diff --git a/.gitignore b/.gitignore index 22fe7a8..a84da22 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,4 @@ .vscode _site Gemfile.lock -vendor/ -bundle/ - +vendor/ \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/bin/rake b/vendor/bundle/ruby/2.6.0/bin/rake deleted file mode 100755 index f24ffd8..0000000 --- a/vendor/bundle/ruby/2.6.0/bin/rake +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# -# This file was generated by RubyGems. -# -# The application 'rake' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -version = ">= 0.a" - -str = ARGV.first -if str - str = str.b[/\A_(.*)_\z/, 1] - if str and Gem::Version.correct?(str) - version = str - ARGV.shift - end -end - -if Gem.respond_to?(:activate_bin_path) -load Gem.activate_bin_path('rake', 'rake', version) -else -gem "rake", version -load Gem.bin_path("rake", "rake", version) -end diff --git a/vendor/bundle/ruby/2.6.0/cache/addressable-2.8.7.gem b/vendor/bundle/ruby/2.6.0/cache/addressable-2.8.7.gem deleted file mode 100644 index c489068..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/addressable-2.8.7.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/cache/colorator-1.1.0.gem b/vendor/bundle/ruby/2.6.0/cache/colorator-1.1.0.gem deleted file mode 100644 index d5616ad..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/colorator-1.1.0.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/cache/concurrent-ruby-1.3.4.gem b/vendor/bundle/ruby/2.6.0/cache/concurrent-ruby-1.3.4.gem deleted file mode 100644 index a656fd0..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/concurrent-ruby-1.3.4.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/cache/eventmachine-1.2.7.gem b/vendor/bundle/ruby/2.6.0/cache/eventmachine-1.2.7.gem deleted file mode 100644 index 708d366..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/eventmachine-1.2.7.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/cache/public_suffix-5.1.1.gem b/vendor/bundle/ruby/2.6.0/cache/public_suffix-5.1.1.gem deleted file mode 100644 index 1d2ef45..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/public_suffix-5.1.1.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/cache/rake-13.2.1.gem b/vendor/bundle/ruby/2.6.0/cache/rake-13.2.1.gem deleted file mode 100644 index 40a47b3..0000000 Binary files a/vendor/bundle/ruby/2.6.0/cache/rake-13.2.1.gem and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/gem_make.out b/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/gem_make.out deleted file mode 100644 index 8984098..0000000 --- a/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/gem_make.out +++ /dev/null @@ -1,57 +0,0 @@ -current directory: /Users/trinale/Desktop/dev/localfirstweb.dev/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext -/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20240920-39130-1l3woup.rb extconf.rb -checking for -lcrypto... *** extconf.rb failed *** -Could not create Makefile due to some reason, probably lack of necessary -libraries and/or headers. Check the mkmf.log file for more details. You may -need configuration options. - -Provided configuration options: - --with-opt-dir - --without-opt-dir - --with-opt-include - --without-opt-include=${opt-dir}/include - --with-opt-lib - --without-opt-lib=${opt-dir}/lib - --with-make-prog - --without-make-prog - --srcdir=. - --curdir - --ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME) - --with-ssl-dir - --without-ssl-dir - --with-ssl-include - --without-ssl-include=${ssl-dir}/include - --with-ssl-lib - --without-ssl-lib=${ssl-dir}/lib - --with-openssl-config - --without-openssl-config - --with-pkg-config - --without-pkg-config - --with-cryptolib - --without-cryptolib -/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError) -You have to install development tools first. - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:546:in `block in try_link0' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/tmpdir.rb:93:in `mktmpdir' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:543:in `try_link0' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:570:in `try_link' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:789:in `try_func' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1016:in `block in have_library' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for' - from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1011:in `have_library' - from extconf.rb:8:in `block in check_libs' - from extconf.rb:8:in `all?' - from extconf.rb:8:in `check_libs' - from extconf.rb:95:in `
' - -To see why this extension failed to compile, please check the mkmf.log which can be found here: - - /Users/trinale/Desktop/dev/localfirstweb.dev/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/mkmf.log - -extconf failed, exit code 1 diff --git a/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/mkmf.log b/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/mkmf.log deleted file mode 100644 index 3c2a2e7..0000000 --- a/vendor/bundle/ruby/2.6.0/extensions/universal-darwin-23/2.6.0/eventmachine-1.2.7/mkmf.log +++ /dev/null @@ -1,19 +0,0 @@ -"xcrun clang -o conftest -I/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/universal-darwin23 -I/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/backward -I/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -g -Os -pipe -DHAVE_GCC_ATOMIC_BUILTINS -DUSE_FFI_CLOSURE_ALLOC conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib -L. -L/AppleInternal/Library/BuildRoots/4ff29661-3588-11ef-9513-e2437461156c/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.6.Internal.sdk/usr/local/lib -lruby.2.6 " -In file included from conftest.c:1: -In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby.h:33: -/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: fatal error: 'ruby/config.h' file not found -#include "ruby/config.h" - ^~~~~~~~~~~~~~~ -/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: note: did not find header 'config.h' in framework 'ruby' (loaded from '/Library/Developer/CommandLineTools/SDKs/MacOSX15.0.sdk/System/Library/Frameworks') -1 error generated. -checked program was: -/* begin */ -1: #include "ruby.h" -2: -3: int main(int argc, char **argv) -4: { -5: return 0; -6: } -/* end */ - -package configuration for openssl is not found diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/CHANGELOG.md b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/CHANGELOG.md deleted file mode 100644 index bf21002..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/CHANGELOG.md +++ /dev/null @@ -1,301 +0,0 @@ -# Addressable 2.8.7 -- Allow `public_suffix` 6 ([#535]) - -[#535]: https://github.com/sporkmonger/addressable/pull/535 - -# Addressable 2.8.6 -- Memoize regexps for common character classes ([#524]) - -[#524]: https://github.com/sporkmonger/addressable/pull/524 - -# Addressable 2.8.5 -- Fix thread safety issue with encoding tables ([#515]) -- Define URI::NONE as a module to avoid serialization issues ([#509]) -- Fix YAML serialization ([#508]) - -[#508]: https://github.com/sporkmonger/addressable/pull/508 -[#509]: https://github.com/sporkmonger/addressable/pull/509 -[#515]: https://github.com/sporkmonger/addressable/pull/515 - -# Addressable 2.8.4 -- Restore `Addressable::IDNA.unicode_normalize_kc` as a deprecated method ([#504]) - -[#504]: https://github.com/sporkmonger/addressable/pull/504 - -# Addressable 2.8.3 -- Fix template expand level 2 hash support for non-string objects ([#499], [#498]) - -[#499]: https://github.com/sporkmonger/addressable/pull/499 -[#498]: https://github.com/sporkmonger/addressable/pull/498 - -# Addressable 2.8.2 -- Improve cache hits and JIT friendliness ([#486](https://github.com/sporkmonger/addressable/pull/486)) -- Improve code style and test coverage ([#482](https://github.com/sporkmonger/addressable/pull/482)) -- Ensure reset of deferred validation ([#481](https://github.com/sporkmonger/addressable/pull/481)) -- Resolve normalization differences between `IDNA::Native` and `IDNA::Pure` ([#408](https://github.com/sporkmonger/addressable/issues/408), [#492]) -- Remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY` regex ([#438](https://github.com/sporkmonger/addressable/pull/438)) (accidentally reverted by [#449] merge but [added back](https://github.com/sporkmonger/addressable/pull/492#discussion_r1105125280) in [#492]) - -[#492]: https://github.com/sporkmonger/addressable/pull/492 - -# Addressable 2.8.1 -- refactor `Addressable::URI.normalize_path` to address linter offenses ([#430](https://github.com/sporkmonger/addressable/pull/430)) -- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463]) -- compatibility w/ public_suffix 5.x ([#466], [#465], [#460]) -- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs containing non UTF-8 characters ([#459](https://github.com/sporkmonger/addressable/pull/459)) -- `Ractor` compatibility ([#449]) -- use the whole string instead of a single line for template match ([#431](https://github.com/sporkmonger/addressable/pull/431)) -- force UTF-8 encoding only if needed ([#341](https://github.com/sporkmonger/addressable/pull/341)) - -[#449]: https://github.com/sporkmonger/addressable/pull/449 -[#460]: https://github.com/sporkmonger/addressable/pull/460 -[#463]: https://github.com/sporkmonger/addressable/pull/463 -[#464]: https://github.com/sporkmonger/addressable/pull/464 -[#465]: https://github.com/sporkmonger/addressable/pull/465 -[#466]: https://github.com/sporkmonger/addressable/pull/466 - -# Addressable 2.8.0 -- fixes ReDoS vulnerability in Addressable::Template#match -- no longer replaces `+` with spaces in queries for non-http(s) schemes -- fixed encoding ipv6 literals -- the `:compacted` flag for `normalized_query` now dedupes parameters -- fix broken `escape_component` alias -- dropping support for Ruby 2.0 and 2.1 -- adding Ruby 3.0 compatibility for development tasks -- drop support for `rack-mount` and remove Addressable::Template#generate -- performance improvements -- switch CI/CD to GitHub Actions - -# Addressable 2.7.0 -- added `:compacted` flag to `normalized_query` -- `heuristic_parse` handles `mailto:` more intuitively -- dropped explicit support for JRuby 9.0.5.0 -- compatibility w/ public_suffix 4.x -- performance improvements - -# Addressable 2.6.0 -- added `tld=` method to allow assignment to the public suffix -- most `heuristic_parse` patterns are now case-insensitive -- `heuristic_parse` handles more `file://` URI variations -- fixes bug in `heuristic_parse` when uri starts with digit -- fixes bug in `request_uri=` with query strings -- fixes template issues with `nil` and `?` operator -- `frozen_string_literal` pragmas added -- minor performance improvements in regexps -- fixes to eliminate warnings - -# Addressable 2.5.2 -- better support for frozen string literals -- fixed bug w/ uppercase characters in scheme -- IDNA errors w/ emoji URLs -- compatibility w/ public_suffix 3.x - -# Addressable 2.5.1 -- allow unicode normalization to be disabled for URI Template expansion -- removed duplicate test - -# Addressable 2.5.0 -- dropping support for Ruby 1.9 -- adding support for Ruby 2.4 preview -- add support for public suffixes and tld; first runtime dependency -- hostname escaping should match RFC; underscores in hostnames no longer escaped -- paths beginning with // and missing an authority are now considered invalid -- validation now also takes place after setting a path -- handle backslashes in authority more like a browser for `heuristic_parse` -- unescaped backslashes in host now raise an `InvalidURIError` -- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation -- `heuristic_parse` now trims whitespace before parsing -- host parts longer than 63 bytes will be ignored and not passed to libidn -- normalized values always encoded as UTF-8 - -# Addressable 2.4.0 -- support for 1.8.x dropped -- double quotes in a host now raises an error -- newlines in host will no longer get unescaped during normalization -- stricter handling of bogus scheme values -- stricter handling of encoded port values -- calling `require 'addressable'` will now load both the URI and Template files -- assigning to the `hostname` component with an `IPAddr` object is now supported -- assigning to the `origin` component is now supported -- fixed minor bug where an exception would be thrown for a missing ACE suffix -- better partial expansion of URI templates - -# Addressable 2.3.8 -- fix warnings -- update dependency gems -- support for 1.8.x officially deprecated - -# Addressable 2.3.7 -- fix scenario in which invalid URIs don't get an exception until inspected -- handle hostnames with two adjacent periods correctly -- upgrade of RSpec - -# Addressable 2.3.6 -- normalization drops empty query string -- better handling in template extract for missing values -- template modifier for `'?'` now treated as optional -- fixed issue where character class parameters were modified -- templates can now be tested for equality -- added `:sorted` option to normalization of query strings -- fixed issue with normalization of hosts given in `'example.com.'` form - -# Addressable 2.3.5 -- added Addressable::URI#empty? method -- Addressable::URI#hostname methods now strip square brackets from IPv6 hosts -- compatibility with Net::HTTP in Ruby 2.0.0 -- Addressable::URI#route_from should always give relative URIs - -# Addressable 2.3.4 -- fixed issue with encoding altering its inputs -- query string normalization now leaves ';' characters alone -- FakeFS is detected before attempting to load unicode tables -- additional testing to ensure frozen objects don't cause problems - -# Addressable 2.3.3 -- fixed issue with converting common primitives during template expansion -- fixed port encoding issue -- removed a few warnings -- normalize should now ignore %2B in query strings -- the IDNA logic should now be handled by libidn in Ruby 1.9 -- no template match should now result in nil instead of an empty MatchData -- added license information to gemspec - -# Addressable 2.3.2 -- added Addressable::URI#default_port method -- fixed issue with Marshalling Unicode data on Windows -- improved heuristic parsing to better handle IPv4 addresses - -# Addressable 2.3.1 -- fixed missing unicode data file - -# Addressable 2.3.0 -- updated Addressable::Template to use RFC 6570, level 4 -- fixed compatibility problems with some versions of Ruby -- moved unicode tables into a data file for performance reasons -- removing support for multiple query value notations - -# Addressable 2.2.8 -- fixed issues with dot segment removal code -- form encoding can now handle multiple values per key -- updated development environment - -# Addressable 2.2.7 -- fixed issues related to Addressable::URI#query_values= -- the Addressable::URI.parse method is now polymorphic - -# Addressable 2.2.6 -- changed the way ambiguous paths are handled -- fixed bug with frozen URIs -- https supported in heuristic parsing - -# Addressable 2.2.5 -- 'parsing' a pre-parsed URI object is now a dup operation -- introduced conditional support for libidn -- fixed normalization issue on ampersands in query strings -- added additional tests around handling of query strings - -# Addressable 2.2.4 -- added origin support from draft-ietf-websec-origin-00 -- resolved issue with attempting to navigate below root -- fixed bug with string splitting in query strings - -# Addressable 2.2.3 -- added :flat_array notation for query strings - -# Addressable 2.2.2 -- fixed issue with percent escaping of '+' character in query strings - -# Addressable 2.2.1 -- added support for application/x-www-form-urlencoded. - -# Addressable 2.2.0 -- added site methods -- improved documentation - -# Addressable 2.1.2 -- added HTTP request URI methods -- better handling of Windows file paths -- validation_deferred boolean replaced with defer_validation block -- normalization of percent-encoded paths should now be correct -- fixed issue with constructing URIs with relative paths -- fixed warnings - -# Addressable 2.1.1 -- more type checking changes -- fixed issue with unicode normalization -- added method to find template defaults -- symbolic keys are now allowed in template mappings -- numeric values and symbolic values are now allowed in template mappings - -# Addressable 2.1.0 -- refactored URI template support out into its own class -- removed extract method due to being useless and unreliable -- removed Addressable::URI.expand_template -- removed Addressable::URI#extract_mapping -- added partial template expansion -- fixed minor bugs in the parse and heuristic_parse methods -- fixed incompatibility with Ruby 1.9.1 -- fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s -- fixed unicode normalization exception -- updated query_values methods to better handle subscript notation -- worked around issue with freezing URIs -- improved specs - -# Addressable 2.0.2 -- fixed issue with URI template expansion -- fixed issue with percent escaping characters 0-15 - -# Addressable 2.0.1 -- fixed issue with query string assignment -- fixed issue with improperly encoded components - -# Addressable 2.0.0 -- the initialize method now takes an options hash as its only parameter -- added query_values method to URI class -- completely replaced IDNA implementation with pure Ruby -- renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION -- completely reworked the Rakefile -- changed the behavior of the port method significantly -- Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed -- documentation is now in YARD format -- more rigorous type checking -- to_str method implemented, implicit conversion to Strings now allowed -- Addressable::URI#omit method added, Addressable::URI#merge method replaced -- updated URI Template code to match v 03 of the draft spec -- added a bunch of new specifications - -# Addressable 1.0.4 -- switched to using RSpec's pending system for specs that rely on IDN -- fixed issue with creating URIs with paths that are not prefixed with '/' - -# Addressable 1.0.3 -- implemented a hash method - -# Addressable 1.0.2 -- fixed minor bug with the extract_mapping method - -# Addressable 1.0.1 -- fixed minor bug with the extract_mapping method - -# Addressable 1.0.0 -- heuristic parse method added -- parsing is slightly more strict -- replaced to_h with to_hash -- fixed routing methods -- improved specifications -- improved heckle rake task -- no surviving heckle mutations - -# Addressable 0.1.2 -- improved normalization -- fixed bug in joining algorithm -- updated specifications - -# Addressable 0.1.1 -- updated documentation -- added URI Template variable extraction - -# Addressable 0.1.0 -- initial release -- implementation based on RFC 3986, 3987 -- support for IRIs via libidn -- support for the URI Template draft spec diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Gemfile b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Gemfile deleted file mode 100644 index 87cf771..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Gemfile +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -source 'https://rubygems.org' - -gemspec - -group :test do - gem 'bigdecimal' if RUBY_VERSION > '2.4' - gem 'rspec', '~> 3.8' - gem 'rspec-its', '~> 1.3' -end - -group :coverage do - gem "coveralls", "> 0.7", require: false, platforms: :mri - gem "simplecov", require: false -end - -group :development do - gem 'launchy', '~> 2.4', '>= 2.4.3' - gem 'redcarpet', :platform => :mri_19 - gem 'yard' -end - -group :test, :development do - gem 'memory_profiler' - gem "rake", ">= 12.3.3" -end - -unless ENV["IDNA_MODE"] == "pure" - gem "idn-ruby", platform: :mri -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/LICENSE.txt b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/LICENSE.txt deleted file mode 100644 index ef51da2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/README.md b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/README.md deleted file mode 100644 index 9892f61..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# Addressable - -
-
Homepage
github.com/sporkmonger/addressable
-
Author
Bob Aman
-
Copyright
Copyright © Bob Aman
-
License
Apache 2.0
-
- -[![Gem Version](https://img.shields.io/gem/dt/addressable.svg)][gem] -[![Build Status](https://github.com/sporkmonger/addressable/workflows/CI/badge.svg)][actions] -[![Test Coverage Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls] -[![Documentation Coverage Status](https://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch] - -[gem]: https://rubygems.org/gems/addressable -[actions]: https://github.com/sporkmonger/addressable/actions -[coveralls]: https://coveralls.io/r/sporkmonger/addressable -[inch]: https://inch-ci.org/github/sporkmonger/addressable - -# Description - -Addressable is an alternative implementation to the URI implementation -that is part of Ruby's standard library. It is flexible, offers heuristic -parsing, and additionally provides extensive support for IRIs and URI templates. - -Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4). - -# Reference - -- {Addressable::URI} -- {Addressable::Template} - -# Example usage - -```ruby -require "addressable/uri" - -uri = Addressable::URI.parse("http://example.com/path/to/resource/") -uri.scheme -#=> "http" -uri.host -#=> "example.com" -uri.path -#=> "/path/to/resource/" - -uri = Addressable::URI.parse("http://www.詹姆斯.com/") -uri.normalize -#=> # -``` - - -# URI Templates - -For more details, see [RFC 6570](https://www.rfc-editor.org/rfc/rfc6570.txt). - - -```ruby - -require "addressable/template" - -template = Addressable::Template.new("http://example.com/{?query*}") -template.expand({ - "query" => { - 'foo' => 'bar', - 'color' => 'red' - } -}) -#=> # - -template = Addressable::Template.new("http://example.com/{?one,two,three}") -template.partial_expand({"one" => "1", "three" => 3}).pattern -#=> "http://example.com/?one=1{&two}&three=3" - -template = Addressable::Template.new( - "http://{host}{/segments*}/{?one,two,bogus}{#fragment}" -) -uri = Addressable::URI.parse( - "http://example.com/a/b/c/?one=1&two=2#foo" -) -template.extract(uri) -#=> -# { -# "host" => "example.com", -# "segments" => ["a", "b", "c"], -# "one" => "1", -# "two" => "2", -# "fragment" => "foo" -# } -``` - -# Install - -```console -$ gem install addressable -``` - -You may optionally turn on native IDN support by installing libidn and the -idn gem: - -```console -$ sudo apt-get install libidn11-dev # Debian/Ubuntu -$ brew install libidn # OS X -$ gem install idn-ruby -``` - -# Semantic Versioning - -This project uses [Semantic Versioning](https://semver.org/). You can (and should) specify your -dependency using a pessimistic version constraint covering the major and minor -values: - -```ruby -spec.add_dependency 'addressable', '~> 2.7' -``` - -If you need a specific bug fix, you can also specify minimum tiny versions -without preventing updates to the latest minor release: - -```ruby -spec.add_dependency 'addressable', '~> 2.3', '>= 2.3.7' -``` diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Rakefile b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Rakefile deleted file mode 100644 index 46fbbd0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/Rakefile +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'rubygems' -require 'rake' - -require File.join(File.dirname(__FILE__), 'lib', 'addressable', 'version') - -PKG_DISPLAY_NAME = 'Addressable' -PKG_NAME = PKG_DISPLAY_NAME.downcase -PKG_VERSION = Addressable::VERSION::STRING -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -PKG_SUMMARY = "URI Implementation" -PKG_DESCRIPTION = <<-TEXT -Addressable is an alternative implementation to the URI implementation that is -part of Ruby's standard library. It is flexible, offers heuristic parsing, and -additionally provides extensive support for IRIs and URI templates. -TEXT - -PKG_FILES = FileList[ - "data/**/*", - "lib/**/*.rb", - "spec/**/*.rb", - "tasks/**/*.rake", - "addressable.gemspec", - "CHANGELOG.md", - "Gemfile", - "LICENSE.txt", - "README.md", - "Rakefile", -] - -task :default => "spec" - -Dir['tasks/**/*.rake'].each { |rake| load rake } diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/addressable.gemspec b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/addressable.gemspec deleted file mode 100644 index bb1f2fa..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/addressable.gemspec +++ /dev/null @@ -1,28 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: addressable 2.8.7 ruby lib - -Gem::Specification.new do |s| - s.name = "addressable".freeze - s.version = "2.8.7".freeze - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v2.8.7" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Bob Aman".freeze] - s.date = "2024-06-21" - s.description = "Addressable is an alternative implementation to the URI implementation that is\npart of Ruby's standard library. It is flexible, offers heuristic parsing, and\nadditionally provides extensive support for IRIs and URI templates.\n".freeze - s.email = "bob@sporkmonger.com".freeze - s.extra_rdoc_files = ["README.md".freeze] - s.files = ["CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "addressable.gemspec".freeze, "data/unicode.data".freeze, "lib/addressable.rb".freeze, "lib/addressable/idna.rb".freeze, "lib/addressable/idna/native.rb".freeze, "lib/addressable/idna/pure.rb".freeze, "lib/addressable/template.rb".freeze, "lib/addressable/uri.rb".freeze, "lib/addressable/version.rb".freeze, "spec/addressable/idna_spec.rb".freeze, "spec/addressable/net_http_compat_spec.rb".freeze, "spec/addressable/security_spec.rb".freeze, "spec/addressable/template_spec.rb".freeze, "spec/addressable/uri_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tasks/clobber.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze, "tasks/metrics.rake".freeze, "tasks/profile.rake".freeze, "tasks/rspec.rake".freeze, "tasks/yard.rake".freeze] - s.homepage = "https://github.com/sporkmonger/addressable".freeze - s.licenses = ["Apache-2.0".freeze] - s.rdoc_options = ["--main".freeze, "README.md".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze) - s.rubygems_version = "3.5.11".freeze - s.summary = "URI Implementation".freeze - - s.specification_version = 4 - - s.add_runtime_dependency(%q.freeze, [">= 2.0.2".freeze, "< 7.0".freeze]) - s.add_development_dependency(%q.freeze, [">= 1.0".freeze, "< 3.0".freeze]) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/data/unicode.data b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/data/unicode.data deleted file mode 100644 index cdfc224..0000000 Binary files a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/data/unicode.data and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable.rb deleted file mode 100644 index b4e98b6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -require 'addressable/uri' -require 'addressable/template' diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna.rb deleted file mode 100644 index 2dbd393..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -begin - require "addressable/idna/native" -rescue LoadError - # libidn or the idn gem was not available, fall back on a pure-Ruby - # implementation... - require "addressable/idna/pure" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb deleted file mode 100644 index a718364..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -require "idn" - -module Addressable - module IDNA - def self.punycode_encode(value) - IDN::Punycode.encode(value.to_s) - end - - def self.punycode_decode(value) - IDN::Punycode.decode(value.to_s) - end - - class << self - # @deprecated Use {String#unicode_normalize(:nfkc)} instead - def unicode_normalize_kc(value) - value.to_s.unicode_normalize(:nfkc) - end - - extend Gem::Deprecate - deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 - end - - def self.to_ascii(value) - value.to_s.split('.', -1).map do |segment| - if segment.size > 0 && segment.size < 64 - IDN::Idna.toASCII(segment, IDN::Idna::ALLOW_UNASSIGNED) - elsif segment.size >= 64 - segment - else - '' - end - end.join('.') - end - - def self.to_unicode(value) - value.to_s.split('.', -1).map do |segment| - if segment.size > 0 && segment.size < 64 - IDN::Idna.toUnicode(segment, IDN::Idna::ALLOW_UNASSIGNED) - elsif segment.size >= 64 - segment - else - '' - end - end.join('.') - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb deleted file mode 100644 index 3d6ffba..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb +++ /dev/null @@ -1,505 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -module Addressable - module IDNA - # This module is loosely based on idn_actionmailer by Mick Staugaard, - # the unicode library by Yoshida Masato, and the punycode implementation - # by Kazuhiro Nishiyama. Most of the code was copied verbatim, but - # some reformatting was done, and some translation from C was done. - # - # Without their code to work from as a base, we'd all still be relying - # on the presence of libidn. Which nobody ever seems to have installed. - # - # Original sources: - # http://github.com/staugaard/idn_actionmailer - # http://www.yoshidam.net/Ruby.html#unicode - # http://rubyforge.org/frs/?group_id=2550 - - - UNICODE_TABLE = File.expand_path( - File.join(File.dirname(__FILE__), '../../..', 'data/unicode.data') - ) - - ACE_PREFIX = "xn--" - - UTF8_REGEX = /\A(?: - [\x09\x0A\x0D\x20-\x7E] # ASCII - | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )*\z/mnx - - UTF8_REGEX_MULTIBYTE = /(?: - [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )/mnx - - # :startdoc: - - # Converts from a Unicode internationalized domain name to an ASCII - # domain name as described in RFC 3490. - def self.to_ascii(input) - input = input.to_s unless input.is_a?(String) - input = input.dup.force_encoding(Encoding::UTF_8).unicode_normalize(:nfkc) - if input.respond_to?(:force_encoding) - input.force_encoding(Encoding::ASCII_8BIT) - end - if input =~ UTF8_REGEX && input =~ UTF8_REGEX_MULTIBYTE - parts = unicode_downcase(input).split('.') - parts.map! do |part| - if part.respond_to?(:force_encoding) - part.force_encoding(Encoding::ASCII_8BIT) - end - if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE - ACE_PREFIX + punycode_encode(part) - else - part - end - end - parts.join('.') - else - input - end - end - - # Converts from an ASCII domain name to a Unicode internationalized - # domain name as described in RFC 3490. - def self.to_unicode(input) - input = input.to_s unless input.is_a?(String) - parts = input.split('.') - parts.map! do |part| - if part =~ /^#{ACE_PREFIX}(.+)/ - begin - punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1]) - rescue Addressable::IDNA::PunycodeBadInput - # toUnicode is explicitly defined as never-fails by the spec - part - end - else - part - end - end - output = parts.join('.') - if output.respond_to?(:force_encoding) - output.force_encoding(Encoding::UTF_8) - end - output - end - - class << self - # @deprecated Use {String#unicode_normalize(:nfkc)} instead - def unicode_normalize_kc(value) - value.to_s.unicode_normalize(:nfkc) - end - - extend Gem::Deprecate - deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 - end - - ## - # Unicode aware downcase method. - # - # @api private - # @param [String] input - # The input string. - # @return [String] The downcased result. - def self.unicode_downcase(input) - input = input.to_s unless input.is_a?(String) - unpacked = input.unpack("U*") - unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) } - return unpacked.pack("U*") - end - private_class_method :unicode_downcase - - def self.lookup_unicode_lowercase(codepoint) - codepoint_data = UNICODE_DATA[codepoint] - (codepoint_data ? - (codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) : - codepoint) - end - private_class_method :lookup_unicode_lowercase - - UNICODE_DATA_COMBINING_CLASS = 0 - UNICODE_DATA_EXCLUSION = 1 - UNICODE_DATA_CANONICAL = 2 - UNICODE_DATA_COMPATIBILITY = 3 - UNICODE_DATA_UPPERCASE = 4 - UNICODE_DATA_LOWERCASE = 5 - UNICODE_DATA_TITLECASE = 6 - - begin - if defined?(FakeFS) - fakefs_state = FakeFS.activated? - FakeFS.deactivate! - end - # This is a sparse Unicode table. Codepoints without entries are - # assumed to have the value: [0, 0, nil, nil, nil, nil, nil] - UNICODE_DATA = File.open(UNICODE_TABLE, "rb") do |file| - Marshal.load(file.read) - end - ensure - if defined?(FakeFS) - FakeFS.activate! if fakefs_state - end - end - - COMPOSITION_TABLE = {} - UNICODE_DATA.each do |codepoint, data| - canonical = data[UNICODE_DATA_CANONICAL] - exclusion = data[UNICODE_DATA_EXCLUSION] - - if canonical && exclusion == 0 - COMPOSITION_TABLE[canonical.unpack("C*")] = codepoint - end - end - - UNICODE_MAX_LENGTH = 256 - ACE_MAX_LENGTH = 256 - - PUNYCODE_BASE = 36 - PUNYCODE_TMIN = 1 - PUNYCODE_TMAX = 26 - PUNYCODE_SKEW = 38 - PUNYCODE_DAMP = 700 - PUNYCODE_INITIAL_BIAS = 72 - PUNYCODE_INITIAL_N = 0x80 - PUNYCODE_DELIMITER = 0x2D - - PUNYCODE_MAXINT = 1 << 64 - - PUNYCODE_PRINT_ASCII = - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + - "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + - " !\"\#$%&'()*+,-./" + - "0123456789:;<=>?" + - "@ABCDEFGHIJKLMNO" + - "PQRSTUVWXYZ[\\]^_" + - "`abcdefghijklmno" + - "pqrstuvwxyz{|}~\n" - - # Input is invalid. - class PunycodeBadInput < StandardError; end - # Output would exceed the space provided. - class PunycodeBigOutput < StandardError; end - # Input needs wider integers to process. - class PunycodeOverflow < StandardError; end - - def self.punycode_encode(unicode) - unicode = unicode.to_s unless unicode.is_a?(String) - input = unicode.unpack("U*") - output = [0] * (ACE_MAX_LENGTH + 1) - input_length = input.size - output_length = [ACE_MAX_LENGTH] - - # Initialize the state - n = PUNYCODE_INITIAL_N - delta = out = 0 - max_out = output_length[0] - bias = PUNYCODE_INITIAL_BIAS - - # Handle the basic code points: - input_length.times do |j| - if punycode_basic?(input[j]) - if max_out - out < 2 - raise PunycodeBigOutput, - "Output would exceed the space provided." - end - output[out] = input[j] - out += 1 - end - end - - h = b = out - - # h is the number of code points that have been handled, b is the - # number of basic code points, and out is the number of characters - # that have been output. - - if b > 0 - output[out] = PUNYCODE_DELIMITER - out += 1 - end - - # Main encoding loop: - - while h < input_length - # All non-basic code points < n have been - # handled already. Find the next larger one: - - m = PUNYCODE_MAXINT - input_length.times do |j| - m = input[j] if (n...m) === input[j] - end - - # Increase delta enough to advance the decoder's - # state to , but guard against overflow: - - if m - n > (PUNYCODE_MAXINT - delta) / (h + 1) - raise PunycodeOverflow, "Input needs wider integers to process." - end - delta += (m - n) * (h + 1) - n = m - - input_length.times do |j| - # Punycode does not need to check whether input[j] is basic: - if input[j] < n - delta += 1 - if delta == 0 - raise PunycodeOverflow, - "Input needs wider integers to process." - end - end - - if input[j] == n - # Represent delta as a generalized variable-length integer: - - q = delta; k = PUNYCODE_BASE - while true - if out >= max_out - raise PunycodeBigOutput, - "Output would exceed the space provided." - end - t = ( - if k <= bias - PUNYCODE_TMIN - elsif k >= bias + PUNYCODE_TMAX - PUNYCODE_TMAX - else - k - bias - end - ) - break if q < t - output[out] = - punycode_encode_digit(t + (q - t) % (PUNYCODE_BASE - t)) - out += 1 - q = (q - t) / (PUNYCODE_BASE - t) - k += PUNYCODE_BASE - end - - output[out] = punycode_encode_digit(q) - out += 1 - bias = punycode_adapt(delta, h + 1, h == b) - delta = 0 - h += 1 - end - end - - delta += 1 - n += 1 - end - - output_length[0] = out - - outlen = out - outlen.times do |j| - c = output[j] - unless c >= 0 && c <= 127 - raise StandardError, "Invalid output char." - end - unless PUNYCODE_PRINT_ASCII[c] - raise PunycodeBadInput, "Input is invalid." - end - end - - output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "") - end - private_class_method :punycode_encode - - def self.punycode_decode(punycode) - input = [] - output = [] - - if ACE_MAX_LENGTH * 2 < punycode.size - raise PunycodeBigOutput, "Output would exceed the space provided." - end - punycode.each_byte do |c| - unless c >= 0 && c <= 127 - raise PunycodeBadInput, "Input is invalid." - end - input.push(c) - end - - input_length = input.length - output_length = [UNICODE_MAX_LENGTH] - - # Initialize the state - n = PUNYCODE_INITIAL_N - - out = i = 0 - max_out = output_length[0] - bias = PUNYCODE_INITIAL_BIAS - - # Handle the basic code points: Let b be the number of input code - # points before the last delimiter, or 0 if there is none, then - # copy the first b code points to the output. - - b = 0 - input_length.times do |j| - b = j if punycode_delimiter?(input[j]) - end - if b > max_out - raise PunycodeBigOutput, "Output would exceed the space provided." - end - - b.times do |j| - unless punycode_basic?(input[j]) - raise PunycodeBadInput, "Input is invalid." - end - output[out] = input[j] - out+=1 - end - - # Main decoding loop: Start just after the last delimiter if any - # basic code points were copied; start at the beginning otherwise. - - in_ = b > 0 ? b + 1 : 0 - while in_ < input_length - - # in_ is the index of the next character to be consumed, and - # out is the number of code points in the output array. - - # Decode a generalized variable-length integer into delta, - # which gets added to i. The overflow checking is easier - # if we increase i as we go, then subtract off its starting - # value at the end to obtain delta. - - oldi = i; w = 1; k = PUNYCODE_BASE - while true - if in_ >= input_length - raise PunycodeBadInput, "Input is invalid." - end - digit = punycode_decode_digit(input[in_]) - in_+=1 - if digit >= PUNYCODE_BASE - raise PunycodeBadInput, "Input is invalid." - end - if digit > (PUNYCODE_MAXINT - i) / w - raise PunycodeOverflow, "Input needs wider integers to process." - end - i += digit * w - t = ( - if k <= bias - PUNYCODE_TMIN - elsif k >= bias + PUNYCODE_TMAX - PUNYCODE_TMAX - else - k - bias - end - ) - break if digit < t - if w > PUNYCODE_MAXINT / (PUNYCODE_BASE - t) - raise PunycodeOverflow, "Input needs wider integers to process." - end - w *= PUNYCODE_BASE - t - k += PUNYCODE_BASE - end - - bias = punycode_adapt(i - oldi, out + 1, oldi == 0) - - # I was supposed to wrap around from out + 1 to 0, - # incrementing n each time, so we'll fix that now: - - if i / (out + 1) > PUNYCODE_MAXINT - n - raise PunycodeOverflow, "Input needs wider integers to process." - end - n += i / (out + 1) - i %= out + 1 - - # Insert n at position i of the output: - - # not needed for Punycode: - # raise PUNYCODE_INVALID_INPUT if decode_digit(n) <= base - if out >= max_out - raise PunycodeBigOutput, "Output would exceed the space provided." - end - - #memmove(output + i + 1, output + i, (out - i) * sizeof *output) - output[i + 1, out - i] = output[i, out - i] - output[i] = n - i += 1 - - out += 1 - end - - output_length[0] = out - - output.pack("U*") - end - private_class_method :punycode_decode - - def self.punycode_basic?(codepoint) - codepoint < 0x80 - end - private_class_method :punycode_basic? - - def self.punycode_delimiter?(codepoint) - codepoint == PUNYCODE_DELIMITER - end - private_class_method :punycode_delimiter? - - def self.punycode_encode_digit(d) - d + 22 + 75 * ((d < 26) ? 1 : 0) - end - private_class_method :punycode_encode_digit - - # Returns the numeric value of a basic codepoint - # (for use in representing integers) in the range 0 to - # base - 1, or PUNYCODE_BASE if codepoint does not represent a value. - def self.punycode_decode_digit(codepoint) - if codepoint - 48 < 10 - codepoint - 22 - elsif codepoint - 65 < 26 - codepoint - 65 - elsif codepoint - 97 < 26 - codepoint - 97 - else - PUNYCODE_BASE - end - end - private_class_method :punycode_decode_digit - - # Bias adaptation method - def self.punycode_adapt(delta, numpoints, firsttime) - delta = firsttime ? delta / PUNYCODE_DAMP : delta >> 1 - # delta >> 1 is a faster way of doing delta / 2 - delta += delta / numpoints - difference = PUNYCODE_BASE - PUNYCODE_TMIN - - k = 0 - while delta > (difference * PUNYCODE_TMAX) / 2 - delta /= difference - k += PUNYCODE_BASE - end - - k + (difference + 1) * delta / (delta + PUNYCODE_SKEW) - end - private_class_method :punycode_adapt - end - # :startdoc: -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/template.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/template.rb deleted file mode 100644 index 08556d9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/template.rb +++ /dev/null @@ -1,1029 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -require "addressable/version" -require "addressable/uri" - -module Addressable - ## - # This is an implementation of a URI template based on - # RFC 6570 (http://tools.ietf.org/html/rfc6570). - class Template - # Constants used throughout the template code. - anything = - Addressable::URI::CharacterClasses::RESERVED + - Addressable::URI::CharacterClasses::UNRESERVED - - - variable_char_class = - Addressable::URI::CharacterClasses::ALPHA + - Addressable::URI::CharacterClasses::DIGIT + '_' - - var_char = - "(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)" - RESERVED = - "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])" - UNRESERVED = - "(?:[#{ - Addressable::URI::CharacterClasses::UNRESERVED - }]|%[a-fA-F0-9][a-fA-F0-9])" - variable = - "(?:#{var_char}(?:\\.?#{var_char})*)" - varspec = - "(?:(#{variable})(\\*|:\\d+)?)" - VARNAME = - /^#{variable}$/ - VARSPEC = - /^#{varspec}$/ - VARIABLE_LIST = - /^#{varspec}(?:,#{varspec})*$/ - operator = - "+#./;?&=,!@|" - EXPRESSION = - /\{([#{operator}])?(#{varspec}(?:,#{varspec})*)\}/ - - - LEADERS = { - '?' => '?', - '/' => '/', - '#' => '#', - '.' => '.', - ';' => ';', - '&' => '&' - } - JOINERS = { - '?' => '&', - '.' => '.', - ';' => ';', - '&' => '&', - '/' => '/' - } - - ## - # Raised if an invalid template value is supplied. - class InvalidTemplateValueError < StandardError - end - - ## - # Raised if an invalid template operator is used in a pattern. - class InvalidTemplateOperatorError < StandardError - end - - ## - # Raised if an invalid template operator is used in a pattern. - class TemplateOperatorAbortedError < StandardError - end - - ## - # This class represents the data that is extracted when a Template - # is matched against a URI. - class MatchData - ## - # Creates a new MatchData object. - # MatchData objects should never be instantiated directly. - # - # @param [Addressable::URI] uri - # The URI that the template was matched against. - def initialize(uri, template, mapping) - @uri = uri.dup.freeze - @template = template - @mapping = mapping.dup.freeze - end - - ## - # @return [Addressable::URI] - # The URI that the Template was matched against. - attr_reader :uri - - ## - # @return [Addressable::Template] - # The Template used for the match. - attr_reader :template - - ## - # @return [Hash] - # The mapping that resulted from the match. - # Note that this mapping does not include keys or values for - # variables that appear in the Template, but are not present - # in the URI. - attr_reader :mapping - - ## - # @return [Array] - # The list of variables that were present in the Template. - # Note that this list will include variables which do not appear - # in the mapping because they were not present in URI. - def variables - self.template.variables - end - alias_method :keys, :variables - alias_method :names, :variables - - ## - # @return [Array] - # The list of values that were captured by the Template. - # Note that this list will include nils for any variables which - # were in the Template, but did not appear in the URI. - def values - @values ||= self.variables.inject([]) do |accu, key| - accu << self.mapping[key] - accu - end - end - alias_method :captures, :values - - ## - # Accesses captured values by name or by index. - # - # @param [String, Symbol, Fixnum] key - # Capture index or name. Note that when accessing by with index - # of 0, the full URI will be returned. The intention is to mimic - # the ::MatchData#[] behavior. - # - # @param [#to_int, nil] len - # If provided, an array of values will be returned with the given - # parameter used as length. - # - # @return [Array, String, nil] - # The captured value corresponding to the index or name. If the - # value was not provided or the key is unknown, nil will be - # returned. - # - # If the second parameter is provided, an array of that length will - # be returned instead. - def [](key, len = nil) - if len - to_a[key, len] - elsif String === key or Symbol === key - mapping[key.to_s] - else - to_a[key] - end - end - - ## - # @return [Array] - # Array with the matched URI as first element followed by the captured - # values. - def to_a - [to_s, *values] - end - - ## - # @return [String] - # The matched URI as String. - def to_s - uri.to_s - end - alias_method :string, :to_s - - # Returns multiple captured values at once. - # - # @param [String, Symbol, Fixnum] *indexes - # Indices of the captures to be returned - # - # @return [Array] - # Values corresponding to given indices. - # - # @see Addressable::Template::MatchData#[] - def values_at(*indexes) - indexes.map { |i| self[i] } - end - - ## - # Returns a String representation of the MatchData's state. - # - # @return [String] The MatchData's state, as a String. - def inspect - sprintf("#<%s:%#0x RESULT:%s>", - self.class.to_s, self.object_id, self.mapping.inspect) - end - - ## - # Dummy method for code expecting a ::MatchData instance - # - # @return [String] An empty string. - def pre_match - "" - end - alias_method :post_match, :pre_match - end - - ## - # Creates a new Addressable::Template object. - # - # @param [#to_str] pattern The URI Template pattern. - # - # @return [Addressable::Template] The initialized Template object. - def initialize(pattern) - if !pattern.respond_to?(:to_str) - raise TypeError, "Can't convert #{pattern.class} into String." - end - @pattern = pattern.to_str.dup.freeze - end - - ## - # Freeze URI, initializing instance variables. - # - # @return [Addressable::URI] The frozen URI object. - def freeze - self.variables - self.variable_defaults - self.named_captures - super - end - - ## - # @return [String] The Template object's pattern. - attr_reader :pattern - - ## - # Returns a String representation of the Template object's state. - # - # @return [String] The Template object's state, as a String. - def inspect - sprintf("#<%s:%#0x PATTERN:%s>", - self.class.to_s, self.object_id, self.pattern) - end - - ## - # Returns true if the Template objects are equal. This method - # does NOT normalize either Template before doing the comparison. - # - # @param [Object] template The Template to compare. - # - # @return [TrueClass, FalseClass] - # true if the Templates are equivalent, false - # otherwise. - def ==(template) - return false unless template.kind_of?(Template) - return self.pattern == template.pattern - end - - ## - # Addressable::Template makes no distinction between `==` and `eql?`. - # - # @see #== - alias_method :eql?, :== - - ## - # Extracts a mapping from the URI using a URI Template pattern. - # - # @param [Addressable::URI, #to_str] uri - # The URI to extract from. - # - # @param [#restore, #match] processor - # A template processor object may optionally be supplied. - # - # The object should respond to either the restore or - # match messages or both. The restore method should - # take two parameters: `[String] name` and `[String] value`. - # The restore method should reverse any transformations that - # have been performed on the value to ensure a valid URI. - # The match method should take a single - # parameter: `[String] name`. The match method should return - # a String containing a regular expression capture group for - # matching on that particular variable. The default value is `".*?"`. - # The match method has no effect on multivariate operator - # expansions. - # - # @return [Hash, NilClass] - # The Hash mapping that was extracted from the URI, or - # nil if the URI didn't match the template. - # - # @example - # class ExampleProcessor - # def self.restore(name, value) - # return value.gsub(/\+/, " ") if name == "query" - # return value - # end - # - # def self.match(name) - # return ".*?" if name == "first" - # return ".*" - # end - # end - # - # uri = Addressable::URI.parse( - # "http://example.com/search/an+example+search+query/" - # ) - # Addressable::Template.new( - # "http://example.com/search/{query}/" - # ).extract(uri, ExampleProcessor) - # #=> {"query" => "an example search query"} - # - # uri = Addressable::URI.parse("http://example.com/a/b/c/") - # Addressable::Template.new( - # "http://example.com/{first}/{second}/" - # ).extract(uri, ExampleProcessor) - # #=> {"first" => "a", "second" => "b/c"} - # - # uri = Addressable::URI.parse("http://example.com/a/b/c/") - # Addressable::Template.new( - # "http://example.com/{first}/{-list|/|second}/" - # ).extract(uri) - # #=> {"first" => "a", "second" => ["b", "c"]} - def extract(uri, processor=nil) - match_data = self.match(uri, processor) - return (match_data ? match_data.mapping : nil) - end - - ## - # Extracts match data from the URI using a URI Template pattern. - # - # @param [Addressable::URI, #to_str] uri - # The URI to extract from. - # - # @param [#restore, #match] processor - # A template processor object may optionally be supplied. - # - # The object should respond to either the restore or - # match messages or both. The restore method should - # take two parameters: `[String] name` and `[String] value`. - # The restore method should reverse any transformations that - # have been performed on the value to ensure a valid URI. - # The match method should take a single - # parameter: `[String] name`. The match method should return - # a String containing a regular expression capture group for - # matching on that particular variable. The default value is `".*?"`. - # The match method has no effect on multivariate operator - # expansions. - # - # @return [Hash, NilClass] - # The Hash mapping that was extracted from the URI, or - # nil if the URI didn't match the template. - # - # @example - # class ExampleProcessor - # def self.restore(name, value) - # return value.gsub(/\+/, " ") if name == "query" - # return value - # end - # - # def self.match(name) - # return ".*?" if name == "first" - # return ".*" - # end - # end - # - # uri = Addressable::URI.parse( - # "http://example.com/search/an+example+search+query/" - # ) - # match = Addressable::Template.new( - # "http://example.com/search/{query}/" - # ).match(uri, ExampleProcessor) - # match.variables - # #=> ["query"] - # match.captures - # #=> ["an example search query"] - # - # uri = Addressable::URI.parse("http://example.com/a/b/c/") - # match = Addressable::Template.new( - # "http://example.com/{first}/{+second}/" - # ).match(uri, ExampleProcessor) - # match.variables - # #=> ["first", "second"] - # match.captures - # #=> ["a", "b/c"] - # - # uri = Addressable::URI.parse("http://example.com/a/b/c/") - # match = Addressable::Template.new( - # "http://example.com/{first}{/second*}/" - # ).match(uri) - # match.variables - # #=> ["first", "second"] - # match.captures - # #=> ["a", ["b", "c"]] - def match(uri, processor=nil) - uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI) - mapping = {} - - # First, we need to process the pattern, and extract the values. - expansions, expansion_regexp = - parse_template_pattern(pattern, processor) - - return nil unless uri.to_str.match(expansion_regexp) - unparsed_values = uri.to_str.scan(expansion_regexp).flatten - - if uri.to_str == pattern - return Addressable::Template::MatchData.new(uri, self, mapping) - elsif expansions.size > 0 - index = 0 - expansions.each do |expansion| - _, operator, varlist = *expansion.match(EXPRESSION) - varlist.split(',').each do |varspec| - _, name, modifier = *varspec.match(VARSPEC) - mapping[name] ||= nil - case operator - when nil, '+', '#', '/', '.' - unparsed_value = unparsed_values[index] - name = varspec[VARSPEC, 1] - value = unparsed_value - value = value.split(JOINERS[operator]) if value && modifier == '*' - when ';', '?', '&' - if modifier == '*' - if unparsed_values[index] - value = unparsed_values[index].split(JOINERS[operator]) - value = value.inject({}) do |acc, v| - key, val = v.split('=') - val = "" if val.nil? - acc[key] = val - acc - end - end - else - if (unparsed_values[index]) - name, value = unparsed_values[index].split('=') - value = "" if value.nil? - end - end - end - if processor != nil && processor.respond_to?(:restore) - value = processor.restore(name, value) - end - if processor == nil - if value.is_a?(Hash) - value = value.inject({}){|acc, (k, v)| - acc[Addressable::URI.unencode_component(k)] = - Addressable::URI.unencode_component(v) - acc - } - elsif value.is_a?(Array) - value = value.map{|v| Addressable::URI.unencode_component(v) } - else - value = Addressable::URI.unencode_component(value) - end - end - if !mapping.has_key?(name) || mapping[name].nil? - # Doesn't exist, set to value (even if value is nil) - mapping[name] = value - end - index = index + 1 - end - end - return Addressable::Template::MatchData.new(uri, self, mapping) - else - return nil - end - end - - ## - # Expands a URI template into another URI template. - # - # @param [Hash] mapping The mapping that corresponds to the pattern. - # @param [#validate, #transform] processor - # An optional processor object may be supplied. - # @param [Boolean] normalize_values - # Optional flag to enable/disable unicode normalization. Default: true - # - # The object should respond to either the validate or - # transform messages or both. Both the validate and - # transform methods should take two parameters: name and - # value. The validate method should return true - # or false; true if the value of the variable is valid, - # false otherwise. An InvalidTemplateValueError - # exception will be raised if the value is invalid. The transform - # method should return the transformed variable value as a String. - # If a transform method is used, the value will not be percent - # encoded automatically. Unicode normalization will be performed both - # before and after sending the value to the transform method. - # - # @return [Addressable::Template] The partially expanded URI template. - # - # @example - # Addressable::Template.new( - # "http://example.com/{one}/{two}/" - # ).partial_expand({"one" => "1"}).pattern - # #=> "http://example.com/1/{two}/" - # - # Addressable::Template.new( - # "http://example.com/{?one,two}/" - # ).partial_expand({"one" => "1"}).pattern - # #=> "http://example.com/?one=1{&two}/" - # - # Addressable::Template.new( - # "http://example.com/{?one,two,three}/" - # ).partial_expand({"one" => "1", "three" => 3}).pattern - # #=> "http://example.com/?one=1{&two}&three=3" - def partial_expand(mapping, processor=nil, normalize_values=true) - result = self.pattern.dup - mapping = normalize_keys(mapping) - result.gsub!( EXPRESSION ) do |capture| - transform_partial_capture(mapping, capture, processor, normalize_values) - end - return Addressable::Template.new(result) - end - - ## - # Expands a URI template into a full URI. - # - # @param [Hash] mapping The mapping that corresponds to the pattern. - # @param [#validate, #transform] processor - # An optional processor object may be supplied. - # @param [Boolean] normalize_values - # Optional flag to enable/disable unicode normalization. Default: true - # - # The object should respond to either the validate or - # transform messages or both. Both the validate and - # transform methods should take two parameters: name and - # value. The validate method should return true - # or false; true if the value of the variable is valid, - # false otherwise. An InvalidTemplateValueError - # exception will be raised if the value is invalid. The transform - # method should return the transformed variable value as a String. - # If a transform method is used, the value will not be percent - # encoded automatically. Unicode normalization will be performed both - # before and after sending the value to the transform method. - # - # @return [Addressable::URI] The expanded URI template. - # - # @example - # class ExampleProcessor - # def self.validate(name, value) - # return !!(value =~ /^[\w ]+$/) if name == "query" - # return true - # end - # - # def self.transform(name, value) - # return value.gsub(/ /, "+") if name == "query" - # return value - # end - # end - # - # Addressable::Template.new( - # "http://example.com/search/{query}/" - # ).expand( - # {"query" => "an example search query"}, - # ExampleProcessor - # ).to_str - # #=> "http://example.com/search/an+example+search+query/" - # - # Addressable::Template.new( - # "http://example.com/search/{query}/" - # ).expand( - # {"query" => "an example search query"} - # ).to_str - # #=> "http://example.com/search/an%20example%20search%20query/" - # - # Addressable::Template.new( - # "http://example.com/search/{query}/" - # ).expand( - # {"query" => "bogus!"}, - # ExampleProcessor - # ).to_str - # #=> Addressable::Template::InvalidTemplateValueError - def expand(mapping, processor=nil, normalize_values=true) - result = self.pattern.dup - mapping = normalize_keys(mapping) - result.gsub!( EXPRESSION ) do |capture| - transform_capture(mapping, capture, processor, normalize_values) - end - return Addressable::URI.parse(result) - end - - ## - # Returns an Array of variables used within the template pattern. - # The variables are listed in the Array in the order they appear within - # the pattern. Multiple occurrences of a variable within a pattern are - # not represented in this Array. - # - # @return [Array] The variables present in the template's pattern. - def variables - @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq - end - alias_method :keys, :variables - alias_method :names, :variables - - ## - # Returns a mapping of variables to their default values specified - # in the template. Variables without defaults are not returned. - # - # @return [Hash] Mapping of template variables to their defaults - def variable_defaults - @variable_defaults ||= - Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten] - end - - ## - # Coerces a template into a `Regexp` object. This regular expression will - # behave very similarly to the actual template, and should match the same - # URI values, but it cannot fully handle, for example, values that would - # extract to an `Array`. - # - # @return [Regexp] A regular expression which should match the template. - def to_regexp - _, source = parse_template_pattern(pattern) - Regexp.new(source) - end - - ## - # Returns the source of the coerced `Regexp`. - # - # @return [String] The source of the `Regexp` given by {#to_regexp}. - # - # @api private - def source - self.to_regexp.source - end - - ## - # Returns the named captures of the coerced `Regexp`. - # - # @return [Hash] The named captures of the `Regexp` given by {#to_regexp}. - # - # @api private - def named_captures - self.to_regexp.named_captures - end - - private - def ordered_variable_defaults - @ordered_variable_defaults ||= begin - expansions, _ = parse_template_pattern(pattern) - expansions.flat_map do |capture| - _, _, varlist = *capture.match(EXPRESSION) - varlist.split(',').map do |varspec| - varspec[VARSPEC, 1] - end - end - end - end - - - ## - # Loops through each capture and expands any values available in mapping - # - # @param [Hash] mapping - # Set of keys to expand - # @param [String] capture - # The expression to expand - # @param [#validate, #transform] processor - # An optional processor object may be supplied. - # @param [Boolean] normalize_values - # Optional flag to enable/disable unicode normalization. Default: true - # - # The object should respond to either the validate or - # transform messages or both. Both the validate and - # transform methods should take two parameters: name and - # value. The validate method should return true - # or false; true if the value of the variable is valid, - # false otherwise. An InvalidTemplateValueError exception - # will be raised if the value is invalid. The transform method - # should return the transformed variable value as a String. If a - # transform method is used, the value will not be percent encoded - # automatically. Unicode normalization will be performed both before and - # after sending the value to the transform method. - # - # @return [String] The expanded expression - def transform_partial_capture(mapping, capture, processor = nil, - normalize_values = true) - _, operator, varlist = *capture.match(EXPRESSION) - - vars = varlist.split(",") - - if operator == "?" - # partial expansion of form style query variables sometimes requires a - # slight reordering of the variables to produce a valid url. - first_to_expand = vars.find { |varspec| - _, name, _ = *varspec.match(VARSPEC) - mapping.key?(name) && !mapping[name].nil? - } - - vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand - end - - vars. - inject("".dup) do |acc, varspec| - _, name, _ = *varspec.match(VARSPEC) - next_val = if mapping.key? name - transform_capture(mapping, "{#{operator}#{varspec}}", - processor, normalize_values) - else - "{#{operator}#{varspec}}" - end - # If we've already expanded at least one '?' operator with non-empty - # value, change to '&' - operator = "&" if (operator == "?") && (next_val != "") - acc << next_val - end - end - - ## - # Transforms a mapped value so that values can be substituted into the - # template. - # - # @param [Hash] mapping The mapping to replace captures - # @param [String] capture - # The expression to replace - # @param [#validate, #transform] processor - # An optional processor object may be supplied. - # @param [Boolean] normalize_values - # Optional flag to enable/disable unicode normalization. Default: true - # - # - # The object should respond to either the validate or - # transform messages or both. Both the validate and - # transform methods should take two parameters: name and - # value. The validate method should return true - # or false; true if the value of the variable is valid, - # false otherwise. An InvalidTemplateValueError exception - # will be raised if the value is invalid. The transform method - # should return the transformed variable value as a String. If a - # transform method is used, the value will not be percent encoded - # automatically. Unicode normalization will be performed both before and - # after sending the value to the transform method. - # - # @return [String] The expanded expression - def transform_capture(mapping, capture, processor=nil, - normalize_values=true) - _, operator, varlist = *capture.match(EXPRESSION) - return_value = varlist.split(',').inject([]) do |acc, varspec| - _, name, modifier = *varspec.match(VARSPEC) - value = mapping[name] - unless value == nil || value == {} - allow_reserved = %w(+ #).include?(operator) - # Common primitives where the .to_s output is well-defined - if Numeric === value || Symbol === value || - value == true || value == false - value = value.to_s - end - length = modifier.gsub(':', '').to_i if modifier =~ /^:\d+/ - - unless (Hash === value) || - value.respond_to?(:to_ary) || value.respond_to?(:to_str) - raise TypeError, - "Can't convert #{value.class} into String or Array." - end - - value = normalize_value(value) if normalize_values - - if processor == nil || !processor.respond_to?(:transform) - # Handle percent escaping - if allow_reserved - encode_map = - Addressable::URI::CharacterClasses::RESERVED + - Addressable::URI::CharacterClasses::UNRESERVED - else - encode_map = Addressable::URI::CharacterClasses::UNRESERVED - end - if value.kind_of?(Array) - transformed_value = value.map do |val| - if length - Addressable::URI.encode_component(val[0...length], encode_map) - else - Addressable::URI.encode_component(val, encode_map) - end - end - unless modifier == "*" - transformed_value = transformed_value.join(',') - end - elsif value.kind_of?(Hash) - transformed_value = value.map do |key, val| - if modifier == "*" - "#{ - Addressable::URI.encode_component( key, encode_map) - }=#{ - Addressable::URI.encode_component( val, encode_map) - }" - else - "#{ - Addressable::URI.encode_component( key, encode_map) - },#{ - Addressable::URI.encode_component( val, encode_map) - }" - end - end - unless modifier == "*" - transformed_value = transformed_value.join(',') - end - else - if length - transformed_value = Addressable::URI.encode_component( - value[0...length], encode_map) - else - transformed_value = Addressable::URI.encode_component( - value, encode_map) - end - end - end - - # Process, if we've got a processor - if processor != nil - if processor.respond_to?(:validate) - if !processor.validate(name, value) - display_value = value.kind_of?(Array) ? value.inspect : value - raise InvalidTemplateValueError, - "#{name}=#{display_value} is an invalid template value." - end - end - if processor.respond_to?(:transform) - transformed_value = processor.transform(name, value) - if normalize_values - transformed_value = normalize_value(transformed_value) - end - end - end - acc << [name, transformed_value] - end - acc - end - return "" if return_value.empty? - join_values(operator, return_value) - end - - ## - # Takes a set of values, and joins them together based on the - # operator. - # - # @param [String, Nil] operator One of the operators from the set - # (?,&,+,#,;,/,.), or nil if there wasn't one. - # @param [Array] return_value - # The set of return values (as [variable_name, value] tuples) that will - # be joined together. - # - # @return [String] The transformed mapped value - def join_values(operator, return_value) - leader = LEADERS.fetch(operator, '') - joiner = JOINERS.fetch(operator, ',') - case operator - when '&', '?' - leader + return_value.map{|k,v| - if v.is_a?(Array) && v.first =~ /=/ - v.join(joiner) - elsif v.is_a?(Array) - v.map{|inner_value| "#{k}=#{inner_value}"}.join(joiner) - else - "#{k}=#{v}" - end - }.join(joiner) - when ';' - return_value.map{|k,v| - if v.is_a?(Array) && v.first =~ /=/ - ';' + v.join(";") - elsif v.is_a?(Array) - ';' + v.map{|inner_value| "#{k}=#{inner_value}"}.join(";") - else - v && v != '' ? ";#{k}=#{v}" : ";#{k}" - end - }.join - else - leader + return_value.map{|k,v| v}.join(joiner) - end - end - - ## - # Takes a set of values, and joins them together based on the - # operator. - # - # @param [Hash, Array, String] value - # Normalizes unicode keys and values with String#unicode_normalize (NFC) - # - # @return [Hash, Array, String] The normalized values - def normalize_value(value) - # Handle unicode normalization - if value.respond_to?(:to_ary) - value.to_ary.map! { |val| normalize_value(val) } - elsif value.kind_of?(Hash) - value = value.inject({}) { |acc, (k, v)| - acc[normalize_value(k)] = normalize_value(v) - acc - } - else - value = value.to_s if !value.kind_of?(String) - if value.encoding != Encoding::UTF_8 - value = value.dup.force_encoding(Encoding::UTF_8) - end - value = value.unicode_normalize(:nfc) - end - value - end - - ## - # Generates a hash with string keys - # - # @param [Hash] mapping A mapping hash to normalize - # - # @return [Hash] - # A hash with stringified keys - def normalize_keys(mapping) - return mapping.inject({}) do |accu, pair| - name, value = pair - if Symbol === name - name = name.to_s - elsif name.respond_to?(:to_str) - name = name.to_str - else - raise TypeError, - "Can't convert #{name.class} into String." - end - accu[name] = value - accu - end - end - - ## - # Generates the Regexp that parses a template pattern. Memoizes the - # value if template processor not set (processors may not be deterministic) - # - # @param [String] pattern The URI template pattern. - # @param [#match] processor The template processor to use. - # - # @return [Array, Regexp] - # An array of expansion variables nad a regular expression which may be - # used to parse a template pattern - def parse_template_pattern(pattern, processor = nil) - if processor.nil? && pattern == @pattern - @cached_template_parse ||= - parse_new_template_pattern(pattern, processor) - else - parse_new_template_pattern(pattern, processor) - end - end - - ## - # Generates the Regexp that parses a template pattern. - # - # @param [String] pattern The URI template pattern. - # @param [#match] processor The template processor to use. - # - # @return [Array, Regexp] - # An array of expansion variables nad a regular expression which may be - # used to parse a template pattern - def parse_new_template_pattern(pattern, processor = nil) - # Escape the pattern. The two gsubs restore the escaped curly braces - # back to their original form. Basically, escape everything that isn't - # within an expansion. - escaped_pattern = Regexp.escape( - pattern - ).gsub(/\\\{(.*?)\\\}/) do |escaped| - escaped.gsub(/\\(.)/, "\\1") - end - - expansions = [] - - # Create a regular expression that captures the values of the - # variables in the URI. - regexp_string = escaped_pattern.gsub( EXPRESSION ) do |expansion| - - expansions << expansion - _, operator, varlist = *expansion.match(EXPRESSION) - leader = Regexp.escape(LEADERS.fetch(operator, '')) - joiner = Regexp.escape(JOINERS.fetch(operator, ',')) - combined = varlist.split(',').map do |varspec| - _, name, modifier = *varspec.match(VARSPEC) - - result = processor && processor.respond_to?(:match) ? processor.match(name) : nil - if result - "(?<#{name}>#{ result })" - else - group = case operator - when '+' - "#{ RESERVED }*?" - when '#' - "#{ RESERVED }*?" - when '/' - "#{ UNRESERVED }*?" - when '.' - "#{ UNRESERVED.gsub('\.', '') }*?" - when ';' - "#{ UNRESERVED }*=?#{ UNRESERVED }*?" - when '?' - "#{ UNRESERVED }*=#{ UNRESERVED }*?" - when '&' - "#{ UNRESERVED }*=#{ UNRESERVED }*?" - else - "#{ UNRESERVED }*?" - end - if modifier == '*' - "(?<#{name}>#{group}(?:#{joiner}?#{group})*)?" - else - "(?<#{name}>#{group})?" - end - end - end.join("#{joiner}?") - "(?:|#{leader}#{combined})" - end - - # Ensure that the regular expression matches the whole URI. - regexp_string = "\\A#{regexp_string}\\z" - return expansions, Regexp.new(regexp_string) - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/uri.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/uri.rb deleted file mode 100644 index 40b80cf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/uri.rb +++ /dev/null @@ -1,2602 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -require "addressable/version" -require "addressable/idna" -require "public_suffix" - -## -# Addressable is a library for processing links and URIs. -module Addressable - ## - # This is an implementation of a URI parser based on - # RFC 3986, - # RFC 3987. - class URI - ## - # Raised if something other than a uri is supplied. - class InvalidURIError < StandardError - end - - ## - # Container for the character classes specified in - # RFC 3986. - # - # Note: Concatenated and interpolated `String`s are not affected by the - # `frozen_string_literal` directive and must be frozen explicitly. - # - # Interpolated `String`s *were* frozen this way before Ruby 3.0: - # https://bugs.ruby-lang.org/issues/17104 - module CharacterClasses - ALPHA = "a-zA-Z" - DIGIT = "0-9" - GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@" - SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=" - RESERVED = (GEN_DELIMS + SUB_DELIMS).freeze - UNRESERVED = (ALPHA + DIGIT + "\\-\\.\\_\\~").freeze - RESERVED_AND_UNRESERVED = RESERVED + UNRESERVED - PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze - SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze - HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze - AUTHORITY = (PCHAR + "\\[\\]").freeze - PATH = (PCHAR + "\\/").freeze - QUERY = (PCHAR + "\\/\\?").freeze - FRAGMENT = (PCHAR + "\\/\\?").freeze - end - - module NormalizeCharacterClasses - HOST = /[^#{CharacterClasses::HOST}]/ - UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ - PCHAR = /[^#{CharacterClasses::PCHAR}]/ - SCHEME = /[^#{CharacterClasses::SCHEME}]/ - FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ - QUERY = %r{[^a-zA-Z0-9\-\.\_\~\!\$\'\(\)\*\+\,\=\:\@\/\?%]|%(?!2B|2b)} - end - - module CharacterClassesRegexps - AUTHORITY = /[^#{CharacterClasses::AUTHORITY}]/ - FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ - HOST = /[^#{CharacterClasses::HOST}]/ - PATH = /[^#{CharacterClasses::PATH}]/ - QUERY = /[^#{CharacterClasses::QUERY}]/ - RESERVED = /[^#{CharacterClasses::RESERVED}]/ - RESERVED_AND_UNRESERVED = /[^#{CharacterClasses::RESERVED_AND_UNRESERVED}]/ - SCHEME = /[^#{CharacterClasses::SCHEME}]/ - UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ - end - - SLASH = '/' - EMPTY_STR = '' - - URIREGEX = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/ - - PORT_MAPPING = { - "http" => 80, - "https" => 443, - "ftp" => 21, - "tftp" => 69, - "sftp" => 22, - "ssh" => 22, - "svn+ssh" => 22, - "telnet" => 23, - "nntp" => 119, - "gopher" => 70, - "wais" => 210, - "ldap" => 389, - "prospero" => 1525 - }.freeze - - ## - # Returns a URI object based on the parsed string. - # - # @param [String, Addressable::URI, #to_str] uri - # The URI string to parse. - # No parsing is performed if the object is already an - # Addressable::URI. - # - # @return [Addressable::URI] The parsed URI. - def self.parse(uri) - # If we were given nil, return nil. - return nil unless uri - # If a URI object is passed, just return itself. - return uri.dup if uri.kind_of?(self) - - # If a URI object of the Ruby standard library variety is passed, - # convert it to a string, then parse the string. - # We do the check this way because we don't want to accidentally - # cause a missing constant exception to be thrown. - if uri.class.name =~ /^URI\b/ - uri = uri.to_s - end - - # Otherwise, convert to a String - begin - uri = uri.to_str - rescue TypeError, NoMethodError - raise TypeError, "Can't convert #{uri.class} into String." - end unless uri.is_a?(String) - - # This Regexp supplied as an example in RFC 3986, and it works great. - scan = uri.scan(URIREGEX) - fragments = scan[0] - scheme = fragments[1] - authority = fragments[3] - path = fragments[4] - query = fragments[6] - fragment = fragments[8] - user = nil - password = nil - host = nil - port = nil - if authority != nil - # The Regexp above doesn't split apart the authority. - userinfo = authority[/^([^\[\]]*)@/, 1] - if userinfo != nil - user = userinfo.strip[/^([^:]*):?/, 1] - password = userinfo.strip[/:(.*)$/, 1] - end - - host = authority.sub( - /^([^\[\]]*)@/, EMPTY_STR - ).sub( - /:([^:@\[\]]*?)$/, EMPTY_STR - ) - - port = authority[/:([^:@\[\]]*?)$/, 1] - port = nil if port == EMPTY_STR - end - - return new( - :scheme => scheme, - :user => user, - :password => password, - :host => host, - :port => port, - :path => path, - :query => query, - :fragment => fragment - ) - end - - ## - # Converts an input to a URI. The input does not have to be a valid - # URI — the method will use heuristics to guess what URI was intended. - # This is not standards-compliant, merely user-friendly. - # - # @param [String, Addressable::URI, #to_str] uri - # The URI string to parse. - # No parsing is performed if the object is already an - # Addressable::URI. - # @param [Hash] hints - # A Hash of hints to the heuristic parser. - # Defaults to {:scheme => "http"}. - # - # @return [Addressable::URI] The parsed URI. - def self.heuristic_parse(uri, hints={}) - # If we were given nil, return nil. - return nil unless uri - # If a URI object is passed, just return itself. - return uri.dup if uri.kind_of?(self) - - # If a URI object of the Ruby standard library variety is passed, - # convert it to a string, then parse the string. - # We do the check this way because we don't want to accidentally - # cause a missing constant exception to be thrown. - if uri.class.name =~ /^URI\b/ - uri = uri.to_s - end - - unless uri.respond_to?(:to_str) - raise TypeError, "Can't convert #{uri.class} into String." - end - # Otherwise, convert to a String - uri = uri.to_str.dup.strip - hints = { - :scheme => "http" - }.merge(hints) - case uri - when /^http:\//i - uri.sub!(/^http:\/+/i, "http://") - when /^https:\//i - uri.sub!(/^https:\/+/i, "https://") - when /^feed:\/+http:\//i - uri.sub!(/^feed:\/+http:\/+/i, "feed:http://") - when /^feed:\//i - uri.sub!(/^feed:\/+/i, "feed://") - when %r[^file:/{4}]i - uri.sub!(%r[^file:/+]i, "file:////") - when %r[^file://localhost/]i - uri.sub!(%r[^file://localhost/+]i, "file:///") - when %r[^file:/+]i - uri.sub!(%r[^file:/+]i, "file:///") - when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ - uri.sub!(/^/, hints[:scheme] + "://") - when /\A\d+\..*:\d+\z/ - uri = "#{hints[:scheme]}://#{uri}" - end - match = uri.match(URIREGEX) - fragments = match.captures - authority = fragments[3] - if authority && authority.length > 0 - new_authority = authority.tr("\\", "/").gsub(" ", "%20") - # NOTE: We want offset 4, not 3! - offset = match.offset(4) - uri = uri.dup - uri[offset[0]...offset[1]] = new_authority - end - parsed = self.parse(uri) - if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/ - parsed = self.parse(hints[:scheme] + "://" + uri) - end - if parsed.path.include?(".") - if parsed.path[/\b@\b/] - parsed.scheme = "mailto" unless parsed.scheme - elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1] - parsed.defer_validation do - new_path = parsed.path.sub( - Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR) - parsed.host = new_host - parsed.path = new_path - parsed.scheme = hints[:scheme] unless parsed.scheme - end - end - end - return parsed - end - - ## - # Converts a path to a file scheme URI. If the path supplied is - # relative, it will be returned as a relative URI. If the path supplied - # is actually a non-file URI, it will parse the URI as if it had been - # parsed with Addressable::URI.parse. Handles all of the - # various Microsoft-specific formats for specifying paths. - # - # @param [String, Addressable::URI, #to_str] path - # Typically a String path to a file or directory, but - # will return a sensible return value if an absolute URI is supplied - # instead. - # - # @return [Addressable::URI] - # The parsed file scheme URI or the original URI if some other URI - # scheme was provided. - # - # @example - # base = Addressable::URI.convert_path("/absolute/path/") - # uri = Addressable::URI.convert_path("relative/path") - # (base + uri).to_s - # #=> "file:///absolute/path/relative/path" - # - # Addressable::URI.convert_path( - # "c:\\windows\\My Documents 100%20\\foo.txt" - # ).to_s - # #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt" - # - # Addressable::URI.convert_path("http://example.com/").to_s - # #=> "http://example.com/" - def self.convert_path(path) - # If we were given nil, return nil. - return nil unless path - # If a URI object is passed, just return itself. - return path if path.kind_of?(self) - unless path.respond_to?(:to_str) - raise TypeError, "Can't convert #{path.class} into String." - end - # Otherwise, convert to a String - path = path.to_str.strip - - path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/ - path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/ - uri = self.parse(path) - - if uri.scheme == nil - # Adjust windows-style uris - uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do - "/#{$1.downcase}:/" - end - uri.path.tr!("\\", SLASH) - if File.exist?(uri.path) && - File.stat(uri.path).directory? - uri.path.chomp!(SLASH) - uri.path = uri.path + '/' - end - - # If the path is absolute, set the scheme and host. - if uri.path.start_with?(SLASH) - uri.scheme = "file" - uri.host = EMPTY_STR - end - uri.normalize! - end - - return uri - end - - ## - # Joins several URIs together. - # - # @param [String, Addressable::URI, #to_str] *uris - # The URIs to join. - # - # @return [Addressable::URI] The joined URI. - # - # @example - # base = "http://example.com/" - # uri = Addressable::URI.parse("relative/path") - # Addressable::URI.join(base, uri) - # #=> # - def self.join(*uris) - uri_objects = uris.collect do |uri| - unless uri.respond_to?(:to_str) - raise TypeError, "Can't convert #{uri.class} into String." - end - uri.kind_of?(self) ? uri : self.parse(uri.to_str) - end - result = uri_objects.shift.dup - uri_objects.each do |uri| - result.join!(uri) - end - return result - end - - ## - # Tables used to optimize encoding operations in `self.encode_component` - # and `self.normalize_component` - SEQUENCE_ENCODING_TABLE = (0..255).map do |byte| - format("%02x", byte).freeze - end.freeze - - SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = (0..255).map do |byte| - format("%%%02X", byte).freeze - end.freeze - - ## - # Percent encodes a URI component. - # - # @param [String, #to_str] component The URI component to encode. - # - # @param [String, Regexp] character_class - # The characters which are not percent encoded. If a String - # is passed, the String must be formatted as a regular - # expression character class. (Do not include the surrounding square - # brackets.) For example, "b-zB-Z0-9" would cause - # everything but the letters 'b' through 'z' and the numbers '0' through - # '9' to be percent encoded. If a Regexp is passed, the - # value /[^b-zB-Z0-9]/ would have the same effect. A set of - # useful String values may be found in the - # Addressable::URI::CharacterClasses module. The default - # value is the reserved plus unreserved character classes specified in - # RFC 3986. - # - # @param [Regexp] upcase_encoded - # A string of characters that may already be percent encoded, and whose - # encodings should be upcased. This allows normalization of percent - # encodings for characters not included in the - # character_class. - # - # @return [String] The encoded component. - # - # @example - # Addressable::URI.encode_component("simple/example", "b-zB-Z0-9") - # => "simple%2Fex%61mple" - # Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/) - # => "simple%2Fex%61mple" - # Addressable::URI.encode_component( - # "simple/example", Addressable::URI::CharacterClasses::UNRESERVED - # ) - # => "simple%2Fexample" - def self.encode_component(component, character_class=CharacterClassesRegexps::RESERVED_AND_UNRESERVED, upcase_encoded='') - return nil if component.nil? - - begin - if component.kind_of?(Symbol) || - component.kind_of?(Numeric) || - component.kind_of?(TrueClass) || - component.kind_of?(FalseClass) - component = component.to_s - else - component = component.to_str - end - rescue TypeError, NoMethodError - raise TypeError, "Can't convert #{component.class} into String." - end if !component.is_a? String - - if ![String, Regexp].include?(character_class.class) - raise TypeError, - "Expected String or Regexp, got #{character_class.inspect}" - end - if character_class.kind_of?(String) - character_class = /[^#{character_class}]/ - end - # We can't perform regexps on invalid UTF sequences, but - # here we need to, so switch to ASCII. - component = component.dup - component.force_encoding(Encoding::ASCII_8BIT) - # Avoiding gsub! because there are edge cases with frozen strings - component = component.gsub(character_class) do |char| - SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[char.ord] - end - if upcase_encoded.length > 0 - upcase_encoded_chars = upcase_encoded.bytes.map do |byte| - SEQUENCE_ENCODING_TABLE[byte] - end - component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/, - &:upcase) - end - - return component - end - - class << self - alias_method :escape_component, :encode_component - end - - ## - # Unencodes any percent encoded characters within a URI component. - # This method may be used for unencoding either components or full URIs, - # however, it is recommended to use the unencode_component - # alias when unencoding components. - # - # @param [String, Addressable::URI, #to_str] uri - # The URI or component to unencode. - # - # @param [Class] return_type - # The type of object to return. - # This value may only be set to String or - # Addressable::URI. All other values are invalid. Defaults - # to String. - # - # @param [String] leave_encoded - # A string of characters to leave encoded. If a percent encoded character - # in this list is encountered then it will remain percent encoded. - # - # @return [String, Addressable::URI] - # The unencoded component or URI. - # The return type is determined by the return_type - # parameter. - def self.unencode(uri, return_type=String, leave_encoded='') - return nil if uri.nil? - - begin - uri = uri.to_str - rescue NoMethodError, TypeError - raise TypeError, "Can't convert #{uri.class} into String." - end if !uri.is_a? String - if ![String, ::Addressable::URI].include?(return_type) - raise TypeError, - "Expected Class (String or Addressable::URI), " + - "got #{return_type.inspect}" - end - - result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence| - c = sequence[1..3].to_i(16).chr - c.force_encoding(sequence.encoding) - leave_encoded.include?(c) ? sequence : c - end - - result.force_encoding(Encoding::UTF_8) - if return_type == String - return result - elsif return_type == ::Addressable::URI - return ::Addressable::URI.parse(result) - end - end - - class << self - alias_method :unescape, :unencode - alias_method :unencode_component, :unencode - alias_method :unescape_component, :unencode - end - - - ## - # Normalizes the encoding of a URI component. - # - # @param [String, #to_str] component The URI component to encode. - # - # @param [String, Regexp] character_class - # The characters which are not percent encoded. If a String - # is passed, the String must be formatted as a regular - # expression character class. (Do not include the surrounding square - # brackets.) For example, "b-zB-Z0-9" would cause - # everything but the letters 'b' through 'z' and the numbers '0' - # through '9' to be percent encoded. If a Regexp is passed, - # the value /[^b-zB-Z0-9]/ would have the same effect. A - # set of useful String values may be found in the - # Addressable::URI::CharacterClasses module. The default - # value is the reserved plus unreserved character classes specified in - # RFC 3986. - # - # @param [String] leave_encoded - # When character_class is a String then - # leave_encoded is a string of characters that should remain - # percent encoded while normalizing the component; if they appear percent - # encoded in the original component, then they will be upcased ("%2f" - # normalized to "%2F") but otherwise left alone. - # - # @return [String] The normalized component. - # - # @example - # Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z") - # => "simple%2Fex%61mple" - # Addressable::URI.normalize_component( - # "simpl%65/%65xampl%65", /[^b-zB-Z]/ - # ) - # => "simple%2Fex%61mple" - # Addressable::URI.normalize_component( - # "simpl%65/%65xampl%65", - # Addressable::URI::CharacterClasses::UNRESERVED - # ) - # => "simple%2Fexample" - # Addressable::URI.normalize_component( - # "one%20two%2fthree%26four", - # "0-9a-zA-Z &/", - # "/" - # ) - # => "one two%2Fthree&four" - def self.normalize_component(component, character_class= - CharacterClassesRegexps::RESERVED_AND_UNRESERVED, - leave_encoded='') - return nil if component.nil? - - begin - component = component.to_str - rescue NoMethodError, TypeError - raise TypeError, "Can't convert #{component.class} into String." - end if !component.is_a? String - - if ![String, Regexp].include?(character_class.class) - raise TypeError, - "Expected String or Regexp, got #{character_class.inspect}" - end - if character_class.kind_of?(String) - leave_re = if leave_encoded.length > 0 - character_class = "#{character_class}%" unless character_class.include?('%') - - bytes = leave_encoded.bytes - leave_encoded_pattern = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|') - "|%(?!#{leave_encoded_pattern}|#{leave_encoded_pattern.upcase})" - end - - character_class = if leave_re - /[^#{character_class}]#{leave_re}/ - else - /[^#{character_class}]/ - end - end - # We can't perform regexps on invalid UTF sequences, but - # here we need to, so switch to ASCII. - component = component.dup - component.force_encoding(Encoding::ASCII_8BIT) - unencoded = self.unencode_component(component, String, leave_encoded) - begin - encoded = self.encode_component( - unencoded.unicode_normalize(:nfc), - character_class, - leave_encoded - ) - rescue ArgumentError - encoded = self.encode_component(unencoded) - end - encoded.force_encoding(Encoding::UTF_8) - return encoded - end - - ## - # Percent encodes any special characters in the URI. - # - # @param [String, Addressable::URI, #to_str] uri - # The URI to encode. - # - # @param [Class] return_type - # The type of object to return. - # This value may only be set to String or - # Addressable::URI. All other values are invalid. Defaults - # to String. - # - # @return [String, Addressable::URI] - # The encoded URI. - # The return type is determined by the return_type - # parameter. - def self.encode(uri, return_type=String) - return nil if uri.nil? - - begin - uri = uri.to_str - rescue NoMethodError, TypeError - raise TypeError, "Can't convert #{uri.class} into String." - end if !uri.is_a? String - - if ![String, ::Addressable::URI].include?(return_type) - raise TypeError, - "Expected Class (String or Addressable::URI), " + - "got #{return_type.inspect}" - end - uri_object = uri.kind_of?(self) ? uri : self.parse(uri) - encoded_uri = Addressable::URI.new( - :scheme => self.encode_component(uri_object.scheme, - Addressable::URI::CharacterClassesRegexps::SCHEME), - :authority => self.encode_component(uri_object.authority, - Addressable::URI::CharacterClassesRegexps::AUTHORITY), - :path => self.encode_component(uri_object.path, - Addressable::URI::CharacterClassesRegexps::PATH), - :query => self.encode_component(uri_object.query, - Addressable::URI::CharacterClassesRegexps::QUERY), - :fragment => self.encode_component(uri_object.fragment, - Addressable::URI::CharacterClassesRegexps::FRAGMENT) - ) - if return_type == String - return encoded_uri.to_s - elsif return_type == ::Addressable::URI - return encoded_uri - end - end - - class << self - alias_method :escape, :encode - end - - ## - # Normalizes the encoding of a URI. Characters within a hostname are - # not percent encoded to allow for internationalized domain names. - # - # @param [String, Addressable::URI, #to_str] uri - # The URI to encode. - # - # @param [Class] return_type - # The type of object to return. - # This value may only be set to String or - # Addressable::URI. All other values are invalid. Defaults - # to String. - # - # @return [String, Addressable::URI] - # The encoded URI. - # The return type is determined by the return_type - # parameter. - def self.normalized_encode(uri, return_type=String) - begin - uri = uri.to_str - rescue NoMethodError, TypeError - raise TypeError, "Can't convert #{uri.class} into String." - end if !uri.is_a? String - - if ![String, ::Addressable::URI].include?(return_type) - raise TypeError, - "Expected Class (String or Addressable::URI), " + - "got #{return_type.inspect}" - end - uri_object = uri.kind_of?(self) ? uri : self.parse(uri) - components = { - :scheme => self.unencode_component(uri_object.scheme), - :user => self.unencode_component(uri_object.user), - :password => self.unencode_component(uri_object.password), - :host => self.unencode_component(uri_object.host), - :port => (uri_object.port.nil? ? nil : uri_object.port.to_s), - :path => self.unencode_component(uri_object.path), - :query => self.unencode_component(uri_object.query), - :fragment => self.unencode_component(uri_object.fragment) - } - components.each do |key, value| - if value != nil - begin - components[key] = value.to_str.unicode_normalize(:nfc) - rescue ArgumentError - # Likely a malformed UTF-8 character, skip unicode normalization - components[key] = value.to_str - end - end - end - encoded_uri = Addressable::URI.new( - :scheme => self.encode_component(components[:scheme], - Addressable::URI::CharacterClassesRegexps::SCHEME), - :user => self.encode_component(components[:user], - Addressable::URI::CharacterClassesRegexps::UNRESERVED), - :password => self.encode_component(components[:password], - Addressable::URI::CharacterClassesRegexps::UNRESERVED), - :host => components[:host], - :port => components[:port], - :path => self.encode_component(components[:path], - Addressable::URI::CharacterClassesRegexps::PATH), - :query => self.encode_component(components[:query], - Addressable::URI::CharacterClassesRegexps::QUERY), - :fragment => self.encode_component(components[:fragment], - Addressable::URI::CharacterClassesRegexps::FRAGMENT) - ) - if return_type == String - return encoded_uri.to_s - elsif return_type == ::Addressable::URI - return encoded_uri - end - end - - ## - # Encodes a set of key/value pairs according to the rules for the - # application/x-www-form-urlencoded MIME type. - # - # @param [#to_hash, #to_ary] form_values - # The form values to encode. - # - # @param [TrueClass, FalseClass] sort - # Sort the key/value pairs prior to encoding. - # Defaults to false. - # - # @return [String] - # The encoded value. - def self.form_encode(form_values, sort=false) - if form_values.respond_to?(:to_hash) - form_values = form_values.to_hash.to_a - elsif form_values.respond_to?(:to_ary) - form_values = form_values.to_ary - else - raise TypeError, "Can't convert #{form_values.class} into Array." - end - - form_values = form_values.inject([]) do |accu, (key, value)| - if value.kind_of?(Array) - value.each do |v| - accu << [key.to_s, v.to_s] - end - else - accu << [key.to_s, value.to_s] - end - accu - end - - if sort - # Useful for OAuth and optimizing caching systems - form_values = form_values.sort - end - escaped_form_values = form_values.map do |(key, value)| - # Line breaks are CRLF pairs - [ - self.encode_component( - key.gsub(/(\r\n|\n|\r)/, "\r\n"), - CharacterClassesRegexps::UNRESERVED - ).gsub("%20", "+"), - self.encode_component( - value.gsub(/(\r\n|\n|\r)/, "\r\n"), - CharacterClassesRegexps::UNRESERVED - ).gsub("%20", "+") - ] - end - return escaped_form_values.map do |(key, value)| - "#{key}=#{value}" - end.join("&") - end - - ## - # Decodes a String according to the rules for the - # application/x-www-form-urlencoded MIME type. - # - # @param [String, #to_str] encoded_value - # The form values to decode. - # - # @return [Array] - # The decoded values. - # This is not a Hash because of the possibility for - # duplicate keys. - def self.form_unencode(encoded_value) - if !encoded_value.respond_to?(:to_str) - raise TypeError, "Can't convert #{encoded_value.class} into String." - end - encoded_value = encoded_value.to_str - split_values = encoded_value.split("&").map do |pair| - pair.split("=", 2) - end - return split_values.map do |(key, value)| - [ - key ? self.unencode_component( - key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil, - value ? (self.unencode_component( - value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil - ] - end - end - - ## - # Creates a new uri object from component parts. - # - # @option [String, #to_str] scheme The scheme component. - # @option [String, #to_str] user The user component. - # @option [String, #to_str] password The password component. - # @option [String, #to_str] userinfo - # The userinfo component. If this is supplied, the user and password - # components must be omitted. - # @option [String, #to_str] host The host component. - # @option [String, #to_str] port The port component. - # @option [String, #to_str] authority - # The authority component. If this is supplied, the user, password, - # userinfo, host, and port components must be omitted. - # @option [String, #to_str] path The path component. - # @option [String, #to_str] query The query component. - # @option [String, #to_str] fragment The fragment component. - # - # @return [Addressable::URI] The constructed URI object. - def initialize(options={}) - if options.has_key?(:authority) - if (options.keys & [:userinfo, :user, :password, :host, :port]).any? - raise ArgumentError, - "Cannot specify both an authority and any of the components " + - "within the authority." - end - end - if options.has_key?(:userinfo) - if (options.keys & [:user, :password]).any? - raise ArgumentError, - "Cannot specify both a userinfo and either the user or password." - end - end - - reset_ivs - - defer_validation do - # Bunch of crazy logic required because of the composite components - # like userinfo and authority. - self.scheme = options[:scheme] if options[:scheme] - self.user = options[:user] if options[:user] - self.password = options[:password] if options[:password] - self.userinfo = options[:userinfo] if options[:userinfo] - self.host = options[:host] if options[:host] - self.port = options[:port] if options[:port] - self.authority = options[:authority] if options[:authority] - self.path = options[:path] if options[:path] - self.query = options[:query] if options[:query] - self.query_values = options[:query_values] if options[:query_values] - self.fragment = options[:fragment] if options[:fragment] - end - - to_s # force path validation - end - - ## - # Freeze URI, initializing instance variables. - # - # @return [Addressable::URI] The frozen URI object. - def freeze - self.normalized_scheme - self.normalized_user - self.normalized_password - self.normalized_userinfo - self.normalized_host - self.normalized_port - self.normalized_authority - self.normalized_site - self.normalized_path - self.normalized_query - self.normalized_fragment - self.hash - super - end - - ## - # The scheme component for this URI. - # - # @return [String] The scheme component. - attr_reader :scheme - - ## - # The scheme component for this URI, normalized. - # - # @return [String] The scheme component, normalized. - def normalized_scheme - return nil unless self.scheme - if @normalized_scheme == NONE - @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i - "svn+ssh".dup - else - Addressable::URI.normalize_component( - self.scheme.strip.downcase, - Addressable::URI::NormalizeCharacterClasses::SCHEME - ) - end - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_scheme) - @normalized_scheme - end - - ## - # Sets the scheme component for this URI. - # - # @param [String, #to_str] new_scheme The new scheme component. - def scheme=(new_scheme) - if new_scheme && !new_scheme.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_scheme.class} into String." - elsif new_scheme - new_scheme = new_scheme.to_str - end - if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i - raise InvalidURIError, "Invalid scheme format: '#{new_scheme}'" - end - @scheme = new_scheme - @scheme = nil if @scheme.to_s.strip.empty? - - # Reset dependent values - @normalized_scheme = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The user component for this URI. - # - # @return [String] The user component. - attr_reader :user - - ## - # The user component for this URI, normalized. - # - # @return [String] The user component, normalized. - def normalized_user - return nil unless self.user - return @normalized_user unless @normalized_user == NONE - @normalized_user = begin - if normalized_scheme =~ /https?/ && self.user.strip.empty? && - (!self.password || self.password.strip.empty?) - nil - else - Addressable::URI.normalize_component( - self.user.strip, - Addressable::URI::NormalizeCharacterClasses::UNRESERVED - ) - end - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_user) - @normalized_user - end - - ## - # Sets the user component for this URI. - # - # @param [String, #to_str] new_user The new user component. - def user=(new_user) - if new_user && !new_user.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_user.class} into String." - end - @user = new_user ? new_user.to_str : nil - - # You can't have a nil user with a non-nil password - if password != nil - @user = EMPTY_STR unless user - end - - # Reset dependent values - @userinfo = nil - @normalized_userinfo = NONE - @authority = nil - @normalized_user = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The password component for this URI. - # - # @return [String] The password component. - attr_reader :password - - ## - # The password component for this URI, normalized. - # - # @return [String] The password component, normalized. - def normalized_password - return nil unless self.password - return @normalized_password unless @normalized_password == NONE - @normalized_password = begin - if self.normalized_scheme =~ /https?/ && self.password.strip.empty? && - (!self.user || self.user.strip.empty?) - nil - else - Addressable::URI.normalize_component( - self.password.strip, - Addressable::URI::NormalizeCharacterClasses::UNRESERVED - ) - end - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_password) - @normalized_password - end - - ## - # Sets the password component for this URI. - # - # @param [String, #to_str] new_password The new password component. - def password=(new_password) - if new_password && !new_password.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_password.class} into String." - end - @password = new_password ? new_password.to_str : nil - - # You can't have a nil user with a non-nil password - if @password != nil - self.user = EMPTY_STR if user.nil? - end - - # Reset dependent values - @userinfo = nil - @normalized_userinfo = NONE - @authority = nil - @normalized_password = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The userinfo component for this URI. - # Combines the user and password components. - # - # @return [String] The userinfo component. - def userinfo - current_user = self.user - current_password = self.password - (current_user || current_password) && @userinfo ||= begin - if current_user && current_password - "#{current_user}:#{current_password}" - elsif current_user && !current_password - "#{current_user}" - end - end - end - - ## - # The userinfo component for this URI, normalized. - # - # @return [String] The userinfo component, normalized. - def normalized_userinfo - return nil unless self.userinfo - return @normalized_userinfo unless @normalized_userinfo == NONE - @normalized_userinfo = begin - current_user = self.normalized_user - current_password = self.normalized_password - if !current_user && !current_password - nil - elsif current_user && current_password - "#{current_user}:#{current_password}".dup - elsif current_user && !current_password - "#{current_user}".dup - end - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_userinfo) - @normalized_userinfo - end - - ## - # Sets the userinfo component for this URI. - # - # @param [String, #to_str] new_userinfo The new userinfo component. - def userinfo=(new_userinfo) - if new_userinfo && !new_userinfo.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_userinfo.class} into String." - end - new_user, new_password = if new_userinfo - [ - new_userinfo.to_str.strip[/^(.*):/, 1], - new_userinfo.to_str.strip[/:(.*)$/, 1] - ] - else - [nil, nil] - end - - # Password assigned first to ensure validity in case of nil - self.password = new_password - self.user = new_user - - # Reset dependent values - @authority = nil - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The host component for this URI. - # - # @return [String] The host component. - attr_reader :host - - ## - # The host component for this URI, normalized. - # - # @return [String] The host component, normalized. - def normalized_host - return nil unless self.host - - @normalized_host ||= begin - if !self.host.strip.empty? - result = ::Addressable::IDNA.to_ascii( - URI.unencode_component(self.host.strip.downcase) - ) - if result =~ /[^\.]\.$/ - # Single trailing dots are unnecessary. - result = result[0...-1] - end - result = Addressable::URI.normalize_component( - result, - NormalizeCharacterClasses::HOST - ) - result - else - EMPTY_STR.dup - end - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_host) - @normalized_host - end - - ## - # Sets the host component for this URI. - # - # @param [String, #to_str] new_host The new host component. - def host=(new_host) - if new_host && !new_host.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_host.class} into String." - end - @host = new_host ? new_host.to_str : nil - - # Reset dependent values - @authority = nil - @normalized_host = nil - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # This method is same as URI::Generic#host except - # brackets for IPv6 (and 'IPvFuture') addresses are removed. - # - # @see Addressable::URI#host - # - # @return [String] The hostname for this URI. - def hostname - v = self.host - /\A\[(.*)\]\z/ =~ v ? $1 : v - end - - ## - # This method is same as URI::Generic#host= except - # the argument can be a bare IPv6 address (or 'IPvFuture'). - # - # @see Addressable::URI#host= - # - # @param [String, #to_str] new_hostname The new hostname for this URI. - def hostname=(new_hostname) - if new_hostname && - (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?)) - new_hostname = new_hostname.to_s - elsif new_hostname && !new_hostname.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_hostname.class} into String." - end - v = new_hostname ? new_hostname.to_str : nil - v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v - self.host = v - end - - ## - # Returns the top-level domain for this host. - # - # @example - # Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk" - def tld - PublicSuffix.parse(self.host, ignore_private: true).tld - end - - ## - # Sets the top-level domain for this URI. - # - # @param [String, #to_str] new_tld The new top-level domain. - def tld=(new_tld) - replaced_tld = host.sub(/#{tld}\z/, new_tld) - self.host = PublicSuffix::Domain.new(replaced_tld).to_s - end - - ## - # Returns the public suffix domain for this host. - # - # @example - # Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk" - def domain - PublicSuffix.domain(self.host, ignore_private: true) - end - - ## - # The authority component for this URI. - # Combines the user, password, host, and port components. - # - # @return [String] The authority component. - def authority - self.host && @authority ||= begin - authority = String.new - if self.userinfo != nil - authority << "#{self.userinfo}@" - end - authority << self.host - if self.port != nil - authority << ":#{self.port}" - end - authority - end - end - - ## - # The authority component for this URI, normalized. - # - # @return [String] The authority component, normalized. - def normalized_authority - return nil unless self.authority - @normalized_authority ||= begin - authority = String.new - if self.normalized_userinfo != nil - authority << "#{self.normalized_userinfo}@" - end - authority << self.normalized_host - if self.normalized_port != nil - authority << ":#{self.normalized_port}" - end - authority - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_authority) - @normalized_authority - end - - ## - # Sets the authority component for this URI. - # - # @param [String, #to_str] new_authority The new authority component. - def authority=(new_authority) - if new_authority - if !new_authority.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_authority.class} into String." - end - new_authority = new_authority.to_str - new_userinfo = new_authority[/^([^\[\]]*)@/, 1] - if new_userinfo - new_user = new_userinfo.strip[/^([^:]*):?/, 1] - new_password = new_userinfo.strip[/:(.*)$/, 1] - end - new_host = new_authority.sub( - /^([^\[\]]*)@/, EMPTY_STR - ).sub( - /:([^:@\[\]]*?)$/, EMPTY_STR - ) - new_port = - new_authority[/:([^:@\[\]]*?)$/, 1] - end - - # Password assigned first to ensure validity in case of nil - self.password = new_password - self.user = new_user - self.host = new_host - self.port = new_port - - # Reset dependent values - @userinfo = nil - @normalized_userinfo = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The origin for this URI, serialized to ASCII, as per - # RFC 6454, section 6.2. - # - # @return [String] The serialized origin. - def origin - if self.scheme && self.authority - if self.normalized_port - "#{self.normalized_scheme}://#{self.normalized_host}" + - ":#{self.normalized_port}" - else - "#{self.normalized_scheme}://#{self.normalized_host}" - end - else - "null" - end - end - - ## - # Sets the origin for this URI, serialized to ASCII, as per - # RFC 6454, section 6.2. This assignment will reset the `userinfo` - # component. - # - # @param [String, #to_str] new_origin The new origin component. - def origin=(new_origin) - if new_origin - if !new_origin.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_origin.class} into String." - end - new_origin = new_origin.to_str - new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1] - unless new_scheme - raise InvalidURIError, 'An origin cannot omit the scheme.' - end - new_host = new_origin[/:\/\/([^\/?#:]+)/, 1] - unless new_host - raise InvalidURIError, 'An origin cannot omit the host.' - end - new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1] - end - - self.scheme = new_scheme - self.host = new_host - self.port = new_port - self.userinfo = nil - - # Reset dependent values - @userinfo = nil - @normalized_userinfo = NONE - @authority = nil - @normalized_authority = nil - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - # Returns an array of known ip-based schemes. These schemes typically - # use a similar URI form: - # //:@:/ - def self.ip_based_schemes - return self.port_mapping.keys - end - - # Returns a hash of common IP-based schemes and their default port - # numbers. Adding new schemes to this hash, as necessary, will allow - # for better URI normalization. - def self.port_mapping - PORT_MAPPING - end - - ## - # The port component for this URI. - # This is the port number actually given in the URI. This does not - # infer port numbers from default values. - # - # @return [Integer] The port component. - attr_reader :port - - ## - # The port component for this URI, normalized. - # - # @return [Integer] The port component, normalized. - def normalized_port - return nil unless self.port - return @normalized_port unless @normalized_port == NONE - @normalized_port = begin - if URI.port_mapping[self.normalized_scheme] == self.port - nil - else - self.port - end - end - end - - ## - # Sets the port component for this URI. - # - # @param [String, Integer, #to_s] new_port The new port component. - def port=(new_port) - if new_port != nil && new_port.respond_to?(:to_str) - new_port = Addressable::URI.unencode_component(new_port.to_str) - end - - if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding? - raise InvalidURIError, "Invalid encoding in port" - end - - if new_port != nil && !(new_port.to_s =~ /^\d+$/) - raise InvalidURIError, - "Invalid port number: #{new_port.inspect}" - end - - @port = new_port.to_s.to_i - @port = nil if @port == 0 - - # Reset dependent values - @authority = nil - @normalized_port = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The inferred port component for this URI. - # This method will normalize to the default port for the URI's scheme if - # the port isn't explicitly specified in the URI. - # - # @return [Integer] The inferred port component. - def inferred_port - if self.port.to_i == 0 - self.default_port - else - self.port.to_i - end - end - - ## - # The default port for this URI's scheme. - # This method will always returns the default port for the URI's scheme - # regardless of the presence of an explicit port in the URI. - # - # @return [Integer] The default port. - def default_port - URI.port_mapping[self.scheme.strip.downcase] if self.scheme - end - - ## - # The combination of components that represent a site. - # Combines the scheme, user, password, host, and port components. - # Primarily useful for HTTP and HTTPS. - # - # For example, "http://example.com/path?query" would have a - # site value of "http://example.com". - # - # @return [String] The components that identify a site. - def site - (self.scheme || self.authority) && @site ||= begin - site_string = "".dup - site_string << "#{self.scheme}:" if self.scheme != nil - site_string << "//#{self.authority}" if self.authority != nil - site_string - end - end - - ## - # The normalized combination of components that represent a site. - # Combines the scheme, user, password, host, and port components. - # Primarily useful for HTTP and HTTPS. - # - # For example, "http://example.com/path?query" would have a - # site value of "http://example.com". - # - # @return [String] The normalized components that identify a site. - def normalized_site - return nil unless self.site - @normalized_site ||= begin - site_string = "".dup - if self.normalized_scheme != nil - site_string << "#{self.normalized_scheme}:" - end - if self.normalized_authority != nil - site_string << "//#{self.normalized_authority}" - end - site_string - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_site) - @normalized_site - end - - ## - # Sets the site value for this URI. - # - # @param [String, #to_str] new_site The new site value. - def site=(new_site) - if new_site - if !new_site.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_site.class} into String." - end - new_site = new_site.to_str - # These two regular expressions derived from the primary parsing - # expression - self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1] - self.authority = new_site[ - /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1 - ] - else - self.scheme = nil - self.authority = nil - end - end - - ## - # The path component for this URI. - # - # @return [String] The path component. - attr_reader :path - - NORMPATH = /^(?!\/)[^\/:]*:.*$/ - ## - # The path component for this URI, normalized. - # - # @return [String] The path component, normalized. - def normalized_path - @normalized_path ||= begin - path = self.path.to_s - if self.scheme == nil && path =~ NORMPATH - # Relative paths with colons in the first segment are ambiguous. - path = path.sub(":", "%2F") - end - # String#split(delimiter, -1) uses the more strict splitting behavior - # found by default in Python. - result = path.strip.split(SLASH, -1).map do |segment| - Addressable::URI.normalize_component( - segment, - Addressable::URI::NormalizeCharacterClasses::PCHAR - ) - end.join(SLASH) - - result = URI.normalize_path(result) - if result.empty? && - ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme) - result = SLASH.dup - end - result - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_path) - @normalized_path - end - - ## - # Sets the path component for this URI. - # - # @param [String, #to_str] new_path The new path component. - def path=(new_path) - if new_path && !new_path.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_path.class} into String." - end - @path = (new_path || EMPTY_STR).to_str - if !@path.empty? && @path[0..0] != SLASH && host != nil - @path = "/#{@path}" - end - - # Reset dependent values - @normalized_path = nil - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # The basename, if any, of the file in the path component. - # - # @return [String] The path's basename. - def basename - # Path cannot be nil - return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR) - end - - ## - # The extname, if any, of the file in the path component. - # Empty string if there is no extension. - # - # @return [String] The path's extname. - def extname - return nil unless self.path - return File.extname(self.basename) - end - - ## - # The query component for this URI. - # - # @return [String] The query component. - attr_reader :query - - ## - # The query component for this URI, normalized. - # - # @return [String] The query component, normalized. - def normalized_query(*flags) - return nil unless self.query - return @normalized_query unless @normalized_query == NONE - @normalized_query = begin - modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup - # Make sure possible key-value pair delimiters are escaped. - modified_query_class.sub!("\\&", "").sub!("\\;", "") - pairs = (query || "").split("&", -1) - pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted) - pairs.sort! if flags.include?(:sorted) - component = pairs.map do |pair| - Addressable::URI.normalize_component( - pair, - Addressable::URI::NormalizeCharacterClasses::QUERY, - "+" - ) - end.join("&") - component == "" ? nil : component - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_query) - @normalized_query - end - - ## - # Sets the query component for this URI. - # - # @param [String, #to_str] new_query The new query component. - def query=(new_query) - if new_query && !new_query.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_query.class} into String." - end - @query = new_query ? new_query.to_str : nil - - # Reset dependent values - @normalized_query = NONE - remove_composite_values - end - - ## - # Converts the query component to a Hash value. - # - # @param [Class] return_type The return type desired. Value must be either - # `Hash` or `Array`. - # - # @return [Hash, Array, nil] The query string parsed as a Hash or Array - # or nil if the query string is blank. - # - # @example - # Addressable::URI.parse("?one=1&two=2&three=3").query_values - # #=> {"one" => "1", "two" => "2", "three" => "3"} - # Addressable::URI.parse("?one=two&one=three").query_values(Array) - # #=> [["one", "two"], ["one", "three"]] - # Addressable::URI.parse("?one=two&one=three").query_values(Hash) - # #=> {"one" => "three"} - # Addressable::URI.parse("?").query_values - # #=> {} - # Addressable::URI.parse("").query_values - # #=> nil - def query_values(return_type=Hash) - empty_accumulator = Array == return_type ? [] : {} - if return_type != Hash && return_type != Array - raise ArgumentError, "Invalid return type. Must be Hash or Array." - end - return nil if self.query == nil - split_query = self.query.split("&").map do |pair| - pair.split("=", 2) if pair && !pair.empty? - end.compact - return split_query.inject(empty_accumulator.dup) do |accu, pair| - # I'd rather use key/value identifiers instead of array lookups, - # but in this case I really want to maintain the exact pair structure, - # so it's best to make all changes in-place. - pair[0] = URI.unencode_component(pair[0]) - if pair[1].respond_to?(:to_str) - value = pair[1].to_str - # I loathe the fact that I have to do this. Stupid HTML 4.01. - # Treating '+' as a space was just an unbelievably bad idea. - # There was nothing wrong with '%20'! - # If it ain't broke, don't fix it! - value = value.tr("+", " ") if ["http", "https", nil].include?(scheme) - pair[1] = URI.unencode_component(value) - end - if return_type == Hash - accu[pair[0]] = pair[1] - else - accu << pair - end - accu - end - end - - ## - # Sets the query component for this URI from a Hash object. - # An empty Hash or Array will result in an empty query string. - # - # @param [Hash, #to_hash, Array] new_query_values The new query values. - # - # @example - # uri.query_values = {:a => "a", :b => ["c", "d", "e"]} - # uri.query - # # => "a=a&b=c&b=d&b=e" - # uri.query_values = [['a', 'a'], ['b', 'c'], ['b', 'd'], ['b', 'e']] - # uri.query - # # => "a=a&b=c&b=d&b=e" - # uri.query_values = [['a', 'a'], ['b', ['c', 'd', 'e']]] - # uri.query - # # => "a=a&b=c&b=d&b=e" - # uri.query_values = [['flag'], ['key', 'value']] - # uri.query - # # => "flag&key=value" - def query_values=(new_query_values) - if new_query_values == nil - self.query = nil - return nil - end - - if !new_query_values.is_a?(Array) - if !new_query_values.respond_to?(:to_hash) - raise TypeError, - "Can't convert #{new_query_values.class} into Hash." - end - new_query_values = new_query_values.to_hash - new_query_values = new_query_values.map do |key, value| - key = key.to_s if key.kind_of?(Symbol) - [key, value] - end - # Useful default for OAuth and caching. - # Only to be used for non-Array inputs. Arrays should preserve order. - new_query_values.sort! - end - - # new_query_values have form [['key1', 'value1'], ['key2', 'value2']] - buffer = "".dup - new_query_values.each do |key, value| - encoded_key = URI.encode_component( - key, CharacterClassesRegexps::UNRESERVED - ) - if value == nil - buffer << "#{encoded_key}&" - elsif value.kind_of?(Array) - value.each do |sub_value| - encoded_value = URI.encode_component( - sub_value, CharacterClassesRegexps::UNRESERVED - ) - buffer << "#{encoded_key}=#{encoded_value}&" - end - else - encoded_value = URI.encode_component( - value, CharacterClassesRegexps::UNRESERVED - ) - buffer << "#{encoded_key}=#{encoded_value}&" - end - end - self.query = buffer.chop - end - - ## - # The HTTP request URI for this URI. This is the path and the - # query string. - # - # @return [String] The request URI required for an HTTP request. - def request_uri - return nil if self.absolute? && self.scheme !~ /^https?$/i - return ( - (!self.path.empty? ? self.path : SLASH) + - (self.query ? "?#{self.query}" : EMPTY_STR) - ) - end - - ## - # Sets the HTTP request URI for this URI. - # - # @param [String, #to_str] new_request_uri The new HTTP request URI. - def request_uri=(new_request_uri) - if !new_request_uri.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_request_uri.class} into String." - end - if self.absolute? && self.scheme !~ /^https?$/i - raise InvalidURIError, - "Cannot set an HTTP request URI for a non-HTTP URI." - end - new_request_uri = new_request_uri.to_str - path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1] - query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1] - path_component = path_component.to_s - path_component = (!path_component.empty? ? path_component : SLASH) - self.path = path_component - self.query = query_component - - # Reset dependent values - remove_composite_values - end - - ## - # The fragment component for this URI. - # - # @return [String] The fragment component. - attr_reader :fragment - - ## - # The fragment component for this URI, normalized. - # - # @return [String] The fragment component, normalized. - def normalized_fragment - return nil unless self.fragment - return @normalized_fragment unless @normalized_fragment == NONE - @normalized_fragment = begin - component = Addressable::URI.normalize_component( - self.fragment, - Addressable::URI::NormalizeCharacterClasses::FRAGMENT - ) - component == "" ? nil : component - end - # All normalized values should be UTF-8 - force_utf8_encoding_if_needed(@normalized_fragment) - @normalized_fragment - end - - ## - # Sets the fragment component for this URI. - # - # @param [String, #to_str] new_fragment The new fragment component. - def fragment=(new_fragment) - if new_fragment && !new_fragment.respond_to?(:to_str) - raise TypeError, "Can't convert #{new_fragment.class} into String." - end - @fragment = new_fragment ? new_fragment.to_str : nil - - # Reset dependent values - @normalized_fragment = NONE - remove_composite_values - - # Ensure we haven't created an invalid URI - validate() - end - - ## - # Determines if the scheme indicates an IP-based protocol. - # - # @return [TrueClass, FalseClass] - # true if the scheme indicates an IP-based protocol. - # false otherwise. - def ip_based? - if self.scheme - return URI.ip_based_schemes.include?( - self.scheme.strip.downcase) - end - return false - end - - ## - # Determines if the URI is relative. - # - # @return [TrueClass, FalseClass] - # true if the URI is relative. false - # otherwise. - def relative? - return self.scheme.nil? - end - - ## - # Determines if the URI is absolute. - # - # @return [TrueClass, FalseClass] - # true if the URI is absolute. false - # otherwise. - def absolute? - return !relative? - end - - ## - # Joins two URIs together. - # - # @param [String, Addressable::URI, #to_str] The URI to join with. - # - # @return [Addressable::URI] The joined URI. - def join(uri) - if !uri.respond_to?(:to_str) - raise TypeError, "Can't convert #{uri.class} into String." - end - if !uri.kind_of?(URI) - # Otherwise, convert to a String, then parse. - uri = URI.parse(uri.to_str) - end - if uri.to_s.empty? - return self.dup - end - - joined_scheme = nil - joined_user = nil - joined_password = nil - joined_host = nil - joined_port = nil - joined_path = nil - joined_query = nil - joined_fragment = nil - - # Section 5.2.2 of RFC 3986 - if uri.scheme != nil - joined_scheme = uri.scheme - joined_user = uri.user - joined_password = uri.password - joined_host = uri.host - joined_port = uri.port - joined_path = URI.normalize_path(uri.path) - joined_query = uri.query - else - if uri.authority != nil - joined_user = uri.user - joined_password = uri.password - joined_host = uri.host - joined_port = uri.port - joined_path = URI.normalize_path(uri.path) - joined_query = uri.query - else - if uri.path == nil || uri.path.empty? - joined_path = self.path - if uri.query != nil - joined_query = uri.query - else - joined_query = self.query - end - else - if uri.path[0..0] == SLASH - joined_path = URI.normalize_path(uri.path) - else - base_path = self.path.dup - base_path = EMPTY_STR if base_path == nil - base_path = URI.normalize_path(base_path) - - # Section 5.2.3 of RFC 3986 - # - # Removes the right-most path segment from the base path. - if base_path.include?(SLASH) - base_path.sub!(/\/[^\/]+$/, SLASH) - else - base_path = EMPTY_STR - end - - # If the base path is empty and an authority segment has been - # defined, use a base path of SLASH - if base_path.empty? && self.authority != nil - base_path = SLASH - end - - joined_path = URI.normalize_path(base_path + uri.path) - end - joined_query = uri.query - end - joined_user = self.user - joined_password = self.password - joined_host = self.host - joined_port = self.port - end - joined_scheme = self.scheme - end - joined_fragment = uri.fragment - - return self.class.new( - :scheme => joined_scheme, - :user => joined_user, - :password => joined_password, - :host => joined_host, - :port => joined_port, - :path => joined_path, - :query => joined_query, - :fragment => joined_fragment - ) - end - alias_method :+, :join - - ## - # Destructive form of join. - # - # @param [String, Addressable::URI, #to_str] The URI to join with. - # - # @return [Addressable::URI] The joined URI. - # - # @see Addressable::URI#join - def join!(uri) - replace_self(self.join(uri)) - end - - ## - # Merges a URI with a Hash of components. - # This method has different behavior from join. Any - # components present in the hash parameter will override the - # original components. The path component is not treated specially. - # - # @param [Hash, Addressable::URI, #to_hash] The components to merge with. - # - # @return [Addressable::URI] The merged URI. - # - # @see Hash#merge - def merge(hash) - unless hash.respond_to?(:to_hash) - raise TypeError, "Can't convert #{hash.class} into Hash." - end - hash = hash.to_hash - - if hash.has_key?(:authority) - if (hash.keys & [:userinfo, :user, :password, :host, :port]).any? - raise ArgumentError, - "Cannot specify both an authority and any of the components " + - "within the authority." - end - end - if hash.has_key?(:userinfo) - if (hash.keys & [:user, :password]).any? - raise ArgumentError, - "Cannot specify both a userinfo and either the user or password." - end - end - - uri = self.class.new - uri.defer_validation do - # Bunch of crazy logic required because of the composite components - # like userinfo and authority. - uri.scheme = - hash.has_key?(:scheme) ? hash[:scheme] : self.scheme - if hash.has_key?(:authority) - uri.authority = - hash.has_key?(:authority) ? hash[:authority] : self.authority - end - if hash.has_key?(:userinfo) - uri.userinfo = - hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo - end - if !hash.has_key?(:userinfo) && !hash.has_key?(:authority) - uri.user = - hash.has_key?(:user) ? hash[:user] : self.user - uri.password = - hash.has_key?(:password) ? hash[:password] : self.password - end - if !hash.has_key?(:authority) - uri.host = - hash.has_key?(:host) ? hash[:host] : self.host - uri.port = - hash.has_key?(:port) ? hash[:port] : self.port - end - uri.path = - hash.has_key?(:path) ? hash[:path] : self.path - uri.query = - hash.has_key?(:query) ? hash[:query] : self.query - uri.fragment = - hash.has_key?(:fragment) ? hash[:fragment] : self.fragment - end - - return uri - end - - ## - # Destructive form of merge. - # - # @param [Hash, Addressable::URI, #to_hash] The components to merge with. - # - # @return [Addressable::URI] The merged URI. - # - # @see Addressable::URI#merge - def merge!(uri) - replace_self(self.merge(uri)) - end - - ## - # Returns the shortest normalized relative form of this URI that uses the - # supplied URI as a base for resolution. Returns an absolute URI if - # necessary. This is effectively the opposite of route_to. - # - # @param [String, Addressable::URI, #to_str] uri The URI to route from. - # - # @return [Addressable::URI] - # The normalized relative URI that is equivalent to the original URI. - def route_from(uri) - uri = URI.parse(uri).normalize - normalized_self = self.normalize - if normalized_self.relative? - raise ArgumentError, "Expected absolute URI, got: #{self.to_s}" - end - if uri.relative? - raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}" - end - if normalized_self == uri - return Addressable::URI.parse("##{normalized_self.fragment}") - end - components = normalized_self.to_hash - if normalized_self.scheme == uri.scheme - components[:scheme] = nil - if normalized_self.authority == uri.authority - components[:user] = nil - components[:password] = nil - components[:host] = nil - components[:port] = nil - if normalized_self.path == uri.path - components[:path] = nil - if normalized_self.query == uri.query - components[:query] = nil - end - else - if uri.path != SLASH and components[:path] - self_splitted_path = split_path(components[:path]) - uri_splitted_path = split_path(uri.path) - self_dir = self_splitted_path.shift - uri_dir = uri_splitted_path.shift - while !self_splitted_path.empty? && !uri_splitted_path.empty? and self_dir == uri_dir - self_dir = self_splitted_path.shift - uri_dir = uri_splitted_path.shift - end - components[:path] = (uri_splitted_path.fill('..') + [self_dir] + self_splitted_path).join(SLASH) - end - end - end - end - # Avoid network-path references. - if components[:host] != nil - components[:scheme] = normalized_self.scheme - end - return Addressable::URI.new( - :scheme => components[:scheme], - :user => components[:user], - :password => components[:password], - :host => components[:host], - :port => components[:port], - :path => components[:path], - :query => components[:query], - :fragment => components[:fragment] - ) - end - - ## - # Returns the shortest normalized relative form of the supplied URI that - # uses this URI as a base for resolution. Returns an absolute URI if - # necessary. This is effectively the opposite of route_from. - # - # @param [String, Addressable::URI, #to_str] uri The URI to route to. - # - # @return [Addressable::URI] - # The normalized relative URI that is equivalent to the supplied URI. - def route_to(uri) - return URI.parse(uri).route_from(self) - end - - ## - # Returns a normalized URI object. - # - # NOTE: This method does not attempt to fully conform to specifications. - # It exists largely to correct other people's failures to read the - # specifications, and also to deal with caching issues since several - # different URIs may represent the same resource and should not be - # cached multiple times. - # - # @return [Addressable::URI] The normalized URI. - def normalize - # This is a special exception for the frequently misused feed - # URI scheme. - if normalized_scheme == "feed" - if self.to_s =~ /^feed:\/*http:\/*/ - return URI.parse( - self.to_s[/^feed:\/*(http:\/*.*)/, 1] - ).normalize - end - end - - return self.class.new( - :scheme => normalized_scheme, - :authority => normalized_authority, - :path => normalized_path, - :query => normalized_query, - :fragment => normalized_fragment - ) - end - - ## - # Destructively normalizes this URI object. - # - # @return [Addressable::URI] The normalized URI. - # - # @see Addressable::URI#normalize - def normalize! - replace_self(self.normalize) - end - - ## - # Creates a URI suitable for display to users. If semantic attacks are - # likely, the application should try to detect these and warn the user. - # See RFC 3986, - # section 7.6 for more information. - # - # @return [Addressable::URI] A URI suitable for display purposes. - def display_uri - display_uri = self.normalize - display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host) - return display_uri - end - - ## - # Returns true if the URI objects are equal. This method - # normalizes both URIs before doing the comparison, and allows comparison - # against Strings. - # - # @param [Object] uri The URI to compare. - # - # @return [TrueClass, FalseClass] - # true if the URIs are equivalent, false - # otherwise. - def ===(uri) - if uri.respond_to?(:normalize) - uri_string = uri.normalize.to_s - else - begin - uri_string = ::Addressable::URI.parse(uri).normalize.to_s - rescue InvalidURIError, TypeError - return false - end - end - return self.normalize.to_s == uri_string - end - - ## - # Returns true if the URI objects are equal. This method - # normalizes both URIs before doing the comparison. - # - # @param [Object] uri The URI to compare. - # - # @return [TrueClass, FalseClass] - # true if the URIs are equivalent, false - # otherwise. - def ==(uri) - return false unless uri.kind_of?(URI) - return self.normalize.to_s == uri.normalize.to_s - end - - ## - # Returns true if the URI objects are equal. This method - # does NOT normalize either URI before doing the comparison. - # - # @param [Object] uri The URI to compare. - # - # @return [TrueClass, FalseClass] - # true if the URIs are equivalent, false - # otherwise. - def eql?(uri) - return false unless uri.kind_of?(URI) - return self.to_s == uri.to_s - end - - ## - # A hash value that will make a URI equivalent to its normalized - # form. - # - # @return [Integer] A hash of the URI. - def hash - @hash ||= self.to_s.hash * -1 - end - - ## - # Clones the URI object. - # - # @return [Addressable::URI] The cloned URI. - def dup - duplicated_uri = self.class.new( - :scheme => self.scheme ? self.scheme.dup : nil, - :user => self.user ? self.user.dup : nil, - :password => self.password ? self.password.dup : nil, - :host => self.host ? self.host.dup : nil, - :port => self.port, - :path => self.path ? self.path.dup : nil, - :query => self.query ? self.query.dup : nil, - :fragment => self.fragment ? self.fragment.dup : nil - ) - return duplicated_uri - end - - ## - # Omits components from a URI. - # - # @param [Symbol] *components The components to be omitted. - # - # @return [Addressable::URI] The URI with components omitted. - # - # @example - # uri = Addressable::URI.parse("http://example.com/path?query") - # #=> # - # uri.omit(:scheme, :authority) - # #=> # - def omit(*components) - invalid_components = components - [ - :scheme, :user, :password, :userinfo, :host, :port, :authority, - :path, :query, :fragment - ] - unless invalid_components.empty? - raise ArgumentError, - "Invalid component names: #{invalid_components.inspect}." - end - duplicated_uri = self.dup - duplicated_uri.defer_validation do - components.each do |component| - duplicated_uri.send((component.to_s + "=").to_sym, nil) - end - duplicated_uri.user = duplicated_uri.normalized_user - end - duplicated_uri - end - - ## - # Destructive form of omit. - # - # @param [Symbol] *components The components to be omitted. - # - # @return [Addressable::URI] The URI with components omitted. - # - # @see Addressable::URI#omit - def omit!(*components) - replace_self(self.omit(*components)) - end - - ## - # Determines if the URI is an empty string. - # - # @return [TrueClass, FalseClass] - # Returns true if empty, false otherwise. - def empty? - return self.to_s.empty? - end - - ## - # Converts the URI to a String. - # - # @return [String] The URI's String representation. - def to_s - if self.scheme == nil && self.path != nil && !self.path.empty? && - self.path =~ NORMPATH - raise InvalidURIError, - "Cannot assemble URI string with ambiguous path: '#{self.path}'" - end - @uri_string ||= begin - uri_string = String.new - uri_string << "#{self.scheme}:" if self.scheme != nil - uri_string << "//#{self.authority}" if self.authority != nil - uri_string << self.path.to_s - uri_string << "?#{self.query}" if self.query != nil - uri_string << "##{self.fragment}" if self.fragment != nil - uri_string.force_encoding(Encoding::UTF_8) - uri_string - end - end - - ## - # URI's are glorified Strings. Allow implicit conversion. - alias_method :to_str, :to_s - - ## - # Returns a Hash of the URI components. - # - # @return [Hash] The URI as a Hash of components. - def to_hash - return { - :scheme => self.scheme, - :user => self.user, - :password => self.password, - :host => self.host, - :port => self.port, - :path => self.path, - :query => self.query, - :fragment => self.fragment - } - end - - ## - # Returns a String representation of the URI object's state. - # - # @return [String] The URI object's state, as a String. - def inspect - sprintf("#<%s:%#0x URI:%s>", URI.to_s, self.object_id, self.to_s) - end - - ## - # This method allows you to make several changes to a URI simultaneously, - # which separately would cause validation errors, but in conjunction, - # are valid. The URI will be revalidated as soon as the entire block has - # been executed. - # - # @param [Proc] block - # A set of operations to perform on a given URI. - def defer_validation - raise LocalJumpError, "No block given." unless block_given? - @validation_deferred = true - yield - @validation_deferred = false - validate - ensure - @validation_deferred = false - end - - def encode_with(coder) - instance_variables.each do |ivar| - value = instance_variable_get(ivar) - if value != NONE - key = ivar.to_s.slice(1..-1) - coder[key] = value - end - end - nil - end - - def init_with(coder) - reset_ivs - coder.map.each do |key, value| - instance_variable_set("@#{key}", value) - end - nil - end - - protected - SELF_REF = '.' - PARENT = '..' - - RULE_2A = /\/\.\/|\/\.$/ - RULE_2B_2C = /\/([^\/]*)\/\.\.\/|\/([^\/]*)\/\.\.$/ - RULE_2D = /^\.\.?\/?/ - RULE_PREFIXED_PARENT = /^\/\.\.?\/|^(\/\.\.?)+\/?$/ - - ## - # Resolves paths to their simplest form. - # - # @param [String] path The path to normalize. - # - # @return [String] The normalized path. - def self.normalize_path(path) - # Section 5.2.4 of RFC 3986 - - return if path.nil? - normalized_path = path.dup - loop do - mod ||= normalized_path.gsub!(RULE_2A, SLASH) - - pair = normalized_path.match(RULE_2B_2C) - if pair - parent = pair[1] - current = pair[2] - else - parent = nil - current = nil - end - - regexp = "/#{Regexp.escape(parent.to_s)}/\\.\\./|" - regexp += "(/#{Regexp.escape(current.to_s)}/\\.\\.$)" - - if pair && ((parent != SELF_REF && parent != PARENT) || - (current != SELF_REF && current != PARENT)) - mod ||= normalized_path.gsub!(Regexp.new(regexp), SLASH) - end - - mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR) - # Non-standard, removes prefixed dotted segments from path. - mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH) - break if mod.nil? - end - - normalized_path - end - - ## - # Ensures that the URI is valid. - def validate - return if !!@validation_deferred - if self.scheme != nil && self.ip_based? && - (self.host == nil || self.host.empty?) && - (self.path == nil || self.path.empty?) - raise InvalidURIError, - "Absolute URI missing hierarchical segment: '#{self.to_s}'" - end - if self.host == nil - if self.port != nil || - self.user != nil || - self.password != nil - raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'" - end - end - if self.path != nil && !self.path.empty? && self.path[0..0] != SLASH && - self.authority != nil - raise InvalidURIError, - "Cannot have a relative path with an authority set: '#{self.to_s}'" - end - if self.path != nil && !self.path.empty? && - self.path[0..1] == SLASH + SLASH && self.authority == nil - raise InvalidURIError, - "Cannot have a path with two leading slashes " + - "without an authority set: '#{self.to_s}'" - end - unreserved = CharacterClasses::UNRESERVED - sub_delims = CharacterClasses::SUB_DELIMS - if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ || - (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~ - Regexp.new("^[#{unreserved}#{sub_delims}:]*$"))) - raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'" - end - return nil - end - - ## - # Replaces the internal state of self with the specified URI's state. - # Used in destructive operations to avoid massive code repetition. - # - # @param [Addressable::URI] uri The URI to replace self with. - # - # @return [Addressable::URI] self. - def replace_self(uri) - # Reset dependent values - reset_ivs - - @scheme = uri.scheme - @user = uri.user - @password = uri.password - @host = uri.host - @port = uri.port - @path = uri.path - @query = uri.query - @fragment = uri.fragment - return self - end - - ## - # Splits path string with "/" (slash). - # It is considered that there is empty string after last slash when - # path ends with slash. - # - # @param [String] path The path to split. - # - # @return [Array] An array of parts of path. - def split_path(path) - splitted = path.split(SLASH) - splitted << EMPTY_STR if path.end_with? SLASH - splitted - end - - ## - # Resets composite values for the entire URI - # - # @api private - def remove_composite_values - @uri_string = nil - @hash = nil - end - - ## - # Converts the string to be UTF-8 if it is not already UTF-8 - # - # @api private - def force_utf8_encoding_if_needed(str) - if str && str.encoding != Encoding::UTF_8 - str.force_encoding(Encoding::UTF_8) - end - end - - private - - ## - # Resets instance variables - # - # @api private - def reset_ivs - @scheme = nil - @user = nil - @normalized_scheme = NONE - @normalized_user = NONE - @uri_string = nil - @hash = nil - @userinfo = nil - @normalized_userinfo = NONE - @authority = nil - @password = nil - @normalized_authority = nil - @port = nil - @normalized_password = NONE - @host = nil - @normalized_host = nil - @normalized_port = NONE - @path = EMPTY_STR - @normalized_path = nil - @normalized_query = NONE - @fragment = nil - @normalized_fragment = NONE - @query = nil - end - - NONE = Module.new.freeze - - private_constant :NONE - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/version.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/version.rb deleted file mode 100644 index 2eec3e6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/lib/addressable/version.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -#-- -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#++ - - -# Used to prevent the class/module from being loaded more than once -if !defined?(Addressable::VERSION) - module Addressable - module VERSION - MAJOR = 2 - MINOR = 8 - TINY = 7 - - STRING = [MAJOR, MINOR, TINY].join('.') - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb deleted file mode 100644 index 428c9ec..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb +++ /dev/null @@ -1,302 +0,0 @@ -# frozen_string_literal: true - -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require "spec_helper" - -# Have to use RubyGems to load the idn gem. -require "rubygems" - -require "addressable/idna" - -shared_examples_for "converting from unicode to ASCII" do - it "should convert 'www.google.com' correctly" do - expect(Addressable::IDNA.to_ascii("www.google.com")).to eq("www.google.com") - end - - long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com' - it "should convert '#{long}' correctly" do - expect(Addressable::IDNA.to_ascii(long)).to eq(long) - end - - it "should convert 'www.詹姆斯.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "www.詹姆斯.com" - )).to eq("www.xn--8ws00zhy3a.com") - end - - it "also accepts unicode strings encoded as ascii-8bit" do - expect(Addressable::IDNA.to_ascii( - "www.詹姆斯.com".b - )).to eq("www.xn--8ws00zhy3a.com") - end - - it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do - "www.Iñtërnâtiônàlizætiøn.com" - expect(Addressable::IDNA.to_ascii( - "www.I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4" + - "n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n.com" - )).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com") - end - - it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "www.In\xCC\x83te\xCC\x88rna\xCC\x82tio\xCC\x82n" + - "a\xCC\x80liz\xC3\xA6ti\xC3\xB8n.com" - )).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com") - end - - it "should convert " + - "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + - "correctly" do - expect(Addressable::IDNA.to_ascii( - "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" + - "\201\252\343\201\214\343\201\204\343\202\217\343\201\221\343\201\256" + - "\343\202\217\343\201\213\343\202\211\343\201\252\343\201\204\343\201" + - "\251\343\202\201\343\201\204\343\202\223\343\202\201\343\201\204\343" + - "\201\256\343\202\211\343\201\271\343\202\213\343\201\276\343\201\240" + - "\343\201\252\343\201\214\343\201\217\343\201\227\343\201\252\343\201" + - "\204\343\201\250\343\201\237\343\202\212\343\201\252\343\201\204." + - "w3.mag.keio.ac.jp" - )).to eq( - "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + - "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" - ) - end - - it "should convert " + - "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + - "correctly" do - expect(Addressable::IDNA.to_ascii( - "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" + - "\201\252\343\201\213\343\202\231\343\201\204\343\202\217\343\201\221" + - "\343\201\256\343\202\217\343\201\213\343\202\211\343\201\252\343\201" + - "\204\343\201\250\343\202\231\343\202\201\343\201\204\343\202\223\343" + - "\202\201\343\201\204\343\201\256\343\202\211\343\201\270\343\202\231" + - "\343\202\213\343\201\276\343\201\237\343\202\231\343\201\252\343\201" + - "\213\343\202\231\343\201\217\343\201\227\343\201\252\343\201\204\343" + - "\201\250\343\201\237\343\202\212\343\201\252\343\201\204." + - "w3.mag.keio.ac.jp" - )).to eq( - "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + - "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" - ) - end - - it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do - expect(Addressable::IDNA.to_ascii( - "点心和烤鸭.w3.mag.keio.ac.jp" - )).to eq("xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp") - end - - it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "가각갂갃간갅갆갇갈갉힢힣.com" - )).to eq("xn--o39acdefghijk5883jma.com") - end - - it "should convert " + - "'\347\242\274\346\250\231\346\272\226\350" + - "\220\254\345\234\213\347\242\274.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "\347\242\274\346\250\231\346\272\226\350" + - "\220\254\345\234\213\347\242\274.com" - )).to eq("xn--9cs565brid46mda086o.com") - end - - it "should convert 'リ宠퐱〹.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "\357\276\230\345\256\240\355\220\261\343\200\271.com" - )).to eq("xn--eek174hoxfpr4k.com") - end - - it "should convert 'リ宠퐱卄.com' correctly" do - expect(Addressable::IDNA.to_ascii( - "\343\203\252\345\256\240\355\220\261\345\215\204.com" - )).to eq("xn--eek174hoxfpr4k.com") - end - - it "should convert 'ᆵ' correctly" do - expect(Addressable::IDNA.to_ascii( - "\341\206\265" - )).to eq("xn--4ud") - end - - it "should convert 'ᆵ' correctly" do - expect(Addressable::IDNA.to_ascii( - "\357\276\257" - )).to eq("xn--4ud") - end - - it "should convert '🌹🌹🌹.ws' correctly" do - expect(Addressable::IDNA.to_ascii( - "\360\237\214\271\360\237\214\271\360\237\214\271.ws" - )).to eq("xn--2h8haa.ws") - end - - it "should handle two adjacent '.'s correctly" do - expect(Addressable::IDNA.to_ascii( - "example..host" - )).to eq("example..host") - end -end - -shared_examples_for "converting from ASCII to unicode" do - long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com' - it "should convert '#{long}' correctly" do - expect(Addressable::IDNA.to_unicode(long)).to eq(long) - end - - it "should return the identity conversion when punycode decode fails" do - expect(Addressable::IDNA.to_unicode("xn--zckp1cyg1.sblo.jp")).to eq( - "xn--zckp1cyg1.sblo.jp") - end - - it "should return the identity conversion when the ACE prefix has no suffix" do - expect(Addressable::IDNA.to_unicode("xn--...-")).to eq("xn--...-") - end - - it "should convert 'www.google.com' correctly" do - expect(Addressable::IDNA.to_unicode("www.google.com")).to eq( - "www.google.com") - end - - it "should convert 'www.詹姆斯.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "www.xn--8ws00zhy3a.com" - )).to eq("www.詹姆斯.com") - end - - it "should convert '詹姆斯.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--8ws00zhy3a.com" - )).to eq("詹姆斯.com") - end - - it "should convert 'www.iñtërnâtiônàlizætiøn.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "www.xn--itrntinliztin-vdb0a5exd8ewcye.com" - )).to eq("www.iñtërnâtiônàlizætiøn.com") - end - - it "should convert 'iñtërnâtiônàlizætiøn.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--itrntinliztin-vdb0a5exd8ewcye.com" - )).to eq("iñtërnâtiônàlizætiøn.com") - end - - it "should convert " + - "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + - "correctly" do - expect(Addressable::IDNA.to_unicode( - "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + - "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" - )).to eq( - "www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp" - ) - end - - it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp" - )).to eq("点心和烤鸭.w3.mag.keio.ac.jp") - end - - it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--o39acdefghijk5883jma.com" - )).to eq("가각갂갃간갅갆갇갈갉힢힣.com") - end - - it "should convert " + - "'\347\242\274\346\250\231\346\272\226\350" + - "\220\254\345\234\213\347\242\274.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--9cs565brid46mda086o.com" - )).to eq( - "\347\242\274\346\250\231\346\272\226\350" + - "\220\254\345\234\213\347\242\274.com" - ) - end - - it "should convert 'リ宠퐱卄.com' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--eek174hoxfpr4k.com" - )).to eq("\343\203\252\345\256\240\355\220\261\345\215\204.com") - end - - it "should convert 'ᆵ' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--4ud" - )).to eq("\341\206\265") - end - - it "should convert '🌹🌹🌹.ws' correctly" do - expect(Addressable::IDNA.to_unicode( - "xn--2h8haa.ws" - )).to eq("\360\237\214\271\360\237\214\271\360\237\214\271.ws") - end - - it "should handle two adjacent '.'s correctly" do - expect(Addressable::IDNA.to_unicode( - "example..host" - )).to eq("example..host") - end -end - -describe Addressable::IDNA, "when using the pure-Ruby implementation" do - before do - Addressable.send(:remove_const, :IDNA) - load "addressable/idna/pure.rb" - end - - it_should_behave_like "converting from unicode to ASCII" - it_should_behave_like "converting from ASCII to unicode" - - begin - require "fiber" - - it "should not blow up inside fibers" do - f = Fiber.new do - Addressable.send(:remove_const, :IDNA) - load "addressable/idna/pure.rb" - end - f.resume - end - rescue LoadError - # Fibers aren't supported in this version of Ruby, skip this test. - warn('Fibers unsupported.') - end -end - -begin - require "idn" - - describe Addressable::IDNA, "when using the native-code implementation" do - before do - Addressable.send(:remove_const, :IDNA) - load "addressable/idna/native.rb" - end - - it_should_behave_like "converting from unicode to ASCII" - it_should_behave_like "converting from ASCII to unicode" - end -rescue LoadError => error - raise error if ENV["CI"] && TestHelper.native_supported? - - # Cannot test the native implementation without libidn support. - warn('Could not load native IDN implementation.') -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb deleted file mode 100644 index d07a43e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require "spec_helper" - -require "addressable/uri" -require "net/http" - -describe Net::HTTP do - it "should be compatible with Addressable" do - response_body = - Net::HTTP.get(Addressable::URI.parse('http://www.google.com/')) - expect(response_body).not_to be_nil - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb deleted file mode 100644 index 3bf90a2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true - -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require "spec_helper" - -require "addressable/uri" - -describe Addressable::URI, "when created with a URI known to cause crashes " + - "in certain browsers" do - it "should parse correctly" do - uri = Addressable::URI.parse('%%30%30') - expect(uri.path).to eq('%%30%30') - expect(uri.normalize.path).to eq('%2500') - end - - it "should parse correctly as a full URI" do - uri = Addressable::URI.parse('http://www.example.com/%%30%30') - expect(uri.path).to eq('/%%30%30') - expect(uri.normalize.path).to eq('/%2500') - end -end - -describe Addressable::URI, "when created with a URI known to cause crashes " + - "in certain browsers" do - it "should parse correctly" do - uri = Addressable::URI.parse('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') - expect(uri.path).to eq('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') - expect(uri.normalize.path).to eq( - '%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' + - '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' + - '%A3%20%E0%A5%A3%20%E5%86%97' - ) - end - - it "should parse correctly as a full URI" do - uri = Addressable::URI.parse('http://www.example.com/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') - expect(uri.path).to eq('/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') - expect(uri.normalize.path).to eq( - '/%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' + - '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' + - '%A3%20%E0%A5%A3%20%E5%86%97' - ) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb deleted file mode 100644 index 24616c2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb +++ /dev/null @@ -1,1264 +0,0 @@ -# frozen_string_literal: true - -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require "spec_helper" - -require "bigdecimal" -require "timeout" -require "addressable/template" - -shared_examples_for 'expands' do |tests| - tests.each do |template, expansion| - exp = expansion.is_a?(Array) ? expansion.first : expansion - it "#{template} to #{exp}" do - tmpl = Addressable::Template.new(template).expand(subject) - expect(tmpl.to_str).to eq(expansion) - end - end -end - -describe "eql?" do - let(:template) { Addressable::Template.new('https://www.example.com/{foo}') } - it 'is equal when the pattern matches' do - other_template = Addressable::Template.new('https://www.example.com/{foo}') - expect(template).to be_eql(other_template) - expect(other_template).to be_eql(template) - end - it 'is not equal when the pattern differs' do - other_template = Addressable::Template.new('https://www.example.com/{bar}') - expect(template).to_not be_eql(other_template) - expect(other_template).to_not be_eql(template) - end - it 'is not equal to non-templates' do - uri = 'https://www.example.com/foo/bar' - addressable_template = Addressable::Template.new uri - addressable_uri = Addressable::URI.parse uri - expect(addressable_template).to_not be_eql(addressable_uri) - expect(addressable_uri).to_not be_eql(addressable_template) - end -end - -describe "==" do - let(:template) { Addressable::Template.new('https://www.example.com/{foo}') } - it 'is equal when the pattern matches' do - other_template = Addressable::Template.new('https://www.example.com/{foo}') - expect(template).to eq other_template - expect(other_template).to eq template - end - it 'is not equal when the pattern differs' do - other_template = Addressable::Template.new('https://www.example.com/{bar}') - expect(template).not_to eq other_template - expect(other_template).not_to eq template - end - it 'is not equal to non-templates' do - uri = 'https://www.example.com/foo/bar' - addressable_template = Addressable::Template.new uri - addressable_uri = Addressable::URI.parse uri - expect(addressable_template).not_to eq addressable_uri - expect(addressable_uri).not_to eq addressable_template - end -end - -describe "#to_regexp" do - it "does not match the first line of multiline strings" do - uri = "https://www.example.com/bar" - template = Addressable::Template.new(uri) - expect(template.match(uri)).not_to be_nil - expect(template.match("#{uri}\ngarbage")).to be_nil - end -end - -describe "Type conversion" do - subject { - { - :var => true, - :hello => 1234, - :nothing => nil, - :sym => :symbolic, - :decimal => BigDecimal('1') - } - } - - it_behaves_like 'expands', { - '{var}' => 'true', - '{hello}' => '1234', - '{nothing}' => '', - '{sym}' => 'symbolic', - '{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1' - } -end - -describe "Level 1:" do - subject { - {:var => "value", :hello => "Hello World!"} - } - it_behaves_like 'expands', { - '{var}' => 'value', - '{hello}' => 'Hello%20World%21' - } -end - -describe "Level 2" do - subject { - { - :var => "value", - :hello => "Hello World!", - :path => "/foo/bar" - } - } - context "Operator +:" do - it_behaves_like 'expands', { - '{+var}' => 'value', - '{+hello}' => 'Hello%20World!', - '{+path}/here' => '/foo/bar/here', - 'here?ref={+path}' => 'here?ref=/foo/bar' - } - end - context "Operator #:" do - it_behaves_like 'expands', { - 'X{#var}' => 'X#value', - 'X{#hello}' => 'X#Hello%20World!' - } - end -end - -describe "Level 3" do - subject { - { - :var => "value", - :hello => "Hello World!", - :empty => "", - :path => "/foo/bar", - :x => "1024", - :y => "768" - } - } - context "Operator nil (multiple vars):" do - it_behaves_like 'expands', { - 'map?{x,y}' => 'map?1024,768', - '{x,hello,y}' => '1024,Hello%20World%21,768' - } - end - context "Operator + (multiple vars):" do - it_behaves_like 'expands', { - '{+x,hello,y}' => '1024,Hello%20World!,768', - '{+path,x}/here' => '/foo/bar,1024/here' - } - end - context "Operator # (multiple vars):" do - it_behaves_like 'expands', { - '{#x,hello,y}' => '#1024,Hello%20World!,768', - '{#path,x}/here' => '#/foo/bar,1024/here' - } - end - context "Operator ." do - it_behaves_like 'expands', { - 'X{.var}' => 'X.value', - 'X{.x,y}' => 'X.1024.768' - } - end - context "Operator /" do - it_behaves_like 'expands', { - '{/var}' => '/value', - '{/var,x}/here' => '/value/1024/here' - } - end - context "Operator ;" do - it_behaves_like 'expands', { - '{;x,y}' => ';x=1024;y=768', - '{;x,y,empty}' => ';x=1024;y=768;empty' - } - end - context "Operator ?" do - it_behaves_like 'expands', { - '{?x,y}' => '?x=1024&y=768', - '{?x,y,empty}' => '?x=1024&y=768&empty=' - } - end - context "Operator &" do - it_behaves_like 'expands', { - '?fixed=yes{&x}' => '?fixed=yes&x=1024', - '{&x,y,empty}' => '&x=1024&y=768&empty=' - } - end -end - -describe "Level 4" do - subject { - { - :var => "value", - :hello => "Hello World!", - :path => "/foo/bar", - :semi => ";", - :list => %w(red green blue), - :keys => {"semi" => ';', "dot" => '.', :comma => ','} - } - } - context "Expansion with value modifiers" do - it_behaves_like 'expands', { - '{var:3}' => 'val', - '{var:30}' => 'value', - '{list}' => 'red,green,blue', - '{list*}' => 'red,green,blue', - '{keys}' => 'semi,%3B,dot,.,comma,%2C', - '{keys*}' => 'semi=%3B,dot=.,comma=%2C', - } - end - context "Operator + with value modifiers" do - it_behaves_like 'expands', { - '{+path:6}/here' => '/foo/b/here', - '{+list}' => 'red,green,blue', - '{+list*}' => 'red,green,blue', - '{+keys}' => 'semi,;,dot,.,comma,,', - '{+keys*}' => 'semi=;,dot=.,comma=,', - } - end - context "Operator # with value modifiers" do - it_behaves_like 'expands', { - '{#path:6}/here' => '#/foo/b/here', - '{#list}' => '#red,green,blue', - '{#list*}' => '#red,green,blue', - '{#keys}' => '#semi,;,dot,.,comma,,', - '{#keys*}' => '#semi=;,dot=.,comma=,', - } - end - context "Operator . with value modifiers" do - it_behaves_like 'expands', { - 'X{.var:3}' => 'X.val', - 'X{.list}' => 'X.red,green,blue', - 'X{.list*}' => 'X.red.green.blue', - 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C', - 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C', - } - end - context "Operator / with value modifiers" do - it_behaves_like 'expands', { - '{/var:1,var}' => '/v/value', - '{/list}' => '/red,green,blue', - '{/list*}' => '/red/green/blue', - '{/list*,path:4}' => '/red/green/blue/%2Ffoo', - '{/keys}' => '/semi,%3B,dot,.,comma,%2C', - '{/keys*}' => '/semi=%3B/dot=./comma=%2C', - } - end - context "Operator ; with value modifiers" do - it_behaves_like 'expands', { - '{;hello:5}' => ';hello=Hello', - '{;list}' => ';list=red,green,blue', - '{;list*}' => ';list=red;list=green;list=blue', - '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C', - '{;keys*}' => ';semi=%3B;dot=.;comma=%2C', - } - end - context "Operator ? with value modifiers" do - it_behaves_like 'expands', { - '{?var:3}' => '?var=val', - '{?list}' => '?list=red,green,blue', - '{?list*}' => '?list=red&list=green&list=blue', - '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C', - '{?keys*}' => '?semi=%3B&dot=.&comma=%2C', - } - end - context "Operator & with value modifiers" do - it_behaves_like 'expands', { - '{&var:3}' => '&var=val', - '{&list}' => '&list=red,green,blue', - '{&list*}' => '&list=red&list=green&list=blue', - '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C', - '{&keys*}' => '&semi=%3B&dot=.&comma=%2C', - } - end -end -describe "Modifiers" do - subject { - { - :var => "value", - :semi => ";", - :year => [1965, 2000, 2012], - :dom => %w(example com) - } - } - context "length" do - it_behaves_like 'expands', { - '{var:3}' => 'val', - '{var:30}' => 'value', - '{var}' => 'value', - '{semi}' => '%3B', - '{semi:2}' => '%3B' - } - end - context "explode" do - it_behaves_like 'expands', { - 'find{?year*}' => 'find?year=1965&year=2000&year=2012', - 'www{.dom*}' => 'www.example.com', - } - end -end -describe "Expansion" do - subject { - { - :count => ["one", "two", "three"], - :dom => ["example", "com"], - :dub => "me/too", - :hello => "Hello World!", - :half => "50%", - :var => "value", - :who => "fred", - :base => "http://example.com/home/", - :path => "/foo/bar", - :list => ["red", "green", "blue"], - :keys => {"semi" => ";","dot" => ".",:comma => ","}, - :v => "6", - :x => "1024", - :y => "768", - :empty => "", - :empty_keys => {}, - :undef => nil - } - } - context "concatenation" do - it_behaves_like 'expands', { - '{count}' => 'one,two,three', - '{count*}' => 'one,two,three', - '{/count}' => '/one,two,three', - '{/count*}' => '/one/two/three', - '{;count}' => ';count=one,two,three', - '{;count*}' => ';count=one;count=two;count=three', - '{?count}' => '?count=one,two,three', - '{?count*}' => '?count=one&count=two&count=three', - '{&count*}' => '&count=one&count=two&count=three' - } - end - context "simple expansion" do - it_behaves_like 'expands', { - '{var}' => 'value', - '{hello}' => 'Hello%20World%21', - '{half}' => '50%25', - 'O{empty}X' => 'OX', - 'O{undef}X' => 'OX', - '{x,y}' => '1024,768', - '{x,hello,y}' => '1024,Hello%20World%21,768', - '?{x,empty}' => '?1024,', - '?{x,undef}' => '?1024', - '?{undef,y}' => '?768', - '{var:3}' => 'val', - '{var:30}' => 'value', - '{list}' => 'red,green,blue', - '{list*}' => 'red,green,blue', - '{keys}' => 'semi,%3B,dot,.,comma,%2C', - '{keys*}' => 'semi=%3B,dot=.,comma=%2C', - } - end - context "reserved expansion (+)" do - it_behaves_like 'expands', { - '{+var}' => 'value', - '{+hello}' => 'Hello%20World!', - '{+half}' => '50%25', - '{base}index' => 'http%3A%2F%2Fexample.com%2Fhome%2Findex', - '{+base}index' => 'http://example.com/home/index', - 'O{+empty}X' => 'OX', - 'O{+undef}X' => 'OX', - '{+path}/here' => '/foo/bar/here', - 'here?ref={+path}' => 'here?ref=/foo/bar', - 'up{+path}{var}/here' => 'up/foo/barvalue/here', - '{+x,hello,y}' => '1024,Hello%20World!,768', - '{+path,x}/here' => '/foo/bar,1024/here', - '{+path:6}/here' => '/foo/b/here', - '{+list}' => 'red,green,blue', - '{+list*}' => 'red,green,blue', - '{+keys}' => 'semi,;,dot,.,comma,,', - '{+keys*}' => 'semi=;,dot=.,comma=,', - } - end - context "fragment expansion (#)" do - it_behaves_like 'expands', { - '{#var}' => '#value', - '{#hello}' => '#Hello%20World!', - '{#half}' => '#50%25', - 'foo{#empty}' => 'foo#', - 'foo{#undef}' => 'foo', - '{#x,hello,y}' => '#1024,Hello%20World!,768', - '{#path,x}/here' => '#/foo/bar,1024/here', - '{#path:6}/here' => '#/foo/b/here', - '{#list}' => '#red,green,blue', - '{#list*}' => '#red,green,blue', - '{#keys}' => '#semi,;,dot,.,comma,,', - '{#keys*}' => '#semi=;,dot=.,comma=,', - } - end - context "label expansion (.)" do - it_behaves_like 'expands', { - '{.who}' => '.fred', - '{.who,who}' => '.fred.fred', - '{.half,who}' => '.50%25.fred', - 'www{.dom*}' => 'www.example.com', - 'X{.var}' => 'X.value', - 'X{.empty}' => 'X.', - 'X{.undef}' => 'X', - 'X{.var:3}' => 'X.val', - 'X{.list}' => 'X.red,green,blue', - 'X{.list*}' => 'X.red.green.blue', - 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C', - 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C', - 'X{.empty_keys}' => 'X', - 'X{.empty_keys*}' => 'X' - } - end - context "path expansion (/)" do - it_behaves_like 'expands', { - '{/who}' => '/fred', - '{/who,who}' => '/fred/fred', - '{/half,who}' => '/50%25/fred', - '{/who,dub}' => '/fred/me%2Ftoo', - '{/var}' => '/value', - '{/var,empty}' => '/value/', - '{/var,undef}' => '/value', - '{/var,x}/here' => '/value/1024/here', - '{/var:1,var}' => '/v/value', - '{/list}' => '/red,green,blue', - '{/list*}' => '/red/green/blue', - '{/list*,path:4}' => '/red/green/blue/%2Ffoo', - '{/keys}' => '/semi,%3B,dot,.,comma,%2C', - '{/keys*}' => '/semi=%3B/dot=./comma=%2C', - } - end - context "path-style expansion (;)" do - it_behaves_like 'expands', { - '{;who}' => ';who=fred', - '{;half}' => ';half=50%25', - '{;empty}' => ';empty', - '{;v,empty,who}' => ';v=6;empty;who=fred', - '{;v,bar,who}' => ';v=6;who=fred', - '{;x,y}' => ';x=1024;y=768', - '{;x,y,empty}' => ';x=1024;y=768;empty', - '{;x,y,undef}' => ';x=1024;y=768', - '{;hello:5}' => ';hello=Hello', - '{;list}' => ';list=red,green,blue', - '{;list*}' => ';list=red;list=green;list=blue', - '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C', - '{;keys*}' => ';semi=%3B;dot=.;comma=%2C', - } - end - context "form query expansion (?)" do - it_behaves_like 'expands', { - '{?who}' => '?who=fred', - '{?half}' => '?half=50%25', - '{?x,y}' => '?x=1024&y=768', - '{?x,y,empty}' => '?x=1024&y=768&empty=', - '{?x,y,undef}' => '?x=1024&y=768', - '{?var:3}' => '?var=val', - '{?list}' => '?list=red,green,blue', - '{?list*}' => '?list=red&list=green&list=blue', - '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C', - '{?keys*}' => '?semi=%3B&dot=.&comma=%2C', - } - end - context "form query expansion (&)" do - it_behaves_like 'expands', { - '{&who}' => '&who=fred', - '{&half}' => '&half=50%25', - '?fixed=yes{&x}' => '?fixed=yes&x=1024', - '{&x,y,empty}' => '&x=1024&y=768&empty=', - '{&x,y,undef}' => '&x=1024&y=768', - '{&var:3}' => '&var=val', - '{&list}' => '&list=red,green,blue', - '{&list*}' => '&list=red&list=green&list=blue', - '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C', - '{&keys*}' => '&semi=%3B&dot=.&comma=%2C', - } - end - context "non-string key in match data" do - subject {Addressable::Template.new("http://example.com/{one}")} - - it "raises TypeError" do - expect { subject.expand(Object.new => "1") }.to raise_error TypeError - end - end -end - -class ExampleTwoProcessor - def self.restore(name, value) - return value.gsub(/-/, " ") if name == "query" - return value - end - - def self.match(name) - return ".*?" if name == "first" - return ".*" - end - def self.validate(name, value) - return !!(value =~ /^[\w ]+$/) if name == "query" - return true - end - - def self.transform(name, value) - return value.gsub(/ /, "+") if name == "query" - return value - end -end - -class DumbProcessor - def self.match(name) - return ".*?" if name == "first" - end -end - -describe Addressable::Template do - describe 'initialize' do - context 'with a non-string' do - it 'raises a TypeError' do - expect { Addressable::Template.new(nil) }.to raise_error(TypeError) - end - end - end - - describe 'freeze' do - subject { Addressable::Template.new("http://example.com/{first}/{+second}/") } - it 'freezes the template' do - expect(subject.freeze).to be_frozen - end - end - - describe "Matching" do - let(:uri){ - Addressable::URI.parse( - "http://example.com/search/an-example-search-query/" - ) - } - let(:uri2){ - Addressable::URI.parse("http://example.com/a/b/c/") - } - let(:uri3){ - Addressable::URI.parse("http://example.com/;a=1;b=2;c=3;first=foo") - } - let(:uri4){ - Addressable::URI.parse("http://example.com/?a=1&b=2&c=3&first=foo") - } - let(:uri5){ - "http://example.com/foo" - } - context "first uri with ExampleTwoProcessor" do - subject { - Addressable::Template.new( - "http://example.com/search/{query}/" - ).match(uri, ExampleTwoProcessor) - } - its(:variables){ should == ["query"] } - its(:captures){ should == ["an example search query"] } - end - - context "second uri with ExampleTwoProcessor" do - subject { - Addressable::Template.new( - "http://example.com/{first}/{+second}/" - ).match(uri2, ExampleTwoProcessor) - } - its(:variables){ should == ["first", "second"] } - its(:captures){ should == ["a", "b/c"] } - end - - context "second uri with DumbProcessor" do - subject { - Addressable::Template.new( - "http://example.com/{first}/{+second}/" - ).match(uri2, DumbProcessor) - } - its(:variables){ should == ["first", "second"] } - its(:captures){ should == ["a", "b/c"] } - end - - context "second uri" do - subject { - Addressable::Template.new( - "http://example.com/{first}{/second*}/" - ).match(uri2) - } - its(:variables){ should == ["first", "second"] } - its(:captures){ should == ["a", ["b","c"]] } - end - context "third uri" do - subject { - Addressable::Template.new( - "http://example.com/{;hash*,first}" - ).match(uri3) - } - its(:variables){ should == ["hash", "first"] } - its(:captures){ should == [ - {"a" => "1", "b" => "2", "c" => "3", "first" => "foo"}, nil] } - end - # Note that this expansion is impossible to revert deterministically - the - # * operator means first could have been a key of hash or a separate key. - # Semantically, a separate key is more likely, but both are possible. - context "fourth uri" do - subject { - Addressable::Template.new( - "http://example.com/{?hash*,first}" - ).match(uri4) - } - its(:variables){ should == ["hash", "first"] } - its(:captures){ should == [ - {"a" => "1", "b" => "2", "c" => "3", "first"=> "foo"}, nil] } - end - context "fifth uri" do - subject { - Addressable::Template.new( - "http://example.com/{path}{?hash*,first}" - ).match(uri5) - } - its(:variables){ should == ["path", "hash", "first"] } - its(:captures){ should == ["foo", nil, nil] } - end - end - - describe 'match' do - subject { Addressable::Template.new('http://example.com/first/second/') } - context 'when the URI is the same as the template' do - it 'returns the match data itself with an empty mapping' do - uri = Addressable::URI.parse('http://example.com/first/second/') - match_data = subject.match(uri) - expect(match_data).to be_an Addressable::Template::MatchData - expect(match_data.uri).to eq(uri) - expect(match_data.template).to eq(subject) - expect(match_data.mapping).to be_empty - expect(match_data.inspect).to be_an String - end - end - end - - describe "extract" do - let(:template) { - Addressable::Template.new( - "http://{host}{/segments*}/{?one,two,bogus}{#fragment}" - ) - } - let(:uri){ "http://example.com/a/b/c/?one=1&two=2#foo" } - let(:uri2){ "http://example.com/a/b/c/#foo" } - it "should be able to extract with queries" do - expect(template.extract(uri)).to eq({ - "host" => "example.com", - "segments" => %w(a b c), - "one" => "1", - "bogus" => nil, - "two" => "2", - "fragment" => "foo" - }) - end - it "should be able to extract without queries" do - expect(template.extract(uri2)).to eq({ - "host" => "example.com", - "segments" => %w(a b c), - "one" => nil, - "bogus" => nil, - "two" => nil, - "fragment" => "foo" - }) - end - - context "issue #137" do - subject { Addressable::Template.new('/path{?page,per_page}') } - - it "can match empty" do - data = subject.extract("/path") - expect(data["page"]).to eq(nil) - expect(data["per_page"]).to eq(nil) - expect(data.keys.sort).to eq(['page', 'per_page']) - end - - it "can match first var" do - data = subject.extract("/path?page=1") - expect(data["page"]).to eq("1") - expect(data["per_page"]).to eq(nil) - expect(data.keys.sort).to eq(['page', 'per_page']) - end - - it "can match second var" do - data = subject.extract("/path?per_page=1") - expect(data["page"]).to eq(nil) - expect(data["per_page"]).to eq("1") - expect(data.keys.sort).to eq(['page', 'per_page']) - end - - it "can match both vars" do - data = subject.extract("/path?page=2&per_page=1") - expect(data["page"]).to eq("2") - expect(data["per_page"]).to eq("1") - expect(data.keys.sort).to eq(['page', 'per_page']) - end - end - end - - describe "Partial expand with symbols" do - context "partial_expand with two simple values" do - subject { - Addressable::Template.new("http://example.com/{one}/{two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand(:one => "1").pattern).to eq( - "http://example.com/1/{two}/" - ) - end - end - context "partial_expand query with missing param in middle" do - subject { - Addressable::Template.new("http://example.com/{?one,two,three}/") - } - it "builds a new pattern" do - expect(subject.partial_expand(:one => "1", :three => "3").pattern).to eq( - "http://example.com/?one=1{&two}&three=3/" - ) - end - end - context "partial_expand form style query with missing param at beginning" do - subject { - Addressable::Template.new("http://example.com/{?one,two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand(:two => "2").pattern).to eq( - "http://example.com/?two=2{&one}/" - ) - end - end - context "issue #307 - partial_expand form query with nil params" do - subject do - Addressable::Template.new("http://example.com/{?one,two,three}/") - end - it "builds a new pattern with two=nil" do - expect(subject.partial_expand(two: nil).pattern).to eq( - "http://example.com/{?one}{&three}/" - ) - end - it "builds a new pattern with one=nil and two=nil" do - expect(subject.partial_expand(one: nil, two: nil).pattern).to eq( - "http://example.com/{?three}/" - ) - end - it "builds a new pattern with one=1 and two=nil" do - expect(subject.partial_expand(one: 1, two: nil).pattern).to eq( - "http://example.com/?one=1{&three}/" - ) - end - it "builds a new pattern with one=nil and two=2" do - expect(subject.partial_expand(one: nil, two: 2).pattern).to eq( - "http://example.com/?two=2{&three}/" - ) - end - it "builds a new pattern with one=nil" do - expect(subject.partial_expand(one: nil).pattern).to eq( - "http://example.com/{?two}{&three}/" - ) - end - end - context "partial_expand with query string" do - subject { - Addressable::Template.new("http://example.com/{?two,one}/") - } - it "builds a new pattern" do - expect(subject.partial_expand(:one => "1").pattern).to eq( - "http://example.com/?one=1{&two}/" - ) - end - end - context "partial_expand with path operator" do - subject { - Addressable::Template.new("http://example.com{/one,two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand(:one => "1").pattern).to eq( - "http://example.com/1{/two}/" - ) - end - end - context "partial expand with unicode values" do - subject do - Addressable::Template.new("http://example.com/{resource}/{query}/") - end - it "normalizes unicode by default" do - template = subject.partial_expand("query" => "Cafe\u0301") - expect(template.pattern).to eq( - "http://example.com/{resource}/Caf%C3%A9/" - ) - end - - it "normalizes as unicode even with wrong encoding specified" do - template = subject.partial_expand("query" => "Cafe\u0301".b) - expect(template.pattern).to eq( - "http://example.com/{resource}/Caf%C3%A9/" - ) - end - - it "raises on invalid unicode input" do - expect { - subject.partial_expand("query" => "M\xE9thode".b) - }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8") - end - - it "does not normalize unicode when byte semantics requested" do - template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false) - expect(template.pattern).to eq( - "http://example.com/{resource}/Cafe%CC%81/" - ) - end - end - end - describe "Partial expand with strings" do - context "partial_expand with two simple values" do - subject { - Addressable::Template.new("http://example.com/{one}/{two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1").pattern).to eq( - "http://example.com/1/{two}/" - ) - end - end - context "partial_expand query with missing param in middle" do - subject { - Addressable::Template.new("http://example.com/{?one,two,three}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq( - "http://example.com/?one=1{&two}&three=3/" - ) - end - end - context "partial_expand with query string" do - subject { - Addressable::Template.new("http://example.com/{?two,one}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1").pattern).to eq( - "http://example.com/?one=1{&two}/" - ) - end - end - context "partial_expand with path operator" do - subject { - Addressable::Template.new("http://example.com{/one,two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1").pattern).to eq( - "http://example.com/1{/two}/" - ) - end - end - end - describe "Expand" do - context "expand with unicode values" do - subject do - Addressable::Template.new("http://example.com/search/{query}/") - end - it "normalizes unicode by default" do - uri = subject.expand("query" => "Cafe\u0301").to_str - expect(uri).to eq("http://example.com/search/Caf%C3%A9/") - end - - it "normalizes as unicode even with wrong encoding specified" do - uri = subject.expand("query" => "Cafe\u0301".b).to_str - expect(uri).to eq("http://example.com/search/Caf%C3%A9/") - end - - it "raises on invalid unicode input" do - expect { - subject.expand("query" => "M\xE9thode".b).to_str - }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8") - end - - it "does not normalize unicode when byte semantics requested" do - uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str - expect(uri).to eq("http://example.com/search/Cafe%CC%81/") - end - end - context "expand with a processor" do - subject { - Addressable::Template.new("http://example.com/search/{query}/") - } - it "processes spaces" do - expect(subject.expand({"query" => "an example search query"}, - ExampleTwoProcessor).to_str).to eq( - "http://example.com/search/an+example+search+query/" - ) - end - it "validates" do - expect{ - subject.expand({"query" => "Bogus!"}, - ExampleTwoProcessor).to_str - }.to raise_error(Addressable::Template::InvalidTemplateValueError) - end - end - context "partial_expand query with missing param in middle" do - subject { - Addressable::Template.new("http://example.com/{?one,two,three}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq( - "http://example.com/?one=1{&two}&three=3/" - ) - end - end - context "partial_expand with query string" do - subject { - Addressable::Template.new("http://example.com/{?two,one}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1").pattern).to eq( - "http://example.com/?one=1{&two}/" - ) - end - end - context "partial_expand with path operator" do - subject { - Addressable::Template.new("http://example.com{/one,two}/") - } - it "builds a new pattern" do - expect(subject.partial_expand("one" => "1").pattern).to eq( - "http://example.com/1{/two}/" - ) - end - end - end - context "Matching with operators" do - describe "Level 1:" do - subject { Addressable::Template.new("foo{foo}/{bar}baz") } - it "can match" do - data = subject.match("foofoo/bananabaz") - expect(data.mapping["foo"]).to eq("foo") - expect(data.mapping["bar"]).to eq("banana") - end - it "can fail" do - expect(subject.match("bar/foo")).to be_nil - expect(subject.match("foobaz")).to be_nil - end - it "can match empty" do - data = subject.match("foo/baz") - expect(data.mapping["foo"]).to eq(nil) - expect(data.mapping["bar"]).to eq(nil) - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - - describe "Level 2:" do - subject { Addressable::Template.new("foo{+foo}{#bar}baz") } - it "can match" do - data = subject.match("foo/test/banana#bazbaz") - expect(data.mapping["foo"]).to eq("/test/banana") - expect(data.mapping["bar"]).to eq("baz") - end - it "can match empty level 2 #" do - data = subject.match("foo/test/bananabaz") - expect(data.mapping["foo"]).to eq("/test/banana") - expect(data.mapping["bar"]).to eq(nil) - data = subject.match("foo/test/banana#baz") - expect(data.mapping["foo"]).to eq("/test/banana") - expect(data.mapping["bar"]).to eq("") - end - it "can match empty level 2 +" do - data = subject.match("foobaz") - expect(data.mapping["foo"]).to eq(nil) - expect(data.mapping["bar"]).to eq(nil) - data = subject.match("foo#barbaz") - expect(data.mapping["foo"]).to eq(nil) - expect(data.mapping["bar"]).to eq("bar") - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - - describe "Level 3:" do - context "no operator" do - subject { Addressable::Template.new("foo{foo,bar}baz") } - it "can match" do - data = subject.match("foofoo,barbaz") - expect(data.mapping["foo"]).to eq("foo") - expect(data.mapping["bar"]).to eq("bar") - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - context "+ operator" do - subject { Addressable::Template.new("foo{+foo,bar}baz") } - it "can match" do - data = subject.match("foofoo/bar,barbaz") - expect(data.mapping["bar"]).to eq("foo/bar,bar") - expect(data.mapping["foo"]).to eq("") - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - context ". operator" do - subject { Addressable::Template.new("foo{.foo,bar}baz") } - it "can match" do - data = subject.match("foo.foo.barbaz") - expect(data.mapping["foo"]).to eq("foo") - expect(data.mapping["bar"]).to eq("bar") - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - context "/ operator" do - subject { Addressable::Template.new("foo{/foo,bar}baz") } - it "can match" do - data = subject.match("foo/foo/barbaz") - expect(data.mapping["foo"]).to eq("foo") - expect(data.mapping["bar"]).to eq("bar") - end - it "lists vars" do - expect(subject.variables).to eq(["foo", "bar"]) - end - end - context "; operator" do - subject { Addressable::Template.new("foo{;foo,bar,baz}baz") } - it "can match" do - data = subject.match("foo;foo=bar%20baz;bar=foo;bazbaz") - expect(data.mapping["foo"]).to eq("bar baz") - expect(data.mapping["bar"]).to eq("foo") - expect(data.mapping["baz"]).to eq("") - end - it "lists vars" do - expect(subject.variables).to eq(%w(foo bar baz)) - end - end - context "? operator" do - context "test" do - subject { Addressable::Template.new("foo{?foo,bar}baz") } - it "can match" do - data = subject.match("foo?foo=bar%20baz&bar=foobaz") - expect(data.mapping["foo"]).to eq("bar baz") - expect(data.mapping["bar"]).to eq("foo") - end - it "lists vars" do - expect(subject.variables).to eq(%w(foo bar)) - end - end - - context "issue #137" do - subject { Addressable::Template.new('/path{?page,per_page}') } - - it "can match empty" do - data = subject.match("/path") - expect(data.mapping["page"]).to eq(nil) - expect(data.mapping["per_page"]).to eq(nil) - expect(data.mapping.keys.sort).to eq(['page', 'per_page']) - end - - it "can match first var" do - data = subject.match("/path?page=1") - expect(data.mapping["page"]).to eq("1") - expect(data.mapping["per_page"]).to eq(nil) - expect(data.mapping.keys.sort).to eq(['page', 'per_page']) - end - - it "can match second var" do - data = subject.match("/path?per_page=1") - expect(data.mapping["page"]).to eq(nil) - expect(data.mapping["per_page"]).to eq("1") - expect(data.mapping.keys.sort).to eq(['page', 'per_page']) - end - - it "can match both vars" do - data = subject.match("/path?page=2&per_page=1") - expect(data.mapping["page"]).to eq("2") - expect(data.mapping["per_page"]).to eq("1") - expect(data.mapping.keys.sort).to eq(['page', 'per_page']) - end - end - - context "issue #71" do - subject { Addressable::Template.new("http://cyberscore.dev/api/users{?username}") } - it "can match" do - data = subject.match("http://cyberscore.dev/api/users?username=foobaz") - expect(data.mapping["username"]).to eq("foobaz") - end - it "lists vars" do - expect(subject.variables).to eq(%w(username)) - expect(subject.keys).to eq(%w(username)) - end - end - end - context "& operator" do - subject { Addressable::Template.new("foo{&foo,bar}baz") } - it "can match" do - data = subject.match("foo&foo=bar%20baz&bar=foobaz") - expect(data.mapping["foo"]).to eq("bar baz") - expect(data.mapping["bar"]).to eq("foo") - end - it "lists vars" do - expect(subject.variables).to eq(%w(foo bar)) - end - end - end - end - - context "support regexes:" do - context "EXPRESSION" do - subject { Addressable::Template::EXPRESSION } - it "should be able to match an expression" do - expect(subject).to match("{foo}") - expect(subject).to match("{foo,9}") - expect(subject).to match("{foo.bar,baz}") - expect(subject).to match("{+foo.bar,baz}") - expect(subject).to match("{foo,foo%20bar}") - expect(subject).to match("{#foo:20,baz*}") - expect(subject).to match("stuff{#foo:20,baz*}things") - end - it "should fail on non vars" do - expect(subject).not_to match("!{foo") - expect(subject).not_to match("{foo.bar.}") - expect(subject).not_to match("!{}") - end - end - context "VARNAME" do - subject { Addressable::Template::VARNAME } - it "should be able to match a variable" do - expect(subject).to match("foo") - expect(subject).to match("9") - expect(subject).to match("foo.bar") - expect(subject).to match("foo_bar") - expect(subject).to match("foo_bar.baz") - expect(subject).to match("foo%20bar") - expect(subject).to match("foo%20bar.baz") - end - it "should fail on non vars" do - expect(subject).not_to match("!foo") - expect(subject).not_to match("foo.bar.") - expect(subject).not_to match("foo%2%00bar") - expect(subject).not_to match("foo_ba%r") - expect(subject).not_to match("foo_bar*") - expect(subject).not_to match("foo_bar:20") - end - - it 'should parse in a reasonable time' do - expect do - Timeout.timeout(0.1) do - expect(subject).not_to match("0"*25 + "!") - end - end.not_to raise_error - end - end - context "VARIABLE_LIST" do - subject { Addressable::Template::VARIABLE_LIST } - it "should be able to match a variable list" do - expect(subject).to match("foo,bar") - expect(subject).to match("foo") - expect(subject).to match("foo,bar*,baz") - expect(subject).to match("foo.bar,bar_baz*,baz:12") - end - it "should fail on non vars" do - expect(subject).not_to match(",foo,bar*,baz") - expect(subject).not_to match("foo,*bar,baz") - expect(subject).not_to match("foo,,bar*,baz") - end - end - context "VARSPEC" do - subject { Addressable::Template::VARSPEC } - it "should be able to match a variable with modifier" do - expect(subject).to match("9:8") - expect(subject).to match("foo.bar*") - expect(subject).to match("foo_bar:12") - expect(subject).to match("foo_bar.baz*") - expect(subject).to match("foo%20bar:12") - expect(subject).to match("foo%20bar.baz*") - end - it "should fail on non vars" do - expect(subject).not_to match("!foo") - expect(subject).not_to match("*foo") - expect(subject).not_to match("fo*o") - expect(subject).not_to match("fo:o") - expect(subject).not_to match("foo:") - end - end - end -end - -describe Addressable::Template::MatchData do - let(:template) { Addressable::Template.new('{foo}/{bar}') } - subject(:its) { template.match('ab/cd') } - its(:uri) { should == Addressable::URI.parse('ab/cd') } - its(:template) { should == template } - its(:mapping) { should == { 'foo' => 'ab', 'bar' => 'cd' } } - its(:variables) { should == ['foo', 'bar'] } - its(:keys) { should == ['foo', 'bar'] } - its(:names) { should == ['foo', 'bar'] } - its(:values) { should == ['ab', 'cd'] } - its(:captures) { should == ['ab', 'cd'] } - its(:to_a) { should == ['ab/cd', 'ab', 'cd'] } - its(:to_s) { should == 'ab/cd' } - its(:string) { should == its.to_s } - its(:pre_match) { should == "" } - its(:post_match) { should == "" } - - describe 'values_at' do - it 'returns an array with the values' do - expect(its.values_at(0, 2)).to eq(['ab/cd', 'cd']) - end - it 'allows mixing integer an string keys' do - expect(its.values_at('foo', 1)).to eq(['ab', 'ab']) - end - it 'accepts unknown keys' do - expect(its.values_at('baz', 'foo')).to eq([nil, 'ab']) - end - end - - describe '[]' do - context 'string key' do - it 'returns the corresponding capture' do - expect(its['foo']).to eq('ab') - expect(its['bar']).to eq('cd') - end - it 'returns nil for unknown keys' do - expect(its['baz']).to be_nil - end - end - context 'symbol key' do - it 'returns the corresponding capture' do - expect(its[:foo]).to eq('ab') - expect(its[:bar]).to eq('cd') - end - it 'returns nil for unknown keys' do - expect(its[:baz]).to be_nil - end - end - context 'integer key' do - it 'returns the full URI for index 0' do - expect(its[0]).to eq('ab/cd') - end - it 'returns the corresponding capture' do - expect(its[1]).to eq('ab') - expect(its[2]).to eq('cd') - end - it 'returns nil for unknown keys' do - expect(its[3]).to be_nil - end - end - context 'other key' do - it 'raises an exception' do - expect { its[Object.new] }.to raise_error(TypeError) - end - end - context 'with length' do - it 'returns an array starting at index with given length' do - expect(its[0, 2]).to eq(['ab/cd', 'ab']) - expect(its[2, 1]).to eq(['cd']) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb deleted file mode 100644 index 26ee923..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb +++ /dev/null @@ -1,6840 +0,0 @@ -# frozen_string_literal: true - -# Copyright (C) Bob Aman -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -require "spec_helper" - -require "addressable/uri" -require "uri" -require "ipaddr" -require "yaml" - -if !"".respond_to?("force_encoding") - class String - def force_encoding(encoding) - @encoding = encoding - end - - def encoding - @encoding ||= Encoding::ASCII_8BIT - end - end - - class Encoding - def initialize(name) - @name = name - end - - def to_s - return @name - end - - UTF_8 = Encoding.new("UTF-8") - ASCII_8BIT = Encoding.new("US-ASCII") - end -end - -module Fake - module URI - class HTTP - def initialize(uri) - @uri = uri - end - - def to_s - return @uri.to_s - end - - alias :to_str :to_s - end - end -end - -describe Addressable::URI, "when created with a non-numeric port number" do - it "should raise an error" do - expect do - Addressable::URI.new(:port => "bogus") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with a invalid encoded port number" do - it "should raise an error" do - expect do - Addressable::URI.new(:port => "%eb") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with a non-string scheme" do - it "should raise an error" do - expect do - Addressable::URI.new(:scheme => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string user" do - it "should raise an error" do - expect do - Addressable::URI.new(:user => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string password" do - it "should raise an error" do - expect do - Addressable::URI.new(:password => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string userinfo" do - it "should raise an error" do - expect do - Addressable::URI.new(:userinfo => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string host" do - it "should raise an error" do - expect do - Addressable::URI.new(:host => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string authority" do - it "should raise an error" do - expect do - Addressable::URI.new(:authority => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string path" do - it "should raise an error" do - expect do - Addressable::URI.new(:path => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string query" do - it "should raise an error" do - expect do - Addressable::URI.new(:query => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a non-string fragment" do - it "should raise an error" do - expect do - Addressable::URI.new(:fragment => :bogus) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when created with a scheme but no hierarchical " + - "segment" do - it "should raise an error" do - expect do - Addressable::URI.parse("http:") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "quote handling" do - describe 'in host name' do - it "should raise an error for single quote" do - expect do - Addressable::URI.parse("http://local\"host/") - end.to raise_error(Addressable::URI::InvalidURIError) - end - end -end - -describe Addressable::URI, "newline normalization" do - it "should not accept newlines in scheme" do - expect do - Addressable::URI.parse("ht%0atp://localhost/") - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should not unescape newline in path" do - uri = Addressable::URI.parse("http://localhost/%0a").normalize - expect(uri.to_s).to eq("http://localhost/%0A") - end - - it "should not unescape newline in hostname" do - uri = Addressable::URI.parse("http://local%0ahost/").normalize - expect(uri.to_s).to eq("http://local%0Ahost/") - end - - it "should not unescape newline in username" do - uri = Addressable::URI.parse("http://foo%0abar@localhost/").normalize - expect(uri.to_s).to eq("http://foo%0Abar@localhost/") - end - - it "should not unescape newline in username" do - uri = Addressable::URI.parse("http://example:foo%0abar@example/").normalize - expect(uri.to_s).to eq("http://example:foo%0Abar@example/") - end - - it "should not accept newline in hostname" do - uri = Addressable::URI.parse("http://localhost/") - expect do - uri.host = "local\nhost" - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with ambiguous path" do - it "should raise an error" do - expect do - Addressable::URI.parse("::http") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with an invalid host" do - it "should raise an error" do - expect do - Addressable::URI.new(:host => "") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with a host consisting of " + - "sub-delims characters" do - it "should not raise an error" do - expect do - Addressable::URI.new( - :host => Addressable::URI::CharacterClasses::SUB_DELIMS.gsub(/\\/, '') - ) - end.not_to raise_error - end -end - -describe Addressable::URI, "when created with a host consisting of " + - "unreserved characters" do - it "should not raise an error" do - expect do - Addressable::URI.new( - :host => Addressable::URI::CharacterClasses::UNRESERVED.gsub(/\\/, '') - ) - end.not_to raise_error - end -end - -describe Addressable::URI, "when created from nil components" do - before do - @uri = Addressable::URI.new - end - - it "should have a nil site value" do - expect(@uri.site).to eq(nil) - end - - it "should have an empty path" do - expect(@uri.path).to eq("") - end - - it "should be an empty uri" do - expect(@uri.to_s).to eq("") - end - - it "should have a nil default port" do - expect(@uri.default_port).to eq(nil) - end - - it "should be empty" do - expect(@uri).to be_empty - end - - it "should raise an error if the scheme is set to whitespace" do - expect do - @uri.scheme = "\t \n" - end.to raise_error(Addressable::URI::InvalidURIError, /'\t \n'/) - end - - it "should raise an error if the scheme is set to all digits" do - expect do - @uri.scheme = "123" - end.to raise_error(Addressable::URI::InvalidURIError, /'123'/) - end - - it "should raise an error if the scheme begins with a digit" do - expect do - @uri.scheme = "1scheme" - end.to raise_error(Addressable::URI::InvalidURIError, /'1scheme'/) - end - - it "should raise an error if the scheme begins with a plus" do - expect do - @uri.scheme = "+scheme" - end.to raise_error(Addressable::URI::InvalidURIError, /'\+scheme'/) - end - - it "should raise an error if the scheme begins with a dot" do - expect do - @uri.scheme = ".scheme" - end.to raise_error(Addressable::URI::InvalidURIError, /'\.scheme'/) - end - - it "should raise an error if the scheme begins with a dash" do - expect do - @uri.scheme = "-scheme" - end.to raise_error(Addressable::URI::InvalidURIError, /'-scheme'/) - end - - it "should raise an error if the scheme contains an illegal character" do - expect do - @uri.scheme = "scheme!" - end.to raise_error(Addressable::URI::InvalidURIError, /'scheme!'/) - end - - it "should raise an error if the scheme contains whitespace" do - expect do - @uri.scheme = "sch eme" - end.to raise_error(Addressable::URI::InvalidURIError, /'sch eme'/) - end - - it "should raise an error if the scheme contains a newline" do - expect do - @uri.scheme = "sch\neme" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should raise an error if set into an invalid state" do - expect do - @uri.user = "user" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should raise an error if set into an invalid state" do - expect do - @uri.password = "pass" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should raise an error if set into an invalid state" do - expect do - @uri.scheme = "http" - @uri.fragment = "fragment" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should raise an error if set into an invalid state" do - expect do - @uri.fragment = "fragment" - @uri.scheme = "http" - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when initialized from individual components" do - before do - @uri = Addressable::URI.new( - :scheme => "http", - :user => "user", - :password => "password", - :host => "example.com", - :port => 8080, - :path => "/path", - :query => "query=value", - :fragment => "fragment" - ) - end - - it "returns 'http' for #scheme" do - expect(@uri.scheme).to eq("http") - end - - it "returns 'http' for #normalized_scheme" do - expect(@uri.normalized_scheme).to eq("http") - end - - it "returns 'user' for #user" do - expect(@uri.user).to eq("user") - end - - it "returns 'user' for #normalized_user" do - expect(@uri.normalized_user).to eq("user") - end - - it "returns 'password' for #password" do - expect(@uri.password).to eq("password") - end - - it "returns 'password' for #normalized_password" do - expect(@uri.normalized_password).to eq("password") - end - - it "returns 'user:password' for #userinfo" do - expect(@uri.userinfo).to eq("user:password") - end - - it "returns 'user:password' for #normalized_userinfo" do - expect(@uri.normalized_userinfo).to eq("user:password") - end - - it "returns 'example.com' for #host" do - expect(@uri.host).to eq("example.com") - end - - it "returns 'example.com' for #normalized_host" do - expect(@uri.normalized_host).to eq("example.com") - end - - it "returns 'com' for #tld" do - expect(@uri.tld).to eq("com") - end - - it "returns 'user:password@example.com:8080' for #authority" do - expect(@uri.authority).to eq("user:password@example.com:8080") - end - - it "returns 'user:password@example.com:8080' for #normalized_authority" do - expect(@uri.normalized_authority).to eq("user:password@example.com:8080") - end - - it "returns 8080 for #port" do - expect(@uri.port).to eq(8080) - end - - it "returns 8080 for #normalized_port" do - expect(@uri.normalized_port).to eq(8080) - end - - it "returns 80 for #default_port" do - expect(@uri.default_port).to eq(80) - end - - it "returns 'http://user:password@example.com:8080' for #site" do - expect(@uri.site).to eq("http://user:password@example.com:8080") - end - - it "returns 'http://user:password@example.com:8080' for #normalized_site" do - expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") - end - - it "returns '/path' for #path" do - expect(@uri.path).to eq("/path") - end - - it "returns '/path' for #normalized_path" do - expect(@uri.normalized_path).to eq("/path") - end - - it "returns 'query=value' for #query" do - expect(@uri.query).to eq("query=value") - end - - it "returns 'query=value' for #normalized_query" do - expect(@uri.normalized_query).to eq("query=value") - end - - it "returns 'fragment' for #fragment" do - expect(@uri.fragment).to eq("fragment") - end - - it "returns 'fragment' for #normalized_fragment" do - expect(@uri.normalized_fragment).to eq("fragment") - end - - it "returns #hash" do - expect(@uri.hash).not_to be nil - end - - it "returns #to_s" do - expect(@uri.to_s).to eq( - "http://user:password@example.com:8080/path?query=value#fragment" - ) - end - - it "should not be empty" do - expect(@uri).not_to be_empty - end - - it "should not be frozen" do - expect(@uri).not_to be_frozen - end - - it "should allow destructive operations" do - expect { @uri.normalize! }.not_to raise_error - end -end - -describe Addressable::URI, "when initialized from " + - "frozen individual components" do - before do - @uri = Addressable::URI.new( - :scheme => "http".freeze, - :user => "user".freeze, - :password => "password".freeze, - :host => "example.com".freeze, - :port => "8080".freeze, - :path => "/path".freeze, - :query => "query=value".freeze, - :fragment => "fragment".freeze - ) - end - - it "returns 'http' for #scheme" do - expect(@uri.scheme).to eq("http") - end - - it "returns 'http' for #normalized_scheme" do - expect(@uri.normalized_scheme).to eq("http") - end - - it "returns 'user' for #user" do - expect(@uri.user).to eq("user") - end - - it "returns 'user' for #normalized_user" do - expect(@uri.normalized_user).to eq("user") - end - - it "returns 'password' for #password" do - expect(@uri.password).to eq("password") - end - - it "returns 'password' for #normalized_password" do - expect(@uri.normalized_password).to eq("password") - end - - it "returns 'user:password' for #userinfo" do - expect(@uri.userinfo).to eq("user:password") - end - - it "returns 'user:password' for #normalized_userinfo" do - expect(@uri.normalized_userinfo).to eq("user:password") - end - - it "returns 'example.com' for #host" do - expect(@uri.host).to eq("example.com") - end - - it "returns 'example.com' for #normalized_host" do - expect(@uri.normalized_host).to eq("example.com") - end - - it "returns 'user:password@example.com:8080' for #authority" do - expect(@uri.authority).to eq("user:password@example.com:8080") - end - - it "returns 'user:password@example.com:8080' for #normalized_authority" do - expect(@uri.normalized_authority).to eq("user:password@example.com:8080") - end - - it "returns 8080 for #port" do - expect(@uri.port).to eq(8080) - end - - it "returns 8080 for #normalized_port" do - expect(@uri.normalized_port).to eq(8080) - end - - it "returns 80 for #default_port" do - expect(@uri.default_port).to eq(80) - end - - it "returns 'http://user:password@example.com:8080' for #site" do - expect(@uri.site).to eq("http://user:password@example.com:8080") - end - - it "returns 'http://user:password@example.com:8080' for #normalized_site" do - expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") - end - - it "returns '/path' for #path" do - expect(@uri.path).to eq("/path") - end - - it "returns '/path' for #normalized_path" do - expect(@uri.normalized_path).to eq("/path") - end - - it "returns 'query=value' for #query" do - expect(@uri.query).to eq("query=value") - end - - it "returns 'query=value' for #normalized_query" do - expect(@uri.normalized_query).to eq("query=value") - end - - it "returns 'fragment' for #fragment" do - expect(@uri.fragment).to eq("fragment") - end - - it "returns 'fragment' for #normalized_fragment" do - expect(@uri.normalized_fragment).to eq("fragment") - end - - it "returns #hash" do - expect(@uri.hash).not_to be nil - end - - it "returns #to_s" do - expect(@uri.to_s).to eq( - "http://user:password@example.com:8080/path?query=value#fragment" - ) - end - - it "should not be empty" do - expect(@uri).not_to be_empty - end - - it "should not be frozen" do - expect(@uri).not_to be_frozen - end - - it "should allow destructive operations" do - expect { @uri.normalize! }.not_to raise_error - end -end - -describe Addressable::URI, "when parsed from a frozen string" do - before do - @uri = Addressable::URI.parse( - "http://user:password@example.com:8080/path?query=value#fragment".freeze - ) - end - - it "returns 'http' for #scheme" do - expect(@uri.scheme).to eq("http") - end - - it "returns 'http' for #normalized_scheme" do - expect(@uri.normalized_scheme).to eq("http") - end - - it "returns 'user' for #user" do - expect(@uri.user).to eq("user") - end - - it "returns 'user' for #normalized_user" do - expect(@uri.normalized_user).to eq("user") - end - - it "returns 'password' for #password" do - expect(@uri.password).to eq("password") - end - - it "returns 'password' for #normalized_password" do - expect(@uri.normalized_password).to eq("password") - end - - it "returns 'user:password' for #userinfo" do - expect(@uri.userinfo).to eq("user:password") - end - - it "returns 'user:password' for #normalized_userinfo" do - expect(@uri.normalized_userinfo).to eq("user:password") - end - - it "returns 'example.com' for #host" do - expect(@uri.host).to eq("example.com") - end - - it "returns 'example.com' for #normalized_host" do - expect(@uri.normalized_host).to eq("example.com") - end - - it "returns 'user:password@example.com:8080' for #authority" do - expect(@uri.authority).to eq("user:password@example.com:8080") - end - - it "returns 'user:password@example.com:8080' for #normalized_authority" do - expect(@uri.normalized_authority).to eq("user:password@example.com:8080") - end - - it "returns 8080 for #port" do - expect(@uri.port).to eq(8080) - end - - it "returns 8080 for #normalized_port" do - expect(@uri.normalized_port).to eq(8080) - end - - it "returns 80 for #default_port" do - expect(@uri.default_port).to eq(80) - end - - it "returns 'http://user:password@example.com:8080' for #site" do - expect(@uri.site).to eq("http://user:password@example.com:8080") - end - - it "returns 'http://user:password@example.com:8080' for #normalized_site" do - expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") - end - - it "returns '/path' for #path" do - expect(@uri.path).to eq("/path") - end - - it "returns '/path' for #normalized_path" do - expect(@uri.normalized_path).to eq("/path") - end - - it "returns 'query=value' for #query" do - expect(@uri.query).to eq("query=value") - end - - it "returns 'query=value' for #normalized_query" do - expect(@uri.normalized_query).to eq("query=value") - end - - it "returns 'fragment' for #fragment" do - expect(@uri.fragment).to eq("fragment") - end - - it "returns 'fragment' for #normalized_fragment" do - expect(@uri.normalized_fragment).to eq("fragment") - end - - it "returns #hash" do - expect(@uri.hash).not_to be nil - end - - it "returns #to_s" do - expect(@uri.to_s).to eq( - "http://user:password@example.com:8080/path?query=value#fragment" - ) - end - - it "should not be empty" do - expect(@uri).not_to be_empty - end - - it "should not be frozen" do - expect(@uri).not_to be_frozen - end - - it "should allow destructive operations" do - expect { @uri.normalize! }.not_to raise_error - end -end - -describe Addressable::URI, "when frozen" do - before do - @uri = Addressable::URI.new.freeze - end - - it "returns nil for #scheme" do - expect(@uri.scheme).to eq(nil) - end - - it "returns nil for #normalized_scheme" do - expect(@uri.normalized_scheme).to eq(nil) - end - - it "returns nil for #user" do - expect(@uri.user).to eq(nil) - end - - it "returns nil for #normalized_user" do - expect(@uri.normalized_user).to eq(nil) - end - - it "returns nil for #password" do - expect(@uri.password).to eq(nil) - end - - it "returns nil for #normalized_password" do - expect(@uri.normalized_password).to eq(nil) - end - - it "returns nil for #userinfo" do - expect(@uri.userinfo).to eq(nil) - end - - it "returns nil for #normalized_userinfo" do - expect(@uri.normalized_userinfo).to eq(nil) - end - - it "returns nil for #host" do - expect(@uri.host).to eq(nil) - end - - it "returns nil for #normalized_host" do - expect(@uri.normalized_host).to eq(nil) - end - - it "returns nil for #authority" do - expect(@uri.authority).to eq(nil) - end - - it "returns nil for #normalized_authority" do - expect(@uri.normalized_authority).to eq(nil) - end - - it "returns nil for #port" do - expect(@uri.port).to eq(nil) - end - - it "returns nil for #normalized_port" do - expect(@uri.normalized_port).to eq(nil) - end - - it "returns nil for #default_port" do - expect(@uri.default_port).to eq(nil) - end - - it "returns nil for #site" do - expect(@uri.site).to eq(nil) - end - - it "returns nil for #normalized_site" do - expect(@uri.normalized_site).to eq(nil) - end - - it "returns '' for #path" do - expect(@uri.path).to eq('') - end - - it "returns '' for #normalized_path" do - expect(@uri.normalized_path).to eq('') - end - - it "returns nil for #query" do - expect(@uri.query).to eq(nil) - end - - it "returns nil for #normalized_query" do - expect(@uri.normalized_query).to eq(nil) - end - - it "returns nil for #fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "returns nil for #normalized_fragment" do - expect(@uri.normalized_fragment).to eq(nil) - end - - it "returns #hash" do - expect(@uri.hash).not_to be nil - end - - it "returns #to_s" do - expect(@uri.to_s).to eq('') - end - - it "should be empty" do - expect(@uri).to be_empty - end - - it "should be frozen" do - expect(@uri).to be_frozen - end - - it "should not be frozen after duping" do - expect(@uri.dup).not_to be_frozen - end - - it "should not allow destructive operations" do - expect { @uri.normalize! }.to raise_error { |error| - expect(error.message).to match(/can't modify frozen/) - expect(error).to satisfy { |e| RuntimeError === e || TypeError === e } - } - end -end - -describe Addressable::URI, "when frozen" do - before do - @uri = Addressable::URI.parse( - "HTTP://example.com.:%38%30/%70a%74%68?a=%31#1%323" - ).freeze - end - - it "returns 'HTTP' for #scheme" do - expect(@uri.scheme).to eq("HTTP") - end - - it "returns 'http' for #normalized_scheme" do - expect(@uri.normalized_scheme).to eq("http") - expect(@uri.normalize.scheme).to eq("http") - end - - it "returns nil for #user" do - expect(@uri.user).to eq(nil) - end - - it "returns nil for #normalized_user" do - expect(@uri.normalized_user).to eq(nil) - end - - it "returns nil for #password" do - expect(@uri.password).to eq(nil) - end - - it "returns nil for #normalized_password" do - expect(@uri.normalized_password).to eq(nil) - end - - it "returns nil for #userinfo" do - expect(@uri.userinfo).to eq(nil) - end - - it "returns nil for #normalized_userinfo" do - expect(@uri.normalized_userinfo).to eq(nil) - end - - it "returns 'example.com.' for #host" do - expect(@uri.host).to eq("example.com.") - end - - it "returns nil for #normalized_host" do - expect(@uri.normalized_host).to eq("example.com") - expect(@uri.normalize.host).to eq("example.com") - end - - it "returns 'example.com.:80' for #authority" do - expect(@uri.authority).to eq("example.com.:80") - end - - it "returns 'example.com:80' for #normalized_authority" do - expect(@uri.normalized_authority).to eq("example.com") - expect(@uri.normalize.authority).to eq("example.com") - end - - it "returns 80 for #port" do - expect(@uri.port).to eq(80) - end - - it "returns nil for #normalized_port" do - expect(@uri.normalized_port).to eq(nil) - expect(@uri.normalize.port).to eq(nil) - end - - it "returns 80 for #default_port" do - expect(@uri.default_port).to eq(80) - end - - it "returns 'HTTP://example.com.:80' for #site" do - expect(@uri.site).to eq("HTTP://example.com.:80") - end - - it "returns 'http://example.com' for #normalized_site" do - expect(@uri.normalized_site).to eq("http://example.com") - expect(@uri.normalize.site).to eq("http://example.com") - end - - it "returns '/%70a%74%68' for #path" do - expect(@uri.path).to eq("/%70a%74%68") - end - - it "returns '/path' for #normalized_path" do - expect(@uri.normalized_path).to eq("/path") - expect(@uri.normalize.path).to eq("/path") - end - - it "returns 'a=%31' for #query" do - expect(@uri.query).to eq("a=%31") - end - - it "returns 'a=1' for #normalized_query" do - expect(@uri.normalized_query).to eq("a=1") - expect(@uri.normalize.query).to eq("a=1") - end - - it "returns '/%70a%74%68?a=%31' for #request_uri" do - expect(@uri.request_uri).to eq("/%70a%74%68?a=%31") - end - - it "returns '1%323' for #fragment" do - expect(@uri.fragment).to eq("1%323") - end - - it "returns '123' for #normalized_fragment" do - expect(@uri.normalized_fragment).to eq("123") - expect(@uri.normalize.fragment).to eq("123") - end - - it "returns #hash" do - expect(@uri.hash).not_to be nil - end - - it "returns #to_s" do - expect(@uri.to_s).to eq('HTTP://example.com.:80/%70a%74%68?a=%31#1%323') - expect(@uri.normalize.to_s).to eq('http://example.com/path?a=1#123') - end - - it "should not be empty" do - expect(@uri).not_to be_empty - end - - it "should be frozen" do - expect(@uri).to be_frozen - end - - it "should not be frozen after duping" do - expect(@uri.dup).not_to be_frozen - end - - it "should not allow destructive operations" do - expect { @uri.normalize! }.to raise_error { |error| - expect(error.message).to match(/can't modify frozen/) - expect(error).to satisfy { |e| RuntimeError === e || TypeError === e } - } - end -end - -describe Addressable::URI, "when normalized and then deeply frozen" do - before do - @uri = Addressable::URI.parse( - "http://user:password@example.com:8080/path?query=value#fragment" - ).normalize! - - @uri.instance_variables.each do |var| - @uri.instance_variable_set(var, @uri.instance_variable_get(var).freeze) - end - - @uri.freeze - end - - it "#normalized_scheme should not error" do - expect { @uri.normalized_scheme }.not_to raise_error - end - - it "#normalized_user should not error" do - expect { @uri.normalized_user }.not_to raise_error - end - - it "#normalized_password should not error" do - expect { @uri.normalized_password }.not_to raise_error - end - - it "#normalized_userinfo should not error" do - expect { @uri.normalized_userinfo }.not_to raise_error - end - - it "#normalized_host should not error" do - expect { @uri.normalized_host }.not_to raise_error - end - - it "#normalized_authority should not error" do - expect { @uri.normalized_authority }.not_to raise_error - end - - it "#normalized_port should not error" do - expect { @uri.normalized_port }.not_to raise_error - end - - it "#normalized_site should not error" do - expect { @uri.normalized_site }.not_to raise_error - end - - it "#normalized_path should not error" do - expect { @uri.normalized_path }.not_to raise_error - end - - it "#normalized_query should not error" do - expect { @uri.normalized_query }.not_to raise_error - end - - it "#normalized_fragment should not error" do - expect { @uri.normalized_fragment }.not_to raise_error - end - - it "should be frozen" do - expect(@uri).to be_frozen - end - - it "should not allow destructive operations" do - expect { @uri.normalize! }.to raise_error(RuntimeError) - end -end - -describe Addressable::URI, "when created from string components" do - before do - @uri = Addressable::URI.new( - :scheme => "http", :host => "example.com" - ) - end - - it "should have a site value of 'http://example.com'" do - expect(@uri.site).to eq("http://example.com") - end - - it "should be equal to the equivalent parsed URI" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - it "should raise an error if invalid components omitted" do - expect do - @uri.omit(:bogus) - end.to raise_error(ArgumentError) - expect do - @uri.omit(:scheme, :bogus, :path) - end.to raise_error(ArgumentError) - end -end - -describe Addressable::URI, "when created with a nil host but " + - "non-nil authority components" do - it "should raise an error" do - expect do - Addressable::URI.new(:user => "user", :password => "pass", :port => 80) - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with both an authority and a user" do - it "should raise an error" do - expect do - Addressable::URI.new( - :user => "user", :authority => "user@example.com:80" - ) - end.to raise_error(ArgumentError) - end -end - -describe Addressable::URI, "when created with an authority and no port" do - before do - @uri = Addressable::URI.new(:authority => "user@example.com") - end - - it "should not infer a port" do - expect(@uri.port).to eq(nil) - expect(@uri.default_port).to eq(nil) - expect(@uri.inferred_port).to eq(nil) - end - - it "should have a site value of '//user@example.com'" do - expect(@uri.site).to eq("//user@example.com") - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when created with a host with trailing dots" do - before do - @uri = Addressable::URI.new(:authority => "example...") - end - - it "should have a stable normalized form" do - expect(@uri.normalize.normalize.normalize.host).to eq( - @uri.normalize.host - ) - end -end - -describe Addressable::URI, "when created with a host with a backslash" do - it "should raise an error" do - expect do - Addressable::URI.new(:authority => "example\\example") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with a host with a slash" do - it "should raise an error" do - expect do - Addressable::URI.new(:authority => "example/example") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with a host with a space" do - it "should raise an error" do - expect do - Addressable::URI.new(:authority => "example example") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when created with both a userinfo and a user" do - it "should raise an error" do - expect do - Addressable::URI.new(:user => "user", :userinfo => "user:pass") - end.to raise_error(ArgumentError) - end -end - -describe Addressable::URI, "when created with a path that hasn't been " + - "prefixed with a '/' but a host specified" do - before do - @uri = Addressable::URI.new( - :scheme => "http", :host => "example.com", :path => "path" - ) - end - - it "should prefix a '/' to the path" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/path")) - end - - it "should have a site value of 'http://example.com'" do - expect(@uri.site).to eq("http://example.com") - end - - it "should have an origin of 'http://example.com" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when created with a path that hasn't been " + - "prefixed with a '/' but no host specified" do - before do - @uri = Addressable::URI.new( - :scheme => "http", :path => "path" - ) - end - - it "should not prefix a '/' to the path" do - expect(@uri).to eq(Addressable::URI.parse("http:path")) - end - - it "should have a site value of 'http:'" do - expect(@uri.site).to eq("http:") - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from an Addressable::URI object" do - it "should not have unexpected side-effects" do - original_uri = Addressable::URI.parse("http://example.com/") - new_uri = Addressable::URI.parse(original_uri) - new_uri.host = 'www.example.com' - expect(new_uri.host).to eq('www.example.com') - expect(new_uri.to_s).to eq('http://www.example.com/') - expect(original_uri.host).to eq('example.com') - expect(original_uri.to_s).to eq('http://example.com/') - end - - it "should not have unexpected side-effects" do - original_uri = Addressable::URI.parse("http://example.com/") - new_uri = Addressable::URI.heuristic_parse(original_uri) - new_uri.host = 'www.example.com' - expect(new_uri.host).to eq('www.example.com') - expect(new_uri.to_s).to eq('http://www.example.com/') - expect(original_uri.host).to eq('example.com') - expect(original_uri.to_s).to eq('http://example.com/') - end - - it "should not have unexpected side-effects" do - original_uri = Addressable::URI.parse("http://example.com/") - new_uri = Addressable::URI.parse(original_uri) - new_uri.origin = 'https://www.example.com:8080' - expect(new_uri.host).to eq('www.example.com') - expect(new_uri.to_s).to eq('https://www.example.com:8080/') - expect(original_uri.host).to eq('example.com') - expect(original_uri.to_s).to eq('http://example.com/') - end - - it "should not have unexpected side-effects" do - original_uri = Addressable::URI.parse("http://example.com/") - new_uri = Addressable::URI.heuristic_parse(original_uri) - new_uri.origin = 'https://www.example.com:8080' - expect(new_uri.host).to eq('www.example.com') - expect(new_uri.to_s).to eq('https://www.example.com:8080/') - expect(original_uri.host).to eq('example.com') - expect(original_uri.to_s).to eq('http://example.com/') - end -end - -describe Addressable::URI, "when parsed from something that looks " + - "like a URI object" do - it "should parse without error" do - uri = Addressable::URI.parse(Fake::URI::HTTP.new("http://example.com/")) - expect do - Addressable::URI.parse(uri) - end.not_to raise_error - end -end - -describe Addressable::URI, "when parsed from a standard library URI object" do - it "should parse without error" do - uri = Addressable::URI.parse(URI.parse("http://example.com/")) - expect do - Addressable::URI.parse(uri) - end.not_to raise_error - end -end - -describe Addressable::URI, "when parsed from ''" do - before do - @uri = Addressable::URI.parse("") - end - - it "should have no scheme" do - expect(@uri.scheme).to eq(nil) - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of ''" do - expect(@uri.path).to eq("") - end - - it "should have a request URI of '/'" do - expect(@uri.request_uri).to eq("/") - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'ftp://ftp.is.co.za/rfc/rfc1808.txt'" do - before do - @uri = Addressable::URI.parse("ftp://ftp.is.co.za/rfc/rfc1808.txt") - end - - it "should use the 'ftp' scheme" do - expect(@uri.scheme).to eq("ftp") - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a host of 'ftp.is.co.za'" do - expect(@uri.host).to eq("ftp.is.co.za") - end - - it "should have inferred_port of 21" do - expect(@uri.inferred_port).to eq(21) - end - - it "should have a path of '/rfc/rfc1808.txt'" do - expect(@uri.path).to eq("/rfc/rfc1808.txt") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have an origin of 'ftp://ftp.is.co.za'" do - expect(@uri.origin).to eq('ftp://ftp.is.co.za') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'http://www.ietf.org/rfc/rfc2396.txt'" do - before do - @uri = Addressable::URI.parse("http://www.ietf.org/rfc/rfc2396.txt") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a host of 'www.ietf.org'" do - expect(@uri.host).to eq("www.ietf.org") - end - - it "should have inferred_port of 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/rfc/rfc2396.txt'" do - expect(@uri.path).to eq("/rfc/rfc2396.txt") - end - - it "should have a request URI of '/rfc/rfc2396.txt'" do - expect(@uri.request_uri).to eq("/rfc/rfc2396.txt") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should correctly omit components" do - expect(@uri.omit(:scheme).to_s).to eq("//www.ietf.org/rfc/rfc2396.txt") - expect(@uri.omit(:path).to_s).to eq("http://www.ietf.org") - end - - it "should correctly omit components destructively" do - @uri.omit!(:scheme) - expect(@uri.to_s).to eq("//www.ietf.org/rfc/rfc2396.txt") - end - - it "should have an origin of 'http://www.ietf.org'" do - expect(@uri.origin).to eq('http://www.ietf.org') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'ldap://[2001:db8::7]/c=GB?objectClass?one'" do - before do - @uri = Addressable::URI.parse("ldap://[2001:db8::7]/c=GB?objectClass?one") - end - - it "should use the 'ldap' scheme" do - expect(@uri.scheme).to eq("ldap") - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a host of '[2001:db8::7]'" do - expect(@uri.host).to eq("[2001:db8::7]") - end - - it "should have inferred_port of 389" do - expect(@uri.inferred_port).to eq(389) - end - - it "should have a path of '/c=GB'" do - expect(@uri.path).to eq("/c=GB") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should not allow request URI assignment" do - expect do - @uri.request_uri = "/" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should have a query of 'objectClass?one'" do - expect(@uri.query).to eq("objectClass?one") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should correctly omit components" do - expect(@uri.omit(:scheme, :authority).to_s).to eq("/c=GB?objectClass?one") - expect(@uri.omit(:path).to_s).to eq("ldap://[2001:db8::7]?objectClass?one") - end - - it "should correctly omit components destructively" do - @uri.omit!(:scheme, :authority) - expect(@uri.to_s).to eq("/c=GB?objectClass?one") - end - - it "should raise an error if omission would create an invalid URI" do - expect do - @uri.omit(:authority, :path) - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should have an origin of 'ldap://[2001:db8::7]'" do - expect(@uri.origin).to eq('ldap://[2001:db8::7]') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'mailto:John.Doe@example.com'" do - before do - @uri = Addressable::URI.parse("mailto:John.Doe@example.com") - end - - it "should use the 'mailto' scheme" do - expect(@uri.scheme).to eq("mailto") - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should not have an inferred_port" do - expect(@uri.inferred_port).to eq(nil) - end - - it "should have a path of 'John.Doe@example.com'" do - expect(@uri.path).to eq("John.Doe@example.com") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -# Section 2 of RFC 6068 -describe Addressable::URI, "when parsed from " + - "'mailto:?to=addr1@an.example,addr2@an.example'" do - before do - @uri = Addressable::URI.parse( - "mailto:?to=addr1@an.example,addr2@an.example" - ) - end - - it "should use the 'mailto' scheme" do - expect(@uri.scheme).to eq("mailto") - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should not have an inferred_port" do - expect(@uri.inferred_port).to eq(nil) - end - - it "should have a path of ''" do - expect(@uri.path).to eq("") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should have the To: field value parameterized" do - expect(@uri.query_values(Hash)["to"]).to eq( - "addr1@an.example,addr2@an.example" - ) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'news:comp.infosystems.www.servers.unix'" do - before do - @uri = Addressable::URI.parse("news:comp.infosystems.www.servers.unix") - end - - it "should use the 'news' scheme" do - expect(@uri.scheme).to eq("news") - end - - it "should not have an inferred_port" do - expect(@uri.inferred_port).to eq(nil) - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of 'comp.infosystems.www.servers.unix'" do - expect(@uri.path).to eq("comp.infosystems.www.servers.unix") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'tel:+1-816-555-1212'" do - before do - @uri = Addressable::URI.parse("tel:+1-816-555-1212") - end - - it "should use the 'tel' scheme" do - expect(@uri.scheme).to eq("tel") - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should not have an inferred_port" do - expect(@uri.inferred_port).to eq(nil) - end - - it "should have a path of '+1-816-555-1212'" do - expect(@uri.path).to eq("+1-816-555-1212") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'telnet://192.0.2.16:80/'" do - before do - @uri = Addressable::URI.parse("telnet://192.0.2.16:80/") - end - - it "should use the 'telnet' scheme" do - expect(@uri.scheme).to eq("telnet") - end - - it "should have a host of '192.0.2.16'" do - expect(@uri.host).to eq("192.0.2.16") - end - - it "should have a port of 80" do - expect(@uri.port).to eq(80) - end - - it "should have a inferred_port of 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a default_port of 23" do - expect(@uri.default_port).to eq(23) - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a path of '/'" do - expect(@uri.path).to eq("/") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have an origin of 'telnet://192.0.2.16:80'" do - expect(@uri.origin).to eq('telnet://192.0.2.16:80') - end -end - -# Section 1.1.2 of RFC 3986 -describe Addressable::URI, "when parsed from " + - "'urn:oasis:names:specification:docbook:dtd:xml:4.1.2'" do - before do - @uri = Addressable::URI.parse( - "urn:oasis:names:specification:docbook:dtd:xml:4.1.2") - end - - it "should use the 'urn' scheme" do - expect(@uri.scheme).to eq("urn") - end - - it "should not have an inferred_port" do - expect(@uri.inferred_port).to eq(nil) - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of " + - "'oasis:names:specification:docbook:dtd:xml:4.1.2'" do - expect(@uri.path).to eq("oasis:names:specification:docbook:dtd:xml:4.1.2") - end - - it "should not have a request URI" do - expect(@uri.request_uri).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when heuristically parsed from " + - "'192.0.2.16:8000/path'" do - before do - @uri = Addressable::URI.heuristic_parse("192.0.2.16:8000/path") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a host of '192.0.2.16'" do - expect(@uri.host).to eq("192.0.2.16") - end - - it "should have a port of '8000'" do - expect(@uri.port).to eq(8000) - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a path of '/path'" do - expect(@uri.path).to eq("/path") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have an origin of 'http://192.0.2.16:8000'" do - expect(@uri.origin).to eq('http://192.0.2.16:8000') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com'" do - before do - @uri = Addressable::URI.parse("http://example.com") - end - - it "when inspected, should have the correct URI" do - expect(@uri.inspect).to include("http://example.com") - end - - it "when inspected, should have the correct class name" do - expect(@uri.inspect).to include("Addressable::URI") - end - - it "when inspected, should have the correct object id" do - expect(@uri.inspect).to include("%#0x" % @uri.object_id) - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should be considered ip-based" do - expect(@uri).to be_ip_based - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not have a specified port" do - expect(@uri.port).to eq(nil) - end - - it "should have an empty path" do - expect(@uri.path).to eq("") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - expect(@uri.query_values).to eq(nil) - end - - it "should have a request URI of '/'" do - expect(@uri.request_uri).to eq("/") - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should not be considered relative" do - expect(@uri).not_to be_relative - end - - it "should not be exactly equal to 42" do - expect(@uri.eql?(42)).to eq(false) - end - - it "should not be equal to 42" do - expect(@uri == 42).to eq(false) - end - - it "should not be roughly equal to 42" do - expect(@uri === 42).to eq(false) - end - - it "should be exactly equal to http://example.com" do - expect(@uri.eql?(Addressable::URI.parse("http://example.com"))).to eq(true) - end - - it "should be roughly equal to http://example.com/" do - expect(@uri === Addressable::URI.parse("http://example.com/")).to eq(true) - end - - it "should be roughly equal to the string 'http://example.com/'" do - expect(@uri === "http://example.com/").to eq(true) - end - - it "should not be roughly equal to the string " + - "'http://example.com:bogus/'" do - expect do - expect(@uri === "http://example.com:bogus/").to eq(false) - end.not_to raise_error - end - - it "should result in itself when joined with itself" do - expect(@uri.join(@uri).to_s).to eq("http://example.com") - expect(@uri.join!(@uri).to_s).to eq("http://example.com") - end - - it "should be equivalent to http://EXAMPLE.com" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com")) - end - - it "should be equivalent to http://EXAMPLE.com:80/" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com:80/")) - end - - it "should have the same hash as http://example.com" do - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com").hash) - end - - it "should have the same hash as http://EXAMPLE.com after assignment" do - @uri.origin = "http://EXAMPLE.com" - expect(@uri.hash).to eq(Addressable::URI.parse("http://EXAMPLE.com").hash) - end - - it "should have a different hash from http://EXAMPLE.com" do - expect(@uri.hash).not_to eq(Addressable::URI.parse("http://EXAMPLE.com").hash) - end - - it "should not allow origin assignment without scheme" do - expect do - @uri.origin = "example.com" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should not allow origin assignment without host" do - expect do - @uri.origin = "http://" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should not allow origin assignment with bogus type" do - expect do - @uri.origin = :bogus - end.to raise_error(TypeError) - end - - # Section 6.2.3 of RFC 3986 - it "should be equivalent to http://example.com/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/")) - end - - # Section 6.2.3 of RFC 3986 - it "should be equivalent to http://example.com:/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) - end - - # Section 6.2.3 of RFC 3986 - it "should be equivalent to http://example.com:80/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) - end - - # Section 6.2.2.1 of RFC 3986 - it "should be equivalent to http://EXAMPLE.COM/" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.COM/")) - end - - it "should have a route of '/path/' to 'http://example.com/path/'" do - expect(@uri.route_to("http://example.com/path/")).to eq( - Addressable::URI.parse("/path/") - ) - end - - it "should have a route of '..' from 'http://example.com/path/'" do - expect(@uri.route_from("http://example.com/path/")).to eq( - Addressable::URI.parse("..") - ) - end - - it "should have a route of '#' to 'http://example.com/'" do - expect(@uri.route_to("http://example.com/")).to eq( - Addressable::URI.parse("#") - ) - end - - it "should have a route of 'http://elsewhere.com/' to " + - "'http://elsewhere.com/'" do - expect(@uri.route_to("http://elsewhere.com/")).to eq( - Addressable::URI.parse("http://elsewhere.com/") - ) - end - - it "when joined with 'relative/path' should be " + - "'http://example.com/relative/path'" do - expect(@uri.join('relative/path')).to eq( - Addressable::URI.parse("http://example.com/relative/path") - ) - end - - it "when joined with a bogus object a TypeError should be raised" do - expect do - @uri.join(42) - end.to raise_error(TypeError) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq(nil) - expect(@uri.to_s).to eq("http://newuser@example.com") - end - - it "should have the correct username after assignment" do - @uri.user = "user@123!" - expect(@uri.user).to eq("user@123!") - expect(@uri.normalized_user).to eq("user%40123%21") - expect(@uri.password).to eq(nil) - expect(@uri.normalize.to_s).to eq("http://user%40123%21@example.com/") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.user).to eq("") - expect(@uri.to_s).to eq("http://:newpass@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "#secret@123!" - expect(@uri.password).to eq("#secret@123!") - expect(@uri.normalized_password).to eq("%23secret%40123%21") - expect(@uri.user).to eq("") - expect(@uri.normalize.to_s).to eq("http://:%23secret%40123%21@example.com/") - expect(@uri.omit(:password).to_s).to eq("http://example.com") - end - - it "should have the correct user/pass after repeated assignment" do - @uri.user = nil - expect(@uri.user).to eq(nil) - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - # Username cannot be nil if the password is set - expect(@uri.user).to eq("") - expect(@uri.to_s).to eq("http://:newpass@example.com") - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - @uri.password = nil - expect(@uri.password).to eq(nil) - expect(@uri.to_s).to eq("http://newuser@example.com") - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - @uri.password = "" - expect(@uri.password).to eq("") - expect(@uri.to_s).to eq("http://newuser:@example.com") - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - @uri.user = nil - # Username cannot be nil if the password is set - expect(@uri.user).to eq("") - expect(@uri.to_s).to eq("http://:newpass@example.com") - end - - it "should have the correct user/pass after userinfo assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - @uri.userinfo = nil - expect(@uri.userinfo).to eq(nil) - expect(@uri.user).to eq(nil) - expect(@uri.password).to eq(nil) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => nil, - :path => "", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -# Section 5.1.2 of RFC 2616 -describe Addressable::URI, "when parsed from " + - "'HTTP://www.w3.org/pub/WWW/TheProject.html'" do - before do - @uri = Addressable::URI.parse("HTTP://www.w3.org/pub/WWW/TheProject.html") - end - - it "should have the correct request URI" do - expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html") - end - - it "should have the correct request URI after assignment" do - @uri.request_uri = "/pub/WWW/TheProject.html?" - expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html?") - expect(@uri.path).to eq("/pub/WWW/TheProject.html") - expect(@uri.query).to eq("") - end - - it "should have the correct request URI after assignment" do - @uri.request_uri = "/some/where/else.html" - expect(@uri.request_uri).to eq("/some/where/else.html") - expect(@uri.path).to eq("/some/where/else.html") - expect(@uri.query).to eq(nil) - end - - it "should have the correct request URI after assignment" do - @uri.request_uri = "/some/where/else.html?query?string" - expect(@uri.request_uri).to eq("/some/where/else.html?query?string") - expect(@uri.path).to eq("/some/where/else.html") - expect(@uri.query).to eq("query?string") - end - - it "should have the correct request URI after assignment" do - @uri.request_uri = "?x=y" - expect(@uri.request_uri).to eq("/?x=y") - expect(@uri.path).to eq("/") - expect(@uri.query).to eq("x=y") - end - - it "should raise an error if the site value is set to something bogus" do - expect do - @uri.site = 42 - end.to raise_error(TypeError) - end - - it "should raise an error if the request URI is set to something bogus" do - expect do - @uri.request_uri = 42 - end.to raise_error(TypeError) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "HTTP", - :user => nil, - :password => nil, - :host => "www.w3.org", - :port => nil, - :path => "/pub/WWW/TheProject.html", - :query => nil, - :fragment => nil - }) - end - - it "should have an origin of 'http://www.w3.org'" do - expect(@uri.origin).to eq('http://www.w3.org') - end -end - -describe Addressable::URI, "when parsing IPv6 addresses" do - it "should not raise an error for " + - "'http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[fe80:0:0:0:200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[fe80:0:0:0:200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[fe80::200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[fe80::200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[::1]/'" do - Addressable::URI.parse("http://[::1]/") - end - - it "should not raise an error for " + - "'http://[fe80::1]/'" do - Addressable::URI.parse("http://[fe80::1]/") - end - - it "should raise an error for " + - "'http://[]/'" do - expect do - Addressable::URI.parse("http://[]/") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when parsing IPv6 address" do - subject { Addressable::URI.parse("http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") } - its(:host) { should == '[3ffe:1900:4545:3:200:f8ff:fe21:67cf]' } - its(:hostname) { should == '3ffe:1900:4545:3:200:f8ff:fe21:67cf' } -end - -describe Addressable::URI, "when assigning IPv6 address" do - it "should allow to set bare IPv6 address as hostname" do - uri = Addressable::URI.parse("http://[::1]/") - uri.hostname = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' - expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/') - end - - it "should allow to set bare IPv6 address as hostname with IPAddr object" do - uri = Addressable::URI.parse("http://[::1]/") - uri.hostname = IPAddr.new('3ffe:1900:4545:3:200:f8ff:fe21:67cf') - expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/') - end - - it "should not allow to set bare IPv6 address as host" do - uri = Addressable::URI.parse("http://[::1]/") - skip "not checked" - expect do - uri.host = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when parsing IPvFuture addresses" do - it "should not raise an error for " + - "'http://[v9.3ffe:1900:4545:3:200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[v9.3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[vff.fe80:0:0:0:200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[vff.fe80:0:0:0:200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[v12.fe80::200:f8ff:fe21:67cf]/'" do - Addressable::URI.parse("http://[v12.fe80::200:f8ff:fe21:67cf]/") - end - - it "should not raise an error for " + - "'http://[va0.::1]/'" do - Addressable::URI.parse("http://[va0.::1]/") - end - - it "should not raise an error for " + - "'http://[v255.fe80::1]/'" do - Addressable::URI.parse("http://[v255.fe80::1]/") - end - - it "should raise an error for " + - "'http://[v0.]/'" do - expect do - Addressable::URI.parse("http://[v0.]/") - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/'" do - before do - @uri = Addressable::URI.parse("http://example.com/") - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://example.com" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to HTTP://example.com/" do - expect(@uri).to eq(Addressable::URI.parse("HTTP://example.com/")) - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://example.com:/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://example.com:80/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://Example.com/" do - expect(@uri).to eq(Addressable::URI.parse("http://Example.com/")) - end - - it "should have the correct username after assignment" do - @uri.user = nil - expect(@uri.user).to eq(nil) - expect(@uri.password).to eq(nil) - expect(@uri.to_s).to eq("http://example.com/") - end - - it "should have the correct password after assignment" do - @uri.password = nil - expect(@uri.password).to eq(nil) - expect(@uri.user).to eq(nil) - expect(@uri.to_s).to eq("http://example.com/") - end - - it "should have a request URI of '/'" do - expect(@uri.request_uri).to eq("/") - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => nil, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have the same hash as its duplicate" do - expect(@uri.hash).to eq(@uri.dup.hash) - end - - it "should have a different hash from its equivalent String value" do - expect(@uri.hash).not_to eq(@uri.to_s.hash) - end - - it "should have the same hash as an equal URI" do - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/").hash) - end - - it "should be equivalent to http://EXAMPLE.com" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com")) - end - - it "should be equivalent to http://EXAMPLE.com:80/" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com:80/")) - end - - it "should have the same hash as http://example.com/" do - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/").hash) - end - - it "should have the same hash as http://example.com after assignment" do - @uri.path = "" - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com").hash) - end - - it "should have the same hash as http://example.com/? after assignment" do - @uri.query = "" - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/?").hash) - end - - it "should have the same hash as http://example.com/? after assignment" do - @uri.query_values = {} - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/?").hash) - end - - it "should have the same hash as http://example.com/# after assignment" do - @uri.fragment = "" - expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/#").hash) - end - - it "should have a different hash from http://example.com" do - expect(@uri.hash).not_to eq(Addressable::URI.parse("http://example.com").hash) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com?#'" do - before do - @uri = Addressable::URI.parse("http://example.com?#") - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => nil, - :path => "", - :query => "", - :fragment => "" - }) - end - - it "should have a request URI of '/?'" do - expect(@uri.request_uri).to eq("/?") - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq("http://example.com") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://@example.com/'" do - before do - @uri = Addressable::URI.parse("http://@example.com/") - end - - it "should be equivalent to http://example.com" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => "", - :password => nil, - :host => "example.com", - :port => nil, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com./'" do - before do - @uri = Addressable::URI.parse("http://example.com./") - end - - it "should be equivalent to http://example.com" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://:@example.com/'" do - before do - @uri = Addressable::URI.parse("http://:@example.com/") - end - - it "should be equivalent to http://example.com" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => "", - :password => "", - :host => "example.com", - :port => nil, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'HTTP://EXAMPLE.COM/'" do - before do - @uri = Addressable::URI.parse("HTTP://EXAMPLE.COM/") - end - - it "should be equivalent to http://example.com" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com")) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "HTTP", - :user => nil, - :password => nil, - :host => "EXAMPLE.COM", - :port => nil, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end - - it "should have a tld of 'com'" do - expect(@uri.tld).to eq('com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.example.co.uk/'" do - before do - @uri = Addressable::URI.parse("http://www.example.co.uk/") - end - - it "should have an origin of 'http://www.example.co.uk'" do - expect(@uri.origin).to eq('http://www.example.co.uk') - end - - it "should have a tld of 'co.uk'" do - expect(@uri.tld).to eq('co.uk') - end - - it "should have a domain of 'example.co.uk'" do - expect(@uri.domain).to eq('example.co.uk') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://sub_domain.blogspot.com/'" do - before do - @uri = Addressable::URI.parse("http://sub_domain.blogspot.com/") - end - - it "should have an origin of 'http://sub_domain.blogspot.com'" do - expect(@uri.origin).to eq('http://sub_domain.blogspot.com') - end - - it "should have a tld of 'com'" do - expect(@uri.tld).to eq('com') - end - - it "should have a domain of 'blogspot.com'" do - expect(@uri.domain).to eq('blogspot.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/~smith/'" do - before do - @uri = Addressable::URI.parse("http://example.com/~smith/") - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://example.com/%7Esmith/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/%7Esmith/")) - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to http://example.com/%7esmith/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/%7esmith/")) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/%E8'" do - before do - @uri = Addressable::URI.parse("http://example.com/%E8") - end - - it "should not raise an exception when normalized" do - expect do - @uri.normalize - end.not_to raise_error - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com/%E8" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com/%E8" - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/path%2Fsegment/'" do - before do - @uri = Addressable::URI.parse("http://example.com/path%2Fsegment/") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should be equal to 'http://example.com/path%2Fsegment/'" do - expect(@uri.normalize).to be_eql( - Addressable::URI.parse("http://example.com/path%2Fsegment/") - ) - end - - it "should not be equal to 'http://example.com/path/segment/'" do - expect(@uri).not_to eq( - Addressable::URI.parse("http://example.com/path/segment/") - ) - end - - it "should not be equal to 'http://example.com/path/segment/'" do - expect(@uri.normalize).not_to be_eql( - Addressable::URI.parse("http://example.com/path/segment/") - ) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?%F6'" do - before do - @uri = Addressable::URI.parse("http://example.com/?%F6") - end - - it "should not raise an exception when normalized" do - expect do - @uri.normalize - end.not_to raise_error - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com/?%F6" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com/?%F6" - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/#%F6'" do - before do - @uri = Addressable::URI.parse("http://example.com/#%F6") - end - - it "should not raise an exception when normalized" do - expect do - @uri.normalize - end.not_to raise_error - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com/#%F6" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com/#%F6" - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/%C3%87'" do - before do - @uri = Addressable::URI.parse("http://example.com/%C3%87") - end - - # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence - it "should be equivalent to 'http://example.com/C%CC%A7'" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/C%CC%A7")) - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com/%C3%87" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com/%C3%87" - end - - it "should raise an error if encoding with an unexpected return type" do - expect do - Addressable::URI.normalized_encode(@uri, Integer) - end.to raise_error(TypeError) - end - - it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do - expect(Addressable::URI.encode(@uri).to_s).to eq( - "http://example.com/%25C3%2587" - ) - end - - it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do - expect(Addressable::URI.encode(@uri, Addressable::URI)).to eq( - Addressable::URI.parse("http://example.com/%25C3%2587") - ) - end - - it "should raise an error if encoding with an unexpected return type" do - expect do - Addressable::URI.encode(@uri, Integer) - end.to raise_error(TypeError) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q=string'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q=string") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/'" do - expect(@uri.path).to eq("/") - end - - it "should have a query string of 'q=string'" do - expect(@uri.query).to eq("q=string") - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should not be considered relative" do - expect(@uri).not_to be_relative - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com:80/'" do - before do - @uri = Addressable::URI.parse("http://example.com:80/") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com:80'" do - expect(@uri.authority).to eq("example.com:80") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have explicit port 80" do - expect(@uri.port).to eq(80) - end - - it "should have a path of '/'" do - expect(@uri.path).to eq("/") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should not be considered relative" do - expect(@uri).not_to be_relative - end - - it "should be exactly equal to http://example.com:80/" do - expect(@uri.eql?(Addressable::URI.parse("http://example.com:80/"))).to eq(true) - end - - it "should be roughly equal to http://example.com/" do - expect(@uri === Addressable::URI.parse("http://example.com/")).to eq(true) - end - - it "should be roughly equal to the string 'http://example.com/'" do - expect(@uri === "http://example.com/").to eq(true) - end - - it "should not be roughly equal to the string " + - "'http://example.com:bogus/'" do - expect do - expect(@uri === "http://example.com:bogus/").to eq(false) - end.not_to raise_error - end - - it "should result in itself when joined with itself" do - expect(@uri.join(@uri).to_s).to eq("http://example.com:80/") - expect(@uri.join!(@uri).to_s).to eq("http://example.com:80/") - end - - # Section 6.2.3 of RFC 3986 - it "should be equal to http://example.com/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com/")) - end - - # Section 6.2.3 of RFC 3986 - it "should be equal to http://example.com:/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) - end - - # Section 6.2.3 of RFC 3986 - it "should be equal to http://example.com:80/" do - expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) - end - - # Section 6.2.2.1 of RFC 3986 - it "should be equal to http://EXAMPLE.COM/" do - expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.COM/")) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => 80, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com:80/" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com:80/" - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com:8080/'" do - before do - @uri = Addressable::URI.parse("http://example.com:8080/") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com:8080'" do - expect(@uri.authority).to eq("example.com:8080") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 8080" do - expect(@uri.inferred_port).to eq(8080) - end - - it "should have explicit port 8080" do - expect(@uri.port).to eq(8080) - end - - it "should have default port 80" do - expect(@uri.default_port).to eq(80) - end - - it "should have a path of '/'" do - expect(@uri.path).to eq("/") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should not be considered relative" do - expect(@uri).not_to be_relative - end - - it "should be exactly equal to http://example.com:8080/" do - expect(@uri.eql?(Addressable::URI.parse( - "http://example.com:8080/"))).to eq(true) - end - - it "should have a route of 'http://example.com:8080/' from " + - "'http://example.com/path/to/'" do - expect(@uri.route_from("http://example.com/path/to/")).to eq( - Addressable::URI.parse("http://example.com:8080/") - ) - end - - it "should have a route of 'http://example.com:8080/' from " + - "'http://example.com:80/path/to/'" do - expect(@uri.route_from("http://example.com:80/path/to/")).to eq( - Addressable::URI.parse("http://example.com:8080/") - ) - end - - it "should have a route of '../../' from " + - "'http://example.com:8080/path/to/'" do - expect(@uri.route_from("http://example.com:8080/path/to/")).to eq( - Addressable::URI.parse("../../") - ) - end - - it "should have a route of 'http://example.com:8080/' from " + - "'http://user:pass@example.com/path/to/'" do - expect(@uri.route_from("http://user:pass@example.com/path/to/")).to eq( - Addressable::URI.parse("http://example.com:8080/") - ) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => 8080, - :path => "/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com:8080'" do - expect(@uri.origin).to eq('http://example.com:8080') - end - - it "should not change if encoded with the normalizing algorithm" do - expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( - "http://example.com:8080/" - ) - expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === - "http://example.com:8080/" - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com:%38%30/'" do - before do - @uri = Addressable::URI.parse("http://example.com:%38%30/") - end - - it "should have the correct port" do - expect(@uri.port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed with empty port" do - subject(:uri) do - Addressable::URI.parse("//example.com:") - end - - it "should not infer a port" do - expect(uri.port).to be(nil) - end - - it "should have a site value of '//example.com'" do - expect(uri.site).to eq("//example.com") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/%2E/'" do - before do - @uri = Addressable::URI.parse("http://example.com/%2E/") - end - - it "should be considered to be in normal form" do - skip( - 'path segment normalization should happen before ' + - 'percent escaping normalization' - ) - @uri.normalize.should be_eql(@uri) - end - - it "should normalize to 'http://example.com/%2E/'" do - skip( - 'path segment normalization should happen before ' + - 'percent escaping normalization' - ) - expect(@uri.normalize).to eq("http://example.com/%2E/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/..'" do - before do - @uri = Addressable::URI.parse("http://example.com/..") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/../..'" do - before do - @uri = Addressable::URI.parse("http://example.com/../..") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/path(/..'" do - before do - @uri = Addressable::URI.parse("http://example.com/path(/..") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/(path)/..'" do - before do - @uri = Addressable::URI.parse("http://example.com/(path)/..") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/path(/../'" do - before do - @uri = Addressable::URI.parse("http://example.com/path(/../") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/(path)/../'" do - before do - @uri = Addressable::URI.parse("http://example.com/(path)/../") - end - - it "should have the correct port" do - expect(@uri.inferred_port).to eq(80) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'/..//example.com'" do - before do - @uri = Addressable::URI.parse("/..//example.com") - end - - it "should become invalid when normalized" do - expect do - @uri.normalize - end.to raise_error(Addressable::URI::InvalidURIError, /authority/) - end - - it "should have a path of '/..//example.com'" do - expect(@uri.path).to eq("/..//example.com") - end -end - -describe Addressable::URI, "when parsed from '/a/b/c/./../../g'" do - before do - @uri = Addressable::URI.parse("/a/b/c/./../../g") - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - # Section 5.2.4 of RFC 3986 - it "should normalize to '/a/g'" do - expect(@uri.normalize.to_s).to eq("/a/g") - end -end - -describe Addressable::URI, "when parsed from 'mid/content=5/../6'" do - before do - @uri = Addressable::URI.parse("mid/content=5/../6") - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - # Section 5.2.4 of RFC 3986 - it "should normalize to 'mid/6'" do - expect(@uri.normalize.to_s).to eq("mid/6") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.example.com///../'" do - before do - @uri = Addressable::URI.parse('http://www.example.com///../') - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end - - it "should normalize to 'http://www.example.com//'" do - expect(@uri.normalize.to_s).to eq("http://www.example.com//") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/path/to/resource/'" do - before do - @uri = Addressable::URI.parse("http://example.com/path/to/resource/") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/path/to/resource/'" do - expect(@uri.path).to eq("/path/to/resource/") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should not be considered relative" do - expect(@uri).not_to be_relative - end - - it "should be exactly equal to http://example.com:8080/" do - expect(@uri.eql?(Addressable::URI.parse( - "http://example.com/path/to/resource/"))).to eq(true) - end - - it "should have a route of 'resource/' from " + - "'http://example.com/path/to/'" do - expect(@uri.route_from("http://example.com/path/to/")).to eq( - Addressable::URI.parse("resource/") - ) - end - - it "should have a route of '../' from " + - "'http://example.com/path/to/resource/sub'" do - expect(@uri.route_from("http://example.com/path/to/resource/sub")).to eq( - Addressable::URI.parse("../") - ) - end - - - it "should have a route of 'resource/' from " + - "'http://example.com/path/to/another'" do - expect(@uri.route_from("http://example.com/path/to/another")).to eq( - Addressable::URI.parse("resource/") - ) - end - - it "should have a route of 'resource/' from " + - "'http://example.com/path/to/res'" do - expect(@uri.route_from("http://example.com/path/to/res")).to eq( - Addressable::URI.parse("resource/") - ) - end - - it "should have a route of 'resource/' from " + - "'http://example.com:80/path/to/'" do - expect(@uri.route_from("http://example.com:80/path/to/")).to eq( - Addressable::URI.parse("resource/") - ) - end - - it "should have a route of 'http://example.com/path/to/' from " + - "'http://example.com:8080/path/to/'" do - expect(@uri.route_from("http://example.com:8080/path/to/")).to eq( - Addressable::URI.parse("http://example.com/path/to/resource/") - ) - end - - it "should have a route of 'http://example.com/path/to/' from " + - "'http://user:pass@example.com/path/to/'" do - expect(@uri.route_from("http://user:pass@example.com/path/to/")).to eq( - Addressable::URI.parse("http://example.com/path/to/resource/") - ) - end - - it "should have a route of '../../path/to/resource/' from " + - "'http://example.com/to/resource/'" do - expect(@uri.route_from("http://example.com/to/resource/")).to eq( - Addressable::URI.parse("../../path/to/resource/") - ) - end - - it "should correctly convert to a hash" do - expect(@uri.to_hash).to eq({ - :scheme => "http", - :user => nil, - :password => nil, - :host => "example.com", - :port => nil, - :path => "/path/to/resource/", - :query => nil, - :fragment => nil - }) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end -end - -describe Addressable::URI, "when parsed from " + - "'relative/path/to/resource'" do - before do - @uri = Addressable::URI.parse("relative/path/to/resource") - end - - it "should not have a scheme" do - expect(@uri.scheme).to eq(nil) - end - - it "should not be considered ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should not have an authority segment" do - expect(@uri.authority).to eq(nil) - end - - it "should not have a host" do - expect(@uri.host).to eq(nil) - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should not have a port" do - expect(@uri.port).to eq(nil) - end - - it "should have a path of 'relative/path/to/resource'" do - expect(@uri.path).to eq("relative/path/to/resource") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should not be considered absolute" do - expect(@uri).not_to be_absolute - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "should raise an error if routing is attempted" do - expect do - @uri.route_to("http://example.com/") - end.to raise_error(ArgumentError, /relative\/path\/to\/resource/) - expect do - @uri.route_from("http://example.com/") - end.to raise_error(ArgumentError, /relative\/path\/to\/resource/) - end - - it "when joined with 'another/relative/path' should be " + - "'relative/path/to/another/relative/path'" do - expect(@uri.join('another/relative/path')).to eq( - Addressable::URI.parse("relative/path/to/another/relative/path") - ) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end -end - -describe Addressable::URI, "when parsed from " + - "'relative_path_with_no_slashes'" do - before do - @uri = Addressable::URI.parse("relative_path_with_no_slashes") - end - - it "should not have a scheme" do - expect(@uri.scheme).to eq(nil) - end - - it "should not be considered ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should not have an authority segment" do - expect(@uri.authority).to eq(nil) - end - - it "should not have a host" do - expect(@uri.host).to eq(nil) - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should not have a port" do - expect(@uri.port).to eq(nil) - end - - it "should have a path of 'relative_path_with_no_slashes'" do - expect(@uri.path).to eq("relative_path_with_no_slashes") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should not be considered absolute" do - expect(@uri).not_to be_absolute - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "when joined with 'another_relative_path' should be " + - "'another_relative_path'" do - expect(@uri.join('another_relative_path')).to eq( - Addressable::URI.parse("another_relative_path") - ) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/file.txt'" do - before do - @uri = Addressable::URI.parse("http://example.com/file.txt") - end - - it "should have a scheme of 'http'" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/file.txt'" do - expect(@uri.path).to eq("/file.txt") - end - - it "should have a basename of 'file.txt'" do - expect(@uri.basename).to eq("file.txt") - end - - it "should have an extname of '.txt'" do - expect(@uri.extname).to eq(".txt") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/file.txt;parameter'" do - before do - @uri = Addressable::URI.parse("http://example.com/file.txt;parameter") - end - - it "should have a scheme of 'http'" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/file.txt;parameter'" do - expect(@uri.path).to eq("/file.txt;parameter") - end - - it "should have a basename of 'file.txt'" do - expect(@uri.basename).to eq("file.txt") - end - - it "should have an extname of '.txt'" do - expect(@uri.extname).to eq(".txt") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/file.txt;x=y'" do - before do - @uri = Addressable::URI.parse("http://example.com/file.txt;x=y") - end - - it "should have a scheme of 'http'" do - expect(@uri.scheme).to eq("http") - end - - it "should have a scheme of 'http'" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'example.com'" do - expect(@uri.authority).to eq("example.com") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have no username" do - expect(@uri.user).to eq(nil) - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/file.txt;x=y'" do - expect(@uri.path).to eq("/file.txt;x=y") - end - - it "should have an extname of '.txt'" do - expect(@uri.extname).to eq(".txt") - end - - it "should have no query string" do - expect(@uri.query).to eq(nil) - end - - it "should have no fragment" do - expect(@uri.fragment).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'svn+ssh://developername@rubyforge.org/var/svn/project'" do - before do - @uri = Addressable::URI.parse( - "svn+ssh://developername@rubyforge.org/var/svn/project" - ) - end - - it "should have a scheme of 'svn+ssh'" do - expect(@uri.scheme).to eq("svn+ssh") - end - - it "should be considered to be ip-based" do - expect(@uri).to be_ip_based - end - - it "should have a path of '/var/svn/project'" do - expect(@uri.path).to eq("/var/svn/project") - end - - it "should have a username of 'developername'" do - expect(@uri.user).to eq("developername") - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'ssh+svn://developername@RUBYFORGE.ORG/var/svn/project'" do - before do - @uri = Addressable::URI.parse( - "ssh+svn://developername@RUBYFORGE.ORG/var/svn/project" - ) - end - - it "should have a scheme of 'ssh+svn'" do - expect(@uri.scheme).to eq("ssh+svn") - end - - it "should have a normalized scheme of 'svn+ssh'" do - expect(@uri.normalized_scheme).to eq("svn+ssh") - end - - it "should have a normalized site of 'svn+ssh'" do - expect(@uri.normalized_site).to eq("svn+ssh://developername@rubyforge.org") - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of '/var/svn/project'" do - expect(@uri.path).to eq("/var/svn/project") - end - - it "should have a username of 'developername'" do - expect(@uri.user).to eq("developername") - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should not be considered to be in normal form" do - expect(@uri.normalize).not_to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'mailto:user@example.com'" do - before do - @uri = Addressable::URI.parse("mailto:user@example.com") - end - - it "should have a scheme of 'mailto'" do - expect(@uri.scheme).to eq("mailto") - end - - it "should not be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of 'user@example.com'" do - expect(@uri.path).to eq("user@example.com") - end - - it "should have no user" do - expect(@uri.user).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'tag:example.com,2006-08-18:/path/to/something'" do - before do - @uri = Addressable::URI.parse( - "tag:example.com,2006-08-18:/path/to/something") - end - - it "should have a scheme of 'tag'" do - expect(@uri.scheme).to eq("tag") - end - - it "should be considered to be ip-based" do - expect(@uri).not_to be_ip_based - end - - it "should have a path of " + - "'example.com,2006-08-18:/path/to/something'" do - expect(@uri.path).to eq("example.com,2006-08-18:/path/to/something") - end - - it "should have no user" do - expect(@uri.user).to eq(nil) - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/x;y/'" do - before do - @uri = Addressable::URI.parse("http://example.com/x;y/") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?x=1&y=2'" do - before do - @uri = Addressable::URI.parse("http://example.com/?x=1&y=2") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end -end - -describe Addressable::URI, "when parsed from " + - "'view-source:http://example.com/'" do - before do - @uri = Addressable::URI.parse("view-source:http://example.com/") - end - - it "should have a scheme of 'view-source'" do - expect(@uri.scheme).to eq("view-source") - end - - it "should have a path of 'http://example.com/'" do - expect(@uri.path).to eq("http://example.com/") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do - before do - @uri = Addressable::URI.parse( - "http://user:pass@example.com/path/to/resource?query=x#fragment") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have an authority segment of 'user:pass@example.com'" do - expect(@uri.authority).to eq("user:pass@example.com") - end - - it "should have a username of 'user'" do - expect(@uri.user).to eq("user") - end - - it "should have a password of 'pass'" do - expect(@uri.password).to eq("pass") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/path/to/resource'" do - expect(@uri.path).to eq("/path/to/resource") - end - - it "should have a query string of 'query=x'" do - expect(@uri.query).to eq("query=x") - end - - it "should have a fragment of 'fragment'" do - expect(@uri.fragment).to eq("fragment") - end - - it "should be considered to be in normal form" do - expect(@uri.normalize).to be_eql(@uri) - end - - it "should have a route of '../../' to " + - "'http://user:pass@example.com/path/'" do - expect(@uri.route_to("http://user:pass@example.com/path/")).to eq( - Addressable::URI.parse("../../") - ) - end - - it "should have a route of 'to/resource?query=x#fragment' " + - "from 'http://user:pass@example.com/path/'" do - expect(@uri.route_from("http://user:pass@example.com/path/")).to eq( - Addressable::URI.parse("to/resource?query=x#fragment") - ) - end - - it "should have a route of '?query=x#fragment' " + - "from 'http://user:pass@example.com/path/to/resource'" do - expect(@uri.route_from("http://user:pass@example.com/path/to/resource")).to eq( - Addressable::URI.parse("?query=x#fragment") - ) - end - - it "should have a route of '#fragment' " + - "from 'http://user:pass@example.com/path/to/resource?query=x'" do - expect(@uri.route_from( - "http://user:pass@example.com/path/to/resource?query=x")).to eq( - Addressable::URI.parse("#fragment") - ) - end - - it "should have a route of '#fragment' from " + - "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do - expect(@uri.route_from( - "http://user:pass@example.com/path/to/resource?query=x#fragment" - )).to eq(Addressable::URI.parse("#fragment")) - end - - it "should have a route of 'http://elsewhere.com/' to " + - "'http://elsewhere.com/'" do - expect(@uri.route_to("http://elsewhere.com/")).to eq( - Addressable::URI.parse("http://elsewhere.com/") - ) - end - - it "should have a route of " + - "'http://user:pass@example.com/path/to/resource?query=x#fragment' " + - "from 'http://example.com/path/to/'" do - expect(@uri.route_from("http://elsewhere.com/path/to/")).to eq( - Addressable::URI.parse( - "http://user:pass@example.com/path/to/resource?query=x#fragment") - ) - end - - it "should have the correct scheme after assignment" do - @uri.scheme = "ftp" - expect(@uri.scheme).to eq("ftp") - expect(@uri.to_s).to eq( - "ftp://user:pass@example.com/path/to/resource?query=x#fragment" - ) - expect(@uri.to_str).to eq( - "ftp://user:pass@example.com/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct site segment after assignment" do - @uri.site = "https://newuser:newpass@example.com:443" - expect(@uri.scheme).to eq("https") - expect(@uri.authority).to eq("newuser:newpass@example.com:443") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("newpass") - expect(@uri.userinfo).to eq("newuser:newpass") - expect(@uri.normalized_userinfo).to eq("newuser:newpass") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(443) - expect(@uri.inferred_port).to eq(443) - expect(@uri.to_s).to eq( - "https://newuser:newpass@example.com:443" + - "/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct authority segment after assignment" do - @uri.authority = "newuser:newpass@example.com:80" - expect(@uri.authority).to eq("newuser:newpass@example.com:80") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("newpass") - expect(@uri.userinfo).to eq("newuser:newpass") - expect(@uri.normalized_userinfo).to eq("newuser:newpass") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(80) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq( - "http://newuser:newpass@example.com:80" + - "/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct userinfo segment after assignment" do - @uri.userinfo = "newuser:newpass" - expect(@uri.userinfo).to eq("newuser:newpass") - expect(@uri.authority).to eq("newuser:newpass@example.com") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("newpass") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq( - "http://newuser:newpass@example.com" + - "/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.authority).to eq("newuser:pass@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.authority).to eq("user:newpass@example.com") - end - - it "should have the correct host after assignment" do - @uri.host = "newexample.com" - expect(@uri.host).to eq("newexample.com") - expect(@uri.authority).to eq("user:pass@newexample.com") - end - - it "should have the correct host after assignment" do - @uri.hostname = "newexample.com" - expect(@uri.host).to eq("newexample.com") - expect(@uri.hostname).to eq("newexample.com") - expect(@uri.authority).to eq("user:pass@newexample.com") - end - - it "should raise an error if assigning a bogus object to the hostname" do - expect do - @uri.hostname = Object.new - end.to raise_error(TypeError) - end - - it "should have the correct port after assignment" do - @uri.port = 8080 - expect(@uri.port).to eq(8080) - expect(@uri.authority).to eq("user:pass@example.com:8080") - end - - it "should have the correct origin after assignment" do - @uri.origin = "http://newexample.com" - expect(@uri.host).to eq("newexample.com") - expect(@uri.authority).to eq("newexample.com") - end - - it "should have the correct path after assignment" do - @uri.path = "/newpath/to/resource" - expect(@uri.path).to eq("/newpath/to/resource") - expect(@uri.to_s).to eq( - "http://user:pass@example.com/newpath/to/resource?query=x#fragment" - ) - end - - it "should have the correct scheme and authority after nil assignment" do - @uri.site = nil - expect(@uri.scheme).to eq(nil) - expect(@uri.authority).to eq(nil) - expect(@uri.to_s).to eq("/path/to/resource?query=x#fragment") - end - - it "should have the correct scheme and authority after assignment" do - @uri.site = "file://" - expect(@uri.scheme).to eq("file") - expect(@uri.authority).to eq("") - expect(@uri.to_s).to eq("file:///path/to/resource?query=x#fragment") - end - - it "should have the correct path after nil assignment" do - @uri.path = nil - expect(@uri.path).to eq("") - expect(@uri.to_s).to eq( - "http://user:pass@example.com?query=x#fragment" - ) - end - - it "should have the correct query string after assignment" do - @uri.query = "newquery=x" - expect(@uri.query).to eq("newquery=x") - expect(@uri.to_s).to eq( - "http://user:pass@example.com/path/to/resource?newquery=x#fragment" - ) - @uri.query = nil - expect(@uri.query).to eq(nil) - expect(@uri.to_s).to eq( - "http://user:pass@example.com/path/to/resource#fragment" - ) - end - - it "should have the correct query string after hash assignment" do - @uri.query_values = {"?uestion mark" => "=sign", "hello" => "g\xC3\xBCnther"} - expect(@uri.query.split("&")).to include("%3Fuestion%20mark=%3Dsign") - expect(@uri.query.split("&")).to include("hello=g%C3%BCnther") - expect(@uri.query_values).to eq({ - "?uestion mark" => "=sign", "hello" => "g\xC3\xBCnther" - }) - end - - it "should have the correct query string after flag hash assignment" do - @uri.query_values = {'flag?1' => nil, 'fl=ag2' => nil, 'flag3' => nil} - expect(@uri.query.split("&")).to include("flag%3F1") - expect(@uri.query.split("&")).to include("fl%3Dag2") - expect(@uri.query.split("&")).to include("flag3") - expect(@uri.query_values(Array).sort).to eq([["fl=ag2"], ["flag3"], ["flag?1"]]) - expect(@uri.query_values(Hash)).to eq({ - 'flag?1' => nil, 'fl=ag2' => nil, 'flag3' => nil - }) - end - - it "should raise an error if query values are set to a bogus type" do - expect do - @uri.query_values = "bogus" - end.to raise_error(TypeError) - end - - it "should have the correct fragment after assignment" do - @uri.fragment = "newfragment" - expect(@uri.fragment).to eq("newfragment") - expect(@uri.to_s).to eq( - "http://user:pass@example.com/path/to/resource?query=x#newfragment" - ) - - @uri.fragment = nil - expect(@uri.fragment).to eq(nil) - expect(@uri.to_s).to eq( - "http://user:pass@example.com/path/to/resource?query=x" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:fragment => "newfragment").to_s).to eq( - "http://user:pass@example.com/path/to/resource?query=x#newfragment" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:fragment => nil).to_s).to eq( - "http://user:pass@example.com/path/to/resource?query=x" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:userinfo => "newuser:newpass").to_s).to eq( - "http://newuser:newpass@example.com/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:userinfo => nil).to_s).to eq( - "http://example.com/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:path => "newpath").to_s).to eq( - "http://user:pass@example.com/newpath?query=x#fragment" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:port => "42", :path => "newpath", :query => "").to_s).to eq( - "http://user:pass@example.com:42/newpath?#fragment" - ) - end - - it "should have the correct values after a merge" do - expect(@uri.merge(:authority => "foo:bar@baz:42").to_s).to eq( - "http://foo:bar@baz:42/path/to/resource?query=x#fragment" - ) - # Ensure the operation was not destructive - expect(@uri.to_s).to eq( - "http://user:pass@example.com/path/to/resource?query=x#fragment" - ) - end - - it "should have the correct values after a destructive merge" do - @uri.merge!(:authority => "foo:bar@baz:42") - # Ensure the operation was destructive - expect(@uri.to_s).to eq( - "http://foo:bar@baz:42/path/to/resource?query=x#fragment" - ) - end - - it "should fail to merge with bogus values" do - expect do - @uri.merge(:port => "bogus") - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should fail to merge with bogus values" do - expect do - @uri.merge(:authority => "bar@baz:bogus") - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should fail to merge with bogus parameters" do - expect do - @uri.merge(42) - end.to raise_error(TypeError) - end - - it "should fail to merge with bogus parameters" do - expect do - @uri.merge("http://example.com/") - end.to raise_error(TypeError) - end - - it "should fail to merge with both authority and subcomponents" do - expect do - @uri.merge(:authority => "foo:bar@baz:42", :port => "42") - end.to raise_error(ArgumentError) - end - - it "should fail to merge with both userinfo and subcomponents" do - expect do - @uri.merge(:userinfo => "foo:bar", :user => "foo") - end.to raise_error(ArgumentError) - end - - it "should be identical to its duplicate" do - expect(@uri).to eq(@uri.dup) - end - - it "should have an origin of 'http://example.com'" do - expect(@uri.origin).to eq('http://example.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/search?q=Q%26A'" do - - before do - @uri = Addressable::URI.parse("http://example.com/search?q=Q%26A") - end - - it "should have a query of 'q=Q%26A'" do - expect(@uri.query).to eq("q=Q%26A") - end - - it "should have query_values of {'q' => 'Q&A'}" do - expect(@uri.query_values).to eq({ 'q' => 'Q&A' }) - end - - it "should normalize to the original uri " + - "(with the ampersand properly percent-encoded)" do - expect(@uri.normalize.to_s).to eq("http://example.com/search?q=Q%26A") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?&x=b'" do - before do - @uri = Addressable::URI.parse("http://example.com/?&x=b") - end - - it "should have a query of '&x=b'" do - expect(@uri.query).to eq("&x=b") - end - - it "should have query_values of {'x' => 'b'}" do - expect(@uri.query_values).to eq({'x' => 'b'}) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q='one;two'&x=1'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q='one;two'&x=1") - end - - it "should have a query of 'q='one;two'&x=1'" do - expect(@uri.query).to eq("q='one;two'&x=1") - end - - it "should have query_values of {\"q\" => \"'one;two'\", \"x\" => \"1\"}" do - expect(@uri.query_values).to eq({"q" => "'one;two'", "x" => "1"}) - end - - it "should escape the ';' character when normalizing to avoid ambiguity " + - "with the W3C HTML 4.01 specification" do - # HTML 4.01 Section B.2.2 - expect(@uri.normalize.query).to eq("q='one%3Btwo'&x=1") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?&&x=b'" do - before do - @uri = Addressable::URI.parse("http://example.com/?&&x=b") - end - - it "should have a query of '&&x=b'" do - expect(@uri.query).to eq("&&x=b") - end - - it "should have query_values of {'x' => 'b'}" do - expect(@uri.query_values).to eq({'x' => 'b'}) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q=a&&x=b'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q=a&&x=b") - end - - it "should have a query of 'q=a&&x=b'" do - expect(@uri.query).to eq("q=a&&x=b") - end - - it "should have query_values of {'q' => 'a, 'x' => 'b'}" do - expect(@uri.query_values).to eq({'q' => 'a', 'x' => 'b'}) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q&&x=b'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q&&x=b") - end - - it "should have a query of 'q&&x=b'" do - expect(@uri.query).to eq("q&&x=b") - end - - it "should have query_values of {'q' => true, 'x' => 'b'}" do - expect(@uri.query_values).to eq({'q' => nil, 'x' => 'b'}) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q=a+b'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q=a+b") - end - - it "should have a query of 'q=a+b'" do - expect(@uri.query).to eq("q=a+b") - end - - it "should have query_values of {'q' => 'a b'}" do - expect(@uri.query_values).to eq({'q' => 'a b'}) - end - - it "should have a normalized query of 'q=a+b'" do - expect(@uri.normalized_query).to eq("q=a+b") - end -end - -describe Addressable::URI, "when parsed from 'https://example.com/?q=a+b'" do - before do - @uri = Addressable::URI.parse("https://example.com/?q=a+b") - end - - it "should have query_values of {'q' => 'a b'}" do - expect(@uri.query_values).to eq("q" => "a b") - end -end - -describe Addressable::URI, "when parsed from 'example.com?q=a+b'" do - before do - @uri = Addressable::URI.parse("example.com?q=a+b") - end - - it "should have query_values of {'q' => 'a b'}" do - expect(@uri.query_values).to eq("q" => "a b") - end -end - -describe Addressable::URI, "when parsed from 'mailto:?q=a+b'" do - before do - @uri = Addressable::URI.parse("mailto:?q=a+b") - end - - it "should have query_values of {'q' => 'a+b'}" do - expect(@uri.query_values).to eq("q" => "a+b") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q=a%2bb'" do - before do - @uri = Addressable::URI.parse("http://example.com/?q=a%2bb") - end - - it "should have a query of 'q=a+b'" do - expect(@uri.query).to eq("q=a%2bb") - end - - it "should have query_values of {'q' => 'a+b'}" do - expect(@uri.query_values).to eq({'q' => 'a+b'}) - end - - it "should have a normalized query of 'q=a%2Bb'" do - expect(@uri.normalized_query).to eq("q=a%2Bb") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?v=%7E&w=%&x=%25&y=%2B&z=C%CC%A7'" do - before do - @uri = Addressable::URI.parse("http://example.com/?v=%7E&w=%&x=%25&y=%2B&z=C%CC%A7") - end - - it "should have a normalized query of 'v=~&w=%25&x=%25&y=%2B&z=%C3%87'" do - expect(@uri.normalized_query).to eq("v=~&w=%25&x=%25&y=%2B&z=%C3%87") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?v=%7E&w=%&x=%25&y=+&z=C%CC%A7'" do - before do - @uri = Addressable::URI.parse("http://example.com/?v=%7E&w=%&x=%25&y=+&z=C%CC%A7") - end - - it "should have a normalized query of 'v=~&w=%25&x=%25&y=+&z=%C3%87'" do - expect(@uri.normalized_query).to eq("v=~&w=%25&x=%25&y=+&z=%C3%87") - end -end - -describe Addressable::URI, "when parsed from 'http://example/?b=1&a=2&c=3'" do - before do - @uri = Addressable::URI.parse("http://example/?b=1&a=2&c=3") - end - - it "should have a sorted normalized query of 'a=2&b=1&c=3'" do - expect(@uri.normalized_query(:sorted)).to eq("a=2&b=1&c=3") - end -end - -describe Addressable::URI, "when parsed from 'http://example/?&a&&c&'" do - before do - @uri = Addressable::URI.parse("http://example/?&a&&c&") - end - - it "should have a compacted normalized query of 'a&c'" do - expect(@uri.normalized_query(:compacted)).to eq("a&c") - end -end - -describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=1'" do - before do - @uri = Addressable::URI.parse("http://example.com/?a=1&a=1") - end - - it "should have a compacted normalized query of 'a=1'" do - expect(@uri.normalized_query(:compacted)).to eq("a=1") - end -end - -describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=2'" do - before do - @uri = Addressable::URI.parse("http://example.com/?a=1&a=2") - end - - it "should have a compacted normalized query of 'a=1&a=2'" do - expect(@uri.normalized_query(:compacted)).to eq("a=1&a=2") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/sound%2bvision'" do - before do - @uri = Addressable::URI.parse("http://example.com/sound%2bvision") - end - - it "should have a normalized path of '/sound+vision'" do - expect(@uri.normalized_path).to eq('/sound+vision') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/?q='" do - before do - @uri = Addressable::URI.parse("http://example.com/?q=") - end - - it "should have a query of 'q='" do - expect(@uri.query).to eq("q=") - end - - it "should have query_values of {'q' => ''}" do - expect(@uri.query_values).to eq({'q' => ''}) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://user@example.com'" do - before do - @uri = Addressable::URI.parse("http://user@example.com") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a username of 'user'" do - expect(@uri.user).to eq("user") - end - - it "should have no password" do - expect(@uri.password).to eq(nil) - end - - it "should have a userinfo of 'user'" do - expect(@uri.userinfo).to eq("user") - end - - it "should have a normalized userinfo of 'user'" do - expect(@uri.normalized_userinfo).to eq("user") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have default_port 80" do - expect(@uri.default_port).to eq(80) - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq(nil) - expect(@uri.to_s).to eq("http://newuser@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.to_s).to eq("http://user:newpass@example.com") - end - - it "should have the correct userinfo segment after assignment" do - @uri.userinfo = "newuser:newpass" - expect(@uri.userinfo).to eq("newuser:newpass") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("newpass") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://newuser:newpass@example.com") - end - - it "should have the correct userinfo segment after nil assignment" do - @uri.userinfo = nil - expect(@uri.userinfo).to eq(nil) - expect(@uri.user).to eq(nil) - expect(@uri.password).to eq(nil) - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://example.com") - end - - it "should have the correct authority segment after assignment" do - @uri.authority = "newuser@example.com" - expect(@uri.authority).to eq("newuser@example.com") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq(nil) - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://newuser@example.com") - end - - it "should raise an error after nil assignment of authority segment" do - expect do - # This would create an invalid URI - @uri.authority = nil - end.to raise_error(Addressable::URI::InvalidURIError) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://user:@example.com'" do - before do - @uri = Addressable::URI.parse("http://user:@example.com") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a username of 'user'" do - expect(@uri.user).to eq("user") - end - - it "should have a password of ''" do - expect(@uri.password).to eq("") - end - - it "should have a normalized userinfo of 'user:'" do - expect(@uri.normalized_userinfo).to eq("user:") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("") - expect(@uri.to_s).to eq("http://newuser:@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.to_s).to eq("http://user:newpass@example.com") - end - - it "should have the correct authority segment after assignment" do - @uri.authority = "newuser:@example.com" - expect(@uri.authority).to eq("newuser:@example.com") - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://newuser:@example.com") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://:pass@example.com'" do - before do - @uri = Addressable::URI.parse("http://:pass@example.com") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a username of ''" do - expect(@uri.user).to eq("") - end - - it "should have a password of 'pass'" do - expect(@uri.password).to eq("pass") - end - - it "should have a userinfo of ':pass'" do - expect(@uri.userinfo).to eq(":pass") - end - - it "should have a normalized userinfo of ':pass'" do - expect(@uri.normalized_userinfo).to eq(":pass") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("pass") - expect(@uri.to_s).to eq("http://newuser:pass@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.user).to eq("") - expect(@uri.to_s).to eq("http://:newpass@example.com") - end - - it "should have the correct authority segment after assignment" do - @uri.authority = ":newpass@example.com" - expect(@uri.authority).to eq(":newpass@example.com") - expect(@uri.user).to eq("") - expect(@uri.password).to eq("newpass") - expect(@uri.host).to eq("example.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://:newpass@example.com") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://:@example.com'" do - before do - @uri = Addressable::URI.parse("http://:@example.com") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a username of ''" do - expect(@uri.user).to eq("") - end - - it "should have a password of ''" do - expect(@uri.password).to eq("") - end - - it "should have a normalized userinfo of nil" do - expect(@uri.normalized_userinfo).to eq(nil) - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have the correct username after assignment" do - @uri.user = "newuser" - expect(@uri.user).to eq("newuser") - expect(@uri.password).to eq("") - expect(@uri.to_s).to eq("http://newuser:@example.com") - end - - it "should have the correct password after assignment" do - @uri.password = "newpass" - expect(@uri.password).to eq("newpass") - expect(@uri.user).to eq("") - expect(@uri.to_s).to eq("http://:newpass@example.com") - end - - it "should have the correct authority segment after assignment" do - @uri.authority = ":@newexample.com" - expect(@uri.authority).to eq(":@newexample.com") - expect(@uri.user).to eq("") - expect(@uri.password).to eq("") - expect(@uri.host).to eq("newexample.com") - expect(@uri.port).to eq(nil) - expect(@uri.inferred_port).to eq(80) - expect(@uri.to_s).to eq("http://:@newexample.com") - end -end - -describe Addressable::URI, "when parsed from " + - "'#example'" do - before do - @uri = Addressable::URI.parse("#example") - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "should have a host of nil" do - expect(@uri.host).to eq(nil) - end - - it "should have a site of nil" do - expect(@uri.site).to eq(nil) - end - - it "should have a normalized_site of nil" do - expect(@uri.normalized_site).to eq(nil) - end - - it "should have a path of ''" do - expect(@uri.path).to eq("") - end - - it "should have a query string of nil" do - expect(@uri.query).to eq(nil) - end - - it "should have a fragment of 'example'" do - expect(@uri.fragment).to eq("example") - end -end - -describe Addressable::URI, "when parsed from " + - "the network-path reference '//example.com/'" do - before do - @uri = Addressable::URI.parse("//example.com/") - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should have a path of '/'" do - expect(@uri.path).to eq("/") - end - - it "should raise an error if routing is attempted" do - expect do - @uri.route_to("http://example.com/") - end.to raise_error(ArgumentError, /\/\/example.com\//) - expect do - @uri.route_from("http://example.com/") - end.to raise_error(ArgumentError, /\/\/example.com\//) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from " + - "'feed://http://example.com/'" do - before do - @uri = Addressable::URI.parse("feed://http://example.com/") - end - - it "should have a host of 'http'" do - expect(@uri.host).to eq("http") - end - - it "should have a path of '//example.com/'" do - expect(@uri.path).to eq("//example.com/") - end -end - -describe Addressable::URI, "when parsed from " + - "'feed:http://example.com/'" do - before do - @uri = Addressable::URI.parse("feed:http://example.com/") - end - - it "should have a path of 'http://example.com/'" do - expect(@uri.path).to eq("http://example.com/") - end - - it "should normalize to 'http://example.com/'" do - expect(@uri.normalize.to_s).to eq("http://example.com/") - expect(@uri.normalize!.to_s).to eq("http://example.com/") - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from " + - "'example://a/b/c/%7Bfoo%7D'" do - before do - @uri = Addressable::URI.parse("example://a/b/c/%7Bfoo%7D") - end - - # Section 6.2.2 of RFC 3986 - it "should be equivalent to eXAMPLE://a/./b/../b/%63/%7bfoo%7d" do - expect(@uri).to eq( - Addressable::URI.parse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d") - ) - end - - it "should have an origin of 'example://a'" do - expect(@uri.origin).to eq('example://a') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://example.com/indirect/path/./to/../resource/'" do - before do - @uri = Addressable::URI.parse( - "http://example.com/indirect/path/./to/../resource/") - end - - it "should use the 'http' scheme" do - expect(@uri.scheme).to eq("http") - end - - it "should have a host of 'example.com'" do - expect(@uri.host).to eq("example.com") - end - - it "should use port 80" do - expect(@uri.inferred_port).to eq(80) - end - - it "should have a path of '/indirect/path/./to/../resource/'" do - expect(@uri.path).to eq("/indirect/path/./to/../resource/") - end - - # Section 6.2.2.3 of RFC 3986 - it "should have a normalized path of '/indirect/path/resource/'" do - expect(@uri.normalize.path).to eq("/indirect/path/resource/") - expect(@uri.normalize!.path).to eq("/indirect/path/resource/") - end -end - -describe Addressable::URI, "when parsed from " + - "'http://under_score.example.com/'" do - it "should not cause an error" do - expect do - Addressable::URI.parse("http://under_score.example.com/") - end.not_to raise_error - end -end - -describe Addressable::URI, "when parsed from " + - "'./this:that'" do - before do - @uri = Addressable::URI.parse("./this:that") - end - - it "should be considered relative" do - expect(@uri).to be_relative - end - - it "should have no scheme" do - expect(@uri.scheme).to eq(nil) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from " + - "'this:that'" do - before do - @uri = Addressable::URI.parse("this:that") - end - - it "should be considered absolute" do - expect(@uri).to be_absolute - end - - it "should have a scheme of 'this'" do - expect(@uri.scheme).to eq("this") - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from '?'" do - before do - @uri = Addressable::URI.parse("?") - end - - it "should normalize to ''" do - expect(@uri.normalize.to_s).to eq("") - end - - it "should have the correct return type" do - expect(@uri.query_values).to eq({}) - expect(@uri.query_values(Hash)).to eq({}) - expect(@uri.query_values(Array)).to eq([]) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do - before do - @uri = Addressable::URI.parse("?one=1&two=2&three=3") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({"one" => "1", "two" => "2", "three" => "3"}) - end - - it "should raise an error for invalid return type values" do - expect do - @uri.query_values(Integer) - end.to raise_error(ArgumentError) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one", "1"], ["two", "2"], ["three", "3"] - ]) - end - - it "should have a 'null' origin" do - expect(@uri.origin).to eq('null') - end -end - -describe Addressable::URI, "when parsed from '?one=1=uno&two=2=dos'" do - before do - @uri = Addressable::URI.parse("?one=1=uno&two=2=dos") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({"one" => "1=uno", "two" => "2=dos"}) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one", "1=uno"], ["two", "2=dos"] - ]) - end -end - -describe Addressable::URI, "when parsed from '?one[two][three]=four'" do - before do - @uri = Addressable::URI.parse("?one[two][three]=four") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({"one[two][three]" => "four"}) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one[two][three]", "four"] - ]) - end -end - -describe Addressable::URI, "when parsed from '?one.two.three=four'" do - before do - @uri = Addressable::URI.parse("?one.two.three=four") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one.two.three" => "four" - }) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one.two.three", "four"] - ]) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one[two][three]=four&one[two][five]=six'" do - before do - @uri = Addressable::URI.parse("?one[two][three]=four&one[two][five]=six") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one[two][three]" => "four", "one[two][five]" => "six" - }) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one[two][three]", "four"], ["one[two][five]", "six"] - ]) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one.two.three=four&one.two.five=six'" do - before do - @uri = Addressable::URI.parse("?one.two.three=four&one.two.five=six") - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one.two.three" => "four", "one.two.five" => "six" - }) - end - - it "should have the correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one.two.three", "four"], ["one.two.five", "six"] - ]) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one=two&one=three'" do - before do - @uri = Addressable::URI.parse( - "?one=two&one=three&one=four" - ) - end - - it "should have correct array query values" do - expect(@uri.query_values(Array)).to eq( - [['one', 'two'], ['one', 'three'], ['one', 'four']] - ) - end - - it "should have correct hash query values" do - skip("This is probably more desirable behavior.") - expect(@uri.query_values(Hash)).to eq( - {'one' => ['two', 'three', 'four']} - ) - end - - it "should handle assignment with keys of mixed type" do - @uri.query_values = @uri.query_values(Hash).merge({:one => 'three'}) - expect(@uri.query_values(Hash)).to eq({'one' => 'three'}) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one[two][three][]=four&one[two][three][]=five'" do - before do - @uri = Addressable::URI.parse( - "?one[two][three][]=four&one[two][three][]=five" - ) - end - - it "should have correct query values" do - expect(@uri.query_values(Hash)).to eq({"one[two][three][]" => "five"}) - end - - it "should have correct array query values" do - expect(@uri.query_values(Array)).to eq([ - ["one[two][three][]", "four"], ["one[two][three][]", "five"] - ]) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one[two][three][0]=four&one[two][three][1]=five'" do - before do - @uri = Addressable::URI.parse( - "?one[two][three][0]=four&one[two][three][1]=five" - ) - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one[two][three][0]" => "four", "one[two][three][1]" => "five" - }) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one[two][three][1]=four&one[two][three][0]=five'" do - before do - @uri = Addressable::URI.parse( - "?one[two][three][1]=four&one[two][three][0]=five" - ) - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one[two][three][1]" => "four", "one[two][three][0]" => "five" - }) - end -end - -describe Addressable::URI, "when parsed from " + - "'?one[two][three][2]=four&one[two][three][1]=five'" do - before do - @uri = Addressable::URI.parse( - "?one[two][three][2]=four&one[two][three][1]=five" - ) - end - - it "should have the correct query values" do - expect(@uri.query_values).to eq({ - "one[two][three][2]" => "four", "one[two][three][1]" => "five" - }) - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.詹姆斯.com/'" do - before do - @uri = Addressable::URI.parse("http://www.詹姆斯.com/") - end - - it "should be equivalent to 'http://www.xn--8ws00zhy3a.com/'" do - expect(@uri).to eq( - Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/") - ) - end - - it "should not have domain name encoded during normalization" do - expect(Addressable::URI.normalized_encode(@uri.to_s)).to eq( - "http://www.詹姆斯.com/" - ) - end - - it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do - expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.詹姆斯.com/ some spaces /'" do - before do - @uri = Addressable::URI.parse("http://www.詹姆斯.com/ some spaces /") - end - - it "should be equivalent to " + - "'http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/'" do - expect(@uri).to eq( - Addressable::URI.parse( - "http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/") - ) - end - - it "should not have domain name encoded during normalization" do - expect(Addressable::URI.normalized_encode(@uri.to_s)).to eq( - "http://www.詹姆斯.com/%20some%20spaces%20/" - ) - end - - it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do - expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.xn--8ws00zhy3a.com/'" do - before do - @uri = Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/") - end - - it "should be displayed as http://www.詹姆斯.com/" do - expect(@uri.display_uri.to_s).to eq("http://www.詹姆斯.com/") - end - - it "should properly force the encoding" do - display_string = @uri.display_uri.to_str - expect(display_string).to eq("http://www.詹姆斯.com/") - if display_string.respond_to?(:encoding) - expect(display_string.encoding.to_s).to eq(Encoding::UTF_8.to_s) - end - end - - it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do - expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') - end -end - -describe Addressable::URI, "when parsed from " + - "'http://www.詹姆斯.com/atomtests/iri/詹.html'" do - before do - @uri = Addressable::URI.parse("http://www.詹姆斯.com/atomtests/iri/詹.html") - end - - it "should normalize to " + - "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" do - expect(@uri.normalize.to_s).to eq( - "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" - ) - expect(@uri.normalize!.to_s).to eq( - "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" - ) - end -end - -describe Addressable::URI, "when parsed from a percent-encoded IRI" do - before do - @uri = Addressable::URI.parse( - "http://www.%E3%81%BB%E3%82%93%E3%81%A8%E3%81%86%E3%81%AB%E3%81%AA" + - "%E3%81%8C%E3%81%84%E3%82%8F%E3%81%91%E3%81%AE%E3%82%8F%E3%81%8B%E3" + - "%82%89%E3%81%AA%E3%81%84%E3%81%A9%E3%82%81%E3%81%84%E3%82%93%E3%82" + - "%81%E3%81%84%E3%81%AE%E3%82%89%E3%81%B9%E3%82%8B%E3%81%BE%E3%81%A0" + - "%E3%81%AA%E3%81%8C%E3%81%8F%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3" + - "%81%9F%E3%82%8A%E3%81%AA%E3%81%84.w3.mag.keio.ac.jp" - ) - end - - it "should normalize to something sane" do - expect(@uri.normalize.to_s).to eq( - "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + - "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" - ) - expect(@uri.normalize!.to_s).to eq( - "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + - "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" - ) - end - - it "should have the correct origin" do - expect(@uri.origin).to eq( - "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + - "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" - ) - end -end - -describe Addressable::URI, "with a base uri of 'http://a/b/c/d;p?q'" do - before do - @uri = Addressable::URI.parse("http://a/b/c/d;p?q") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g:h' should resolve to g:h" do - expect((@uri + "g:h").to_s).to eq("g:h") - expect(Addressable::URI.join(@uri, "g:h").to_s).to eq("g:h") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g' should resolve to http://a/b/c/g" do - expect((@uri + "g").to_s).to eq("http://a/b/c/g") - expect(Addressable::URI.join(@uri.to_s, "g").to_s).to eq("http://a/b/c/g") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with './g' should resolve to http://a/b/c/g" do - expect((@uri + "./g").to_s).to eq("http://a/b/c/g") - expect(Addressable::URI.join(@uri.to_s, "./g").to_s).to eq("http://a/b/c/g") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g/' should resolve to http://a/b/c/g/" do - expect((@uri + "g/").to_s).to eq("http://a/b/c/g/") - expect(Addressable::URI.join(@uri.to_s, "g/").to_s).to eq("http://a/b/c/g/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '/g' should resolve to http://a/g" do - expect((@uri + "/g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "/g").to_s).to eq("http://a/g") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '//g' should resolve to http://g" do - expect((@uri + "//g").to_s).to eq("http://g") - expect(Addressable::URI.join(@uri.to_s, "//g").to_s).to eq("http://g") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '?y' should resolve to http://a/b/c/d;p?y" do - expect((@uri + "?y").to_s).to eq("http://a/b/c/d;p?y") - expect(Addressable::URI.join(@uri.to_s, "?y").to_s).to eq("http://a/b/c/d;p?y") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g?y' should resolve to http://a/b/c/g?y" do - expect((@uri + "g?y").to_s).to eq("http://a/b/c/g?y") - expect(Addressable::URI.join(@uri.to_s, "g?y").to_s).to eq("http://a/b/c/g?y") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '#s' should resolve to http://a/b/c/d;p?q#s" do - expect((@uri + "#s").to_s).to eq("http://a/b/c/d;p?q#s") - expect(Addressable::URI.join(@uri.to_s, "#s").to_s).to eq( - "http://a/b/c/d;p?q#s" - ) - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g#s' should resolve to http://a/b/c/g#s" do - expect((@uri + "g#s").to_s).to eq("http://a/b/c/g#s") - expect(Addressable::URI.join(@uri.to_s, "g#s").to_s).to eq("http://a/b/c/g#s") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g?y#s' should resolve to http://a/b/c/g?y#s" do - expect((@uri + "g?y#s").to_s).to eq("http://a/b/c/g?y#s") - expect(Addressable::URI.join( - @uri.to_s, "g?y#s").to_s).to eq("http://a/b/c/g?y#s") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with ';x' should resolve to http://a/b/c/;x" do - expect((@uri + ";x").to_s).to eq("http://a/b/c/;x") - expect(Addressable::URI.join(@uri.to_s, ";x").to_s).to eq("http://a/b/c/;x") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g;x' should resolve to http://a/b/c/g;x" do - expect((@uri + "g;x").to_s).to eq("http://a/b/c/g;x") - expect(Addressable::URI.join(@uri.to_s, "g;x").to_s).to eq("http://a/b/c/g;x") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with 'g;x?y#s' should resolve to http://a/b/c/g;x?y#s" do - expect((@uri + "g;x?y#s").to_s).to eq("http://a/b/c/g;x?y#s") - expect(Addressable::URI.join( - @uri.to_s, "g;x?y#s").to_s).to eq("http://a/b/c/g;x?y#s") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '' should resolve to http://a/b/c/d;p?q" do - expect((@uri + "").to_s).to eq("http://a/b/c/d;p?q") - expect(Addressable::URI.join(@uri.to_s, "").to_s).to eq("http://a/b/c/d;p?q") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '.' should resolve to http://a/b/c/" do - expect((@uri + ".").to_s).to eq("http://a/b/c/") - expect(Addressable::URI.join(@uri.to_s, ".").to_s).to eq("http://a/b/c/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with './' should resolve to http://a/b/c/" do - expect((@uri + "./").to_s).to eq("http://a/b/c/") - expect(Addressable::URI.join(@uri.to_s, "./").to_s).to eq("http://a/b/c/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '..' should resolve to http://a/b/" do - expect((@uri + "..").to_s).to eq("http://a/b/") - expect(Addressable::URI.join(@uri.to_s, "..").to_s).to eq("http://a/b/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '../' should resolve to http://a/b/" do - expect((@uri + "../").to_s).to eq("http://a/b/") - expect(Addressable::URI.join(@uri.to_s, "../").to_s).to eq("http://a/b/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '../g' should resolve to http://a/b/g" do - expect((@uri + "../g").to_s).to eq("http://a/b/g") - expect(Addressable::URI.join(@uri.to_s, "../g").to_s).to eq("http://a/b/g") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '../..' should resolve to http://a/" do - expect((@uri + "../..").to_s).to eq("http://a/") - expect(Addressable::URI.join(@uri.to_s, "../..").to_s).to eq("http://a/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '../../' should resolve to http://a/" do - expect((@uri + "../../").to_s).to eq("http://a/") - expect(Addressable::URI.join(@uri.to_s, "../../").to_s).to eq("http://a/") - end - - # Section 5.4.1 of RFC 3986 - it "when joined with '../../g' should resolve to http://a/g" do - expect((@uri + "../../g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "../../g").to_s).to eq("http://a/g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '../../../g' should resolve to http://a/g" do - expect((@uri + "../../../g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "../../../g").to_s).to eq("http://a/g") - end - - it "when joined with '../.././../g' should resolve to http://a/g" do - expect((@uri + "../.././../g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "../.././../g").to_s).to eq( - "http://a/g" - ) - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '../../../../g' should resolve to http://a/g" do - expect((@uri + "../../../../g").to_s).to eq("http://a/g") - expect(Addressable::URI.join( - @uri.to_s, "../../../../g").to_s).to eq("http://a/g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '/./g' should resolve to http://a/g" do - expect((@uri + "/./g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "/./g").to_s).to eq("http://a/g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '/../g' should resolve to http://a/g" do - expect((@uri + "/../g").to_s).to eq("http://a/g") - expect(Addressable::URI.join(@uri.to_s, "/../g").to_s).to eq("http://a/g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g.' should resolve to http://a/b/c/g." do - expect((@uri + "g.").to_s).to eq("http://a/b/c/g.") - expect(Addressable::URI.join(@uri.to_s, "g.").to_s).to eq("http://a/b/c/g.") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '.g' should resolve to http://a/b/c/.g" do - expect((@uri + ".g").to_s).to eq("http://a/b/c/.g") - expect(Addressable::URI.join(@uri.to_s, ".g").to_s).to eq("http://a/b/c/.g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g..' should resolve to http://a/b/c/g.." do - expect((@uri + "g..").to_s).to eq("http://a/b/c/g..") - expect(Addressable::URI.join(@uri.to_s, "g..").to_s).to eq("http://a/b/c/g..") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with '..g' should resolve to http://a/b/c/..g" do - expect((@uri + "..g").to_s).to eq("http://a/b/c/..g") - expect(Addressable::URI.join(@uri.to_s, "..g").to_s).to eq("http://a/b/c/..g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with './../g' should resolve to http://a/b/g" do - expect((@uri + "./../g").to_s).to eq("http://a/b/g") - expect(Addressable::URI.join(@uri.to_s, "./../g").to_s).to eq("http://a/b/g") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with './g/.' should resolve to http://a/b/c/g/" do - expect((@uri + "./g/.").to_s).to eq("http://a/b/c/g/") - expect(Addressable::URI.join(@uri.to_s, "./g/.").to_s).to eq("http://a/b/c/g/") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g/./h' should resolve to http://a/b/c/g/h" do - expect((@uri + "g/./h").to_s).to eq("http://a/b/c/g/h") - expect(Addressable::URI.join(@uri.to_s, "g/./h").to_s).to eq("http://a/b/c/g/h") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g/../h' should resolve to http://a/b/c/h" do - expect((@uri + "g/../h").to_s).to eq("http://a/b/c/h") - expect(Addressable::URI.join(@uri.to_s, "g/../h").to_s).to eq("http://a/b/c/h") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g;x=1/./y' " + - "should resolve to http://a/b/c/g;x=1/y" do - expect((@uri + "g;x=1/./y").to_s).to eq("http://a/b/c/g;x=1/y") - expect(Addressable::URI.join( - @uri.to_s, "g;x=1/./y").to_s).to eq("http://a/b/c/g;x=1/y") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g;x=1/../y' should resolve to http://a/b/c/y" do - expect((@uri + "g;x=1/../y").to_s).to eq("http://a/b/c/y") - expect(Addressable::URI.join( - @uri.to_s, "g;x=1/../y").to_s).to eq("http://a/b/c/y") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g?y/./x' " + - "should resolve to http://a/b/c/g?y/./x" do - expect((@uri + "g?y/./x").to_s).to eq("http://a/b/c/g?y/./x") - expect(Addressable::URI.join( - @uri.to_s, "g?y/./x").to_s).to eq("http://a/b/c/g?y/./x") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g?y/../x' " + - "should resolve to http://a/b/c/g?y/../x" do - expect((@uri + "g?y/../x").to_s).to eq("http://a/b/c/g?y/../x") - expect(Addressable::URI.join( - @uri.to_s, "g?y/../x").to_s).to eq("http://a/b/c/g?y/../x") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g#s/./x' " + - "should resolve to http://a/b/c/g#s/./x" do - expect((@uri + "g#s/./x").to_s).to eq("http://a/b/c/g#s/./x") - expect(Addressable::URI.join( - @uri.to_s, "g#s/./x").to_s).to eq("http://a/b/c/g#s/./x") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'g#s/../x' " + - "should resolve to http://a/b/c/g#s/../x" do - expect((@uri + "g#s/../x").to_s).to eq("http://a/b/c/g#s/../x") - expect(Addressable::URI.join( - @uri.to_s, "g#s/../x").to_s).to eq("http://a/b/c/g#s/../x") - end - - # Section 5.4.2 of RFC 3986 - it "when joined with 'http:g' should resolve to http:g" do - expect((@uri + "http:g").to_s).to eq("http:g") - expect(Addressable::URI.join(@uri.to_s, "http:g").to_s).to eq("http:g") - end - - # Edge case to be sure - it "when joined with '//example.com/' should " + - "resolve to http://example.com/" do - expect((@uri + "//example.com/").to_s).to eq("http://example.com/") - expect(Addressable::URI.join( - @uri.to_s, "//example.com/").to_s).to eq("http://example.com/") - end - - it "when joined with a bogus object a TypeError should be raised" do - expect do - Addressable::URI.join(@uri, 42) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when converting the path " + - "'relative/path/to/something'" do - before do - @path = 'relative/path/to/something' - end - - it "should convert to " + - "\'relative/path/to/something\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("relative/path/to/something") - end - - it "should join with an absolute file path correctly" do - @base = Addressable::URI.convert_path("/absolute/path/") - @uri = Addressable::URI.convert_path(@path) - expect((@base + @uri).to_str).to eq( - "file:///absolute/path/relative/path/to/something" - ) - end -end - -describe Addressable::URI, "when converting a bogus path" do - it "should raise a TypeError" do - expect do - Addressable::URI.convert_path(42) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when given a UNIX root directory" do - before do - @path = "/" - end - - it "should convert to \'file:///\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given a Windows root directory" do - before do - @path = "C:\\" - end - - it "should convert to \'file:///c:/\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the path '/one/two/'" do - before do - @path = '/one/two/' - end - - it "should convert to " + - "\'file:///one/two/\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///one/two/") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the tld " do - it "'uk' should have a tld of 'uk'" do - uri = Addressable::URI.parse("http://example.com") - uri.tld = "uk" - - expect(uri.tld).to eq("uk") - end - - context "which " do - let (:uri) { Addressable::URI.parse("http://www.comrade.net/path/to/source/") } - - it "contains a subdomain" do - uri.tld = "co.uk" - - expect(uri.to_s).to eq("http://www.comrade.co.uk/path/to/source/") - end - - it "is part of the domain" do - uri.tld = "com" - - expect(uri.to_s).to eq("http://www.comrade.com/path/to/source/") - end - end -end - -describe Addressable::URI, "when given the path " + - "'c:\\windows\\My Documents 100%20\\foo.txt'" do - before do - @path = "c:\\windows\\My Documents 100%20\\foo.txt" - end - - it "should convert to " + - "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the path " + - "'file://c:\\windows\\My Documents 100%20\\foo.txt'" do - before do - @path = "file://c:\\windows\\My Documents 100%20\\foo.txt" - end - - it "should convert to " + - "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the path " + - "'file:c:\\windows\\My Documents 100%20\\foo.txt'" do - before do - @path = "file:c:\\windows\\My Documents 100%20\\foo.txt" - end - - it "should convert to " + - "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the path " + - "'file:/c:\\windows\\My Documents 100%20\\foo.txt'" do - before do - @path = "file:/c:\\windows\\My Documents 100%20\\foo.txt" - end - - it "should convert to " + - "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given the path " + - "'file:///c|/windows/My%20Documents%20100%20/foo.txt'" do - before do - @path = "file:///c|/windows/My%20Documents%20100%20/foo.txt" - end - - it "should convert to " + - "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") - end - - it "should have an origin of 'file://'" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.origin).to eq('file://') - end -end - -describe Addressable::URI, "when given an http protocol URI" do - before do - @path = "http://example.com/" - end - - it "should not do any conversion at all" do - @uri = Addressable::URI.convert_path(@path) - expect(@uri.to_str).to eq("http://example.com/") - end -end - -class SuperString - def initialize(string) - @string = string.to_s - end - - def to_str - return @string - end -end - -describe Addressable::URI, "when parsing a non-String object" do - it "should correctly parse anything with a 'to_str' method" do - Addressable::URI.parse(SuperString.new(42)) - end - - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.parse(42) - end.to raise_error(TypeError) - end - - it "should correctly parse heuristically anything with a 'to_str' method" do - Addressable::URI.heuristic_parse(SuperString.new(42)) - end - - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.heuristic_parse(42) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when form encoding a hash" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.form_encode( - [["&one", "/1"], ["=two", "?2"], [":three", "#3"]] - )).to eq("%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.form_encode( - {"q" => "one two three"} - )).to eq("q=one+two+three") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.form_encode( - {"key" => nil} - )).to eq("key=") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.form_encode( - {"q" => ["one", "two", "three"]} - )).to eq("q=one&q=two&q=three") - end - - it "should result in correctly encoded newlines" do - expect(Addressable::URI.form_encode( - {"text" => "one\ntwo\rthree\r\nfour\n\r"} - )).to eq("text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A") - end - - it "should result in a sorted percent encoded sequence" do - expect(Addressable::URI.form_encode( - [["a", "1"], ["dup", "3"], ["dup", "2"]], true - )).to eq("a=1&dup=2&dup=3") - end -end - -describe Addressable::URI, "when form encoding a non-Array object" do - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.form_encode(42) - end.to raise_error(TypeError) - end -end - -# See https://tools.ietf.org/html/rfc6749#appendix-B -describe Addressable::URI, "when form encoding the example value from OAuth 2" do - it "should result in correct values" do - expect(Addressable::URI.form_encode( - {"value" => " %&+£€"} - )).to eq("value=+%25%26%2B%C2%A3%E2%82%AC") - end -end - -# See https://tools.ietf.org/html/rfc6749#appendix-B -describe Addressable::URI, "when form unencoding the example value from OAuth 2" do - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "value=+%25%26%2B%C2%A3%E2%82%AC" - )).to eq([["value", " %&+£€"]]) - end -end - -describe Addressable::URI, "when form unencoding a string" do - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233" - )).to eq([["&one", "/1"], ["=two", "?2"], [":three", "#3"]]) - end - - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "q=one+two+three" - )).to eq([["q", "one two three"]]) - end - - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A" - )).to eq([["text", "one\ntwo\nthree\nfour\n\n"]]) - end - - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "a=1&dup=2&dup=3" - )).to eq([["a", "1"], ["dup", "2"], ["dup", "3"]]) - end - - it "should result in correct values" do - expect(Addressable::URI.form_unencode( - "key" - )).to eq([["key", nil]]) - end - - it "should result in correct values" do - expect(Addressable::URI.form_unencode("GivenName=Ren%C3%A9")).to eq( - [["GivenName", "René"]] - ) - end -end - -describe Addressable::URI, "when form unencoding a non-String object" do - it "should correctly parse anything with a 'to_str' method" do - Addressable::URI.form_unencode(SuperString.new(42)) - end - - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.form_unencode(42) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when normalizing a non-String object" do - it "should correctly parse anything with a 'to_str' method" do - Addressable::URI.normalize_component(SuperString.new(42)) - end - - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.normalize_component(42) - end.to raise_error(TypeError) - end - - it "should raise a TypeError for objects than cannot be converted" do - expect do - Addressable::URI.normalize_component("component", 42) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when normalizing a path with an encoded slash" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.parse("/path%2Fsegment/").normalize.path).to eq( - "/path%2Fsegment/" - ) - end -end - -describe Addressable::URI, "when normalizing a path with special unicode" do - it "does not stop at or ignore null bytes" do - expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq( - "/path%00segment/" - ) - end - - it "does apply NFC unicode normalization" do - expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq( - "/%CE%A9" - ) - end - - it "does not apply NFKC unicode normalization" do - expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq( - "/%C2%AF%C2%A0" - ) - end -end - -describe Addressable::URI, "when normalizing a partially encoded string" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component( - "partially % encoded%21" - )).to eq("partially%20%25%20encoded!") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component( - "partially %25 encoded!" - )).to eq("partially%20%25%20encoded!") - end -end - -describe Addressable::URI, "when normalizing a unicode sequence" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component( - "/C%CC%A7" - )).to eq("/%C3%87") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component( - "/%C3%87" - )).to eq("/%C3%87") - end -end - -describe Addressable::URI, "when normalizing a multibyte string" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component("günther")).to eq( - "g%C3%BCnther" - ) - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component("g%C3%BCnther")).to eq( - "g%C3%BCnther" - ) - end -end - -describe Addressable::URI, "when normalizing a string but leaving some characters encoded" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.normalize_component("%58X%59Y%5AZ", "0-9a-zXY", "Y")).to eq( - "XX%59Y%5A%5A" - ) - end - - it "should not modify the character class" do - character_class = "0-9a-zXY" - - character_class_copy = character_class.dup - - Addressable::URI.normalize_component("%58X%59Y%5AZ", character_class, "Y") - - expect(character_class).to eq(character_class_copy) - end -end - -describe Addressable::URI, "when encoding IP literals" do - it "should work for IPv4" do - input = "http://127.0.0.1/" - expect(Addressable::URI.encode(input)).to eq(input) - end - - it "should work for IPv6" do - input = "http://[fe80::200:f8ff:fe21:67cf]/" - expect(Addressable::URI.encode(input)).to eq(input) - end -end - -describe Addressable::URI, "when encoding a string with existing encodings to upcase" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.encode_component("JK%4c", "0-9A-IKM-Za-z%", "L")).to eq("%4AK%4C") - end -end - -describe Addressable::URI, "when encoding a multibyte string" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.encode_component("günther")).to eq("g%C3%BCnther") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.encode_component( - "günther", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/ - )).to eq("g%C3%BCnther") - end -end - -describe Addressable::URI, "when form encoding a multibyte string" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.form_encode({"GivenName" => "René"})).to eq( - "GivenName=Ren%C3%A9" - ) - end -end - -describe Addressable::URI, "when encoding a string with ASCII chars 0-15" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.encode_component("one\ntwo")).to eq("one%0Atwo") - end - - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.encode_component( - "one\ntwo", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/ - )).to eq("one%0Atwo") - end -end - -describe Addressable::URI, "when unencoding a multibyte string" do - it "should result in correct percent encoded sequence" do - expect(Addressable::URI.unencode_component("g%C3%BCnther")).to eq("günther") - end - - it "should consistently use UTF-8 internally" do - expect(Addressable::URI.unencode_component("ski=%BA%DAɫ")).to eq("ski=\xBA\xDAɫ") - end - - it "should not fail with UTF-8 incompatible string" do - url = "/M%E9/\xE9?p=\xFC".b - expect(Addressable::URI.unencode_component(url)).to eq("/M\xE9/\xE9?p=\xFC") - end - - it "should result in correct percent encoded sequence as a URI" do - expect(Addressable::URI.unencode( - "/path?g%C3%BCnther", ::Addressable::URI - )).to eq(Addressable::URI.new( - :path => "/path", :query => "günther" - )) - end -end - -describe Addressable::URI, "when partially unencoding a string" do - it "should unencode all characters by default" do - expect(Addressable::URI.unencode('%%25~%7e+%2b', String)).to eq('%%~~++') - end - - it "should unencode characters not in leave_encoded" do - expect(Addressable::URI.unencode('%%25~%7e+%2b', String, '~')).to eq('%%~%7e++') - end - - it "should leave characters in leave_encoded alone" do - expect(Addressable::URI.unencode('%%25~%7e+%2b', String, '%~+')).to eq('%%25~%7e+%2b') - end -end - -describe Addressable::URI, "when unencoding a bogus object" do - it "should raise a TypeError" do - expect do - Addressable::URI.unencode_component(42) - end.to raise_error(TypeError) - end - - it "should raise a TypeError" do - expect do - Addressable::URI.unencode("/path?g%C3%BCnther", Integer) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when encoding a bogus object" do - it "should raise a TypeError" do - expect do - Addressable::URI.encode(Object.new) - end.to raise_error(TypeError) - end - - it "should raise a TypeError" do - expect do - Addressable::URI.normalized_encode(Object.new) - end.to raise_error(TypeError) - end - - it "should raise a TypeError" do - expect do - Addressable::URI.encode_component("günther", Object.new) - end.to raise_error(TypeError) - end - - it "should raise a TypeError" do - expect do - Addressable::URI.encode_component(Object.new) - end.to raise_error(TypeError) - end -end - -describe Addressable::URI, "when given the input " + - "'http://example.com/'" do - before do - @input = "http://example.com/" - end - - it "should heuristically parse to 'http://example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com/") - end - - it "should not raise error when frozen" do - expect do - Addressable::URI.heuristic_parse(@input).freeze.to_s - end.not_to raise_error - end -end - -describe Addressable::URI, "when given the input " + - "'https://example.com/'" do - before do - @input = "https://example.com/" - end - - it "should heuristically parse to 'https://example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("https://example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'http:example.com/'" do - before do - @input = "http:example.com/" - end - - it "should heuristically parse to 'http://example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com/") - end - - it "should heuristically parse to 'http://example.com/' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'https:example.com/'" do - before do - @input = "https:example.com/" - end - - it "should heuristically parse to 'https://example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("https://example.com/") - end - - it "should heuristically parse to 'https://example.com/' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("https://example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'http://example.com/example.com/'" do - before do - @input = "http://example.com/example.com/" - end - - it "should heuristically parse to 'http://example.com/example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com/example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'http://prefix\\.example.com/'" do - before do - @input = "http://prefix\\.example.com/" - end - - it "should heuristically parse to 'http://prefix/.example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("prefix") - expect(@uri.to_s).to eq("http://prefix/.example.com/") - end - - it "should heuristically parse to 'http://prefix/.example.com/' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://prefix/.example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'http://p:\\/'" do - before do - @input = "http://p:\\/" - end - - it "should heuristically parse to 'http://p//'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("p") - expect(@uri.to_s).to eq("http://p//") - end - - it "should heuristically parse to 'http://p//' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://p//") - end -end - -describe Addressable::URI, "when given the input " + - "'http://p://'" do - before do - @input = "http://p://" - end - - it "should heuristically parse to 'http://p//'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("p") - expect(@uri.to_s).to eq("http://p//") - end - - it "should heuristically parse to 'http://p//' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://p//") - end -end - -describe Addressable::URI, "when given the input " + - "'http://p://p'" do - before do - @input = "http://p://p" - end - - it "should heuristically parse to 'http://p//p'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("p") - expect(@uri.to_s).to eq("http://p//p") - end - - it "should heuristically parse to 'http://p//p' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://p//p") - end -end - -describe Addressable::URI, "when given the input " + - "'http://prefix .example.com/'" do - before do - @input = "http://prefix .example.com/" - end - - # Justification here being that no browser actually tries to resolve this. - # They all treat this as a web search. - it "should heuristically parse to 'http://prefix%20.example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("prefix%20.example.com") - expect(@uri.to_s).to eq("http://prefix%20.example.com/") - end - - it "should heuristically parse to 'http://prefix%20.example.com/' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://prefix%20.example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "' http://www.example.com/ '" do - before do - @input = " http://www.example.com/ " - end - - it "should heuristically parse to 'http://prefix%20.example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.scheme).to eq("http") - expect(@uri.path).to eq("/") - expect(@uri.to_s).to eq("http://www.example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'http://prefix%2F.example.com/'" do - before do - @input = "http://prefix%2F.example.com/" - end - - it "should heuristically parse to 'http://prefix%2F.example.com/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.authority).to eq("prefix%2F.example.com") - expect(@uri.to_s).to eq("http://prefix%2F.example.com/") - end - - it "should heuristically parse to 'http://prefix%2F.example.com/' " + - "even with a scheme hint of 'ftp'" do - @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) - expect(@uri.to_s).to eq("http://prefix%2F.example.com/") - end -end - -describe Addressable::URI, "when given the input " + - "'/path/to/resource'" do - before do - @input = "/path/to/resource" - end - - it "should heuristically parse to '/path/to/resource'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("/path/to/resource") - end -end - -describe Addressable::URI, "when given the input " + - "'relative/path/to/resource'" do - before do - @input = "relative/path/to/resource" - end - - it "should heuristically parse to 'relative/path/to/resource'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("relative/path/to/resource") - end -end - -describe Addressable::URI, "when given the input " + - "'example.com'" do - before do - @input = "example.com" - end - - it "should heuristically parse to 'http://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com") - end -end - -describe Addressable::URI, "when given the input " + - "'example.com' and a scheme hint of 'ftp'" do - before do - @input = "example.com" - @hints = {:scheme => 'ftp'} - end - - it "should heuristically parse to 'http://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input, @hints) - expect(@uri.to_s).to eq("ftp://example.com") - end -end - -describe Addressable::URI, "when given the input " + - "'example.com:21' and a scheme hint of 'ftp'" do - before do - @input = "example.com:21" - @hints = {:scheme => 'ftp'} - end - - it "should heuristically parse to 'http://example.com:21'" do - @uri = Addressable::URI.heuristic_parse(@input, @hints) - expect(@uri.to_s).to eq("ftp://example.com:21") - end -end - -describe Addressable::URI, "when given the input " + - "'example.com/path/to/resource'" do - before do - @input = "example.com/path/to/resource" - end - - it "should heuristically parse to 'http://example.com/path/to/resource'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com/path/to/resource") - end -end - -describe Addressable::URI, "when given the input " + - "'http:///example.com'" do - before do - @input = "http:///example.com" - end - - it "should heuristically parse to 'http://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com") - end -end - -describe Addressable::URI, "when given the input which "\ - "start with digits and has specified port" do - before do - @input = "7777.example.org:8089" - end - - it "should heuristically parse to 'http://7777.example.org:8089'" do - uri = Addressable::URI.heuristic_parse(@input) - expect(uri.to_s).to eq("http://7777.example.org:8089") - end -end - -describe Addressable::URI, "when given the input " + - "'feed:///example.com'" do - before do - @input = "feed:///example.com" - end - - it "should heuristically parse to 'feed://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("feed://example.com") - end -end - -describe Addressable::URI, "when given the input " + - "'file://localhost/path/to/resource/'" do - before do - @input = "file://localhost/path/to/resource/" - end - - it "should heuristically parse to 'file:///path/to/resource/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("file:///path/to/resource/") - end -end - -describe Addressable::URI, "when given the input " + - "'file://path/to/resource/'" do - before do - @input = "file://path/to/resource/" - end - - it "should heuristically parse to 'file:///path/to/resource/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("file:///path/to/resource/") - end -end - -describe Addressable::URI, "when given the input " + - "'file://///path/to/resource/'" do - before do - @input = "file:///////path/to/resource/" - end - - it "should heuristically parse to 'file:////path/to/resource/'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("file:////path/to/resource/") - end -end - -describe Addressable::URI, "when given the input " + - "'feed://http://example.com'" do - before do - @input = "feed://http://example.com" - end - - it "should heuristically parse to 'feed:http://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("feed:http://example.com") - end -end - -describe Addressable::URI, "when given the input " + - "::URI.parse('http://example.com')" do - before do - @input = ::URI.parse('http://example.com') - end - - it "should heuristically parse to 'http://example.com'" do - @uri = Addressable::URI.heuristic_parse(@input) - expect(@uri.to_s).to eq("http://example.com") - end -end - -describe Addressable::URI, "when given the input: 'user@domain.com'" do - before do - @input = "user@domain.com" - end - - context "for heuristic parse" do - it "should remain 'mailto:user@domain.com'" do - uri = Addressable::URI.heuristic_parse("mailto:#{@input}") - expect(uri.to_s).to eq("mailto:user@domain.com") - end - - it "should have a scheme of 'mailto'" do - uri = Addressable::URI.heuristic_parse(@input) - expect(uri.to_s).to eq("mailto:user@domain.com") - expect(uri.scheme).to eq("mailto") - end - - it "should remain 'acct:user@domain.com'" do - uri = Addressable::URI.heuristic_parse("acct:#{@input}") - expect(uri.to_s).to eq("acct:user@domain.com") - end - - context "HTTP" do - before do - @uri = Addressable::URI.heuristic_parse("http://#{@input}/") - end - - it "should remain 'http://user@domain.com/'" do - expect(@uri.to_s).to eq("http://user@domain.com/") - end - - it "should have the username 'user' for HTTP basic authentication" do - expect(@uri.user).to eq("user") - end - end - end -end - -describe Addressable::URI, "when assigning query values" do - before do - @uri = Addressable::URI.new - end - - it "should correctly assign {:a => 'a', :b => ['c', 'd', 'e']}" do - @uri.query_values = {:a => "a", :b => ["c", "d", "e"]} - expect(@uri.query).to eq("a=a&b=c&b=d&b=e") - end - - it "should raise an error attempting to assign {'a' => {'b' => ['c']}}" do - expect do - @uri.query_values = { 'a' => {'b' => ['c'] } } - end.to raise_error(TypeError) - end - - it "should raise an error attempting to assign " + - "{:b => '2', :a => {:c => '1'}}" do - expect do - @uri.query_values = {:b => '2', :a => {:c => '1'}} - end.to raise_error(TypeError) - end - - it "should raise an error attempting to assign " + - "{:a => 'a', :b => [{:c => 'c', :d => 'd'}, " + - "{:e => 'e', :f => 'f'}]}" do - expect do - @uri.query_values = { - :a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}] - } - end.to raise_error(TypeError) - end - - it "should raise an error attempting to assign " + - "{:a => 'a', :b => [{:c => true, :d => 'd'}, " + - "{:e => 'e', :f => 'f'}]}" do - expect do - @uri.query_values = { - :a => 'a', :b => [{:c => true, :d => 'd'}, {:e => 'e', :f => 'f'}] - } - end.to raise_error(TypeError) - end - - it "should raise an error attempting to assign " + - "{:a => 'a', :b => {:c => true, :d => 'd'}}" do - expect do - @uri.query_values = { - :a => 'a', :b => {:c => true, :d => 'd'} - } - end.to raise_error(TypeError) - end - - it "should raise an error attempting to assign " + - "{:a => 'a', :b => {:c => true, :d => 'd'}}" do - expect do - @uri.query_values = { - :a => 'a', :b => {:c => true, :d => 'd'} - } - end.to raise_error(TypeError) - end - - it "should correctly assign {:a => 1, :b => 1.5}" do - @uri.query_values = { :a => 1, :b => 1.5 } - expect(@uri.query).to eq("a=1&b=1.5") - end - - it "should raise an error attempting to assign " + - "{:z => 1, :f => [2, {999.1 => [3,'4']}, ['h', 'i']], " + - ":a => {:b => ['c', 'd'], :e => true, :y => 0.5}}" do - expect do - @uri.query_values = { - :z => 1, - :f => [ 2, {999.1 => [3,'4']}, ['h', 'i'] ], - :a => { :b => ['c', 'd'], :e => true, :y => 0.5 } - } - end.to raise_error(TypeError) - end - - it "should correctly assign {}" do - @uri.query_values = {} - expect(@uri.query).to eq('') - end - - it "should correctly assign nil" do - @uri.query_values = nil - expect(@uri.query).to eq(nil) - end - - it "should correctly sort {'ab' => 'c', :ab => 'a', :a => 'x'}" do - @uri.query_values = {'ab' => 'c', :ab => 'a', :a => 'x'} - expect(@uri.query).to eq("a=x&ab=a&ab=c") - end - - it "should correctly assign " + - "[['b', 'c'], ['b', 'a'], ['a', 'a']]" do - # Order can be guaranteed in this format, so preserve it. - @uri.query_values = [['b', 'c'], ['b', 'a'], ['a', 'a']] - expect(@uri.query).to eq("b=c&b=a&a=a") - end - - it "should preserve query string order" do - query_string = (('a'..'z').to_a.reverse.map { |e| "#{e}=#{e}" }).join("&") - @uri.query = query_string - original_uri = @uri.to_s - @uri.query_values = @uri.query_values(Array) - expect(@uri.to_s).to eq(original_uri) - end - - describe 'when a hash with mixed types is assigned to query_values' do - it 'should not raise an error' do - skip 'Issue #94' - expect { subject.query_values = { "page" => "1", :page => 2 } }.to_not raise_error - end - end -end - -describe Addressable::URI, "when assigning path values" do - before do - @uri = Addressable::URI.new - end - - it "should correctly assign paths containing colons" do - @uri.path = "acct:bob@sporkmonger.com" - expect(@uri.path).to eq("acct:bob@sporkmonger.com") - expect(@uri.normalize.to_str).to eq("acct%2Fbob@sporkmonger.com") - expect { @uri.to_s }.to raise_error( - Addressable::URI::InvalidURIError - ) - end - - it "should correctly assign paths containing colons" do - @uri.path = "/acct:bob@sporkmonger.com" - @uri.authority = "example.com" - expect(@uri.normalize.to_str).to eq("//example.com/acct:bob@sporkmonger.com") - end - - it "should correctly assign paths containing colons" do - @uri.path = "acct:bob@sporkmonger.com" - @uri.scheme = "something" - expect(@uri.normalize.to_str).to eq("something:acct:bob@sporkmonger.com") - end - - it "should not allow relative paths to be assigned on absolute URIs" do - expect do - @uri.scheme = "http" - @uri.host = "example.com" - @uri.path = "acct:bob@sporkmonger.com" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should not allow relative paths to be assigned on absolute URIs" do - expect do - @uri.path = "acct:bob@sporkmonger.com" - @uri.scheme = "http" - @uri.host = "example.com" - end.to raise_error(Addressable::URI::InvalidURIError) - end - - it "should not allow relative paths to be assigned on absolute URIs" do - expect do - @uri.path = "uuid:0b3ecf60-3f93-11df-a9c3-001f5bfffe12" - @uri.scheme = "urn" - end.not_to raise_error - end -end - -describe Addressable::URI, "when initializing a subclass of Addressable::URI" do - before do - @uri = Class.new(Addressable::URI).new - end - - it "should have the same class after being parsed" do - expect(@uri.class).to eq(Addressable::URI.parse(@uri).class) - end - - it "should have the same class as its duplicate" do - expect(@uri.class).to eq(@uri.dup.class) - end - - it "should have the same class after being normalized" do - expect(@uri.class).to eq(@uri.normalize.class) - end - - it "should have the same class after being merged" do - expect(@uri.class).to eq(@uri.merge(:path => 'path').class) - end - - it "should have the same class after being joined" do - expect(@uri.class).to eq(@uri.join('path').class) - end -end - -describe Addressable::URI, "support serialization roundtrip" do - before do - @uri = Addressable::URI.new( - :scheme => "http", - :user => "user", - :password => "password", - :host => "example.com", - :port => 80, - :path => "/path", - :query => "query=value", - :fragment => "fragment" - ) - end - - it "is in a working state after being serialized with Marshal" do - @uri = Addressable::URI.parse("http://example.com") - cloned_uri = Marshal.load(Marshal.dump(@uri)) - expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme - end - - it "is in a working state after being serialized with YAML" do - @uri = Addressable::URI.parse("http://example.com") - cloned_uri = if YAML.respond_to?(:unsafe_load) - YAML.unsafe_load(YAML.dump(@uri)) - else - YAML.load(YAML.dump(@uri)) - end - expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme - end -end - -describe Addressable::URI, "when initialized in a non-main `Ractor`" do - it "should have the same value as if used in the main `Ractor`" do - pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor) - main = Addressable::URI.parse("http://example.com") - expect( - Ractor.new { Addressable::URI.parse("http://example.com") }.take - ).to eq(main) - end -end - -describe Addressable::URI, "when deferring validation" do - subject(:deferred) { uri.instance_variable_get(:@validation_deferred) } - - let(:uri) { Addressable::URI.parse("http://example.com") } - - it "defers validation within the block" do - uri.defer_validation do - expect(deferred).to be true - end - end - - it "always resets deferral afterward" do - expect { uri.defer_validation { raise "boom" } }.to raise_error("boom") - expect(deferred).to be false - end - - it "returns nil" do - res = uri.defer_validation {} - expect(res).to be nil - end -end - -describe Addressable::URI, "YAML safe loading" do - it "doesn't serialize anonymous objects" do - url = Addressable::URI.parse("http://example.com/") - expect(YAML.dump(url)).to_not include("!ruby/object {}") - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/spec_helper.rb b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/spec_helper.rb deleted file mode 100644 index bd8e395..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/spec/spec_helper.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require 'bundler/setup' -require 'rspec/its' - -begin - require 'coveralls' - Coveralls.wear! do - add_filter "spec/" - add_filter "vendor/" - end -rescue LoadError - warn "warning: coveralls gem not found; skipping Coveralls" - require 'simplecov' - SimpleCov.start do - add_filter "spec/" - add_filter "vendor/" - end -end if Gem.loaded_specs.key?("simplecov") - -class TestHelper - def self.native_supported? - mri = RUBY_ENGINE == "ruby" - windows = RUBY_PLATFORM.include?("mingw") - - mri && !windows - end -end - -RSpec.configure do |config| - config.warnings = true - config.filter_run_when_matching :focus -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/clobber.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/clobber.rake deleted file mode 100644 index a9e32b3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/clobber.rake +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -desc "Remove all build products" -task "clobber" diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/gem.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/gem.rake deleted file mode 100644 index 70b1f97..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/gem.rake +++ /dev/null @@ -1,95 +0,0 @@ -# frozen_string_literal: true - -require "rubygems/package_task" - -namespace :gem do - GEM_SPEC = Gem::Specification.new do |s| - s.name = PKG_NAME - s.version = PKG_VERSION - s.summary = PKG_SUMMARY - s.description = PKG_DESCRIPTION - - s.files = PKG_FILES.to_a - - s.extra_rdoc_files = %w( README.md ) - s.rdoc_options.concat ["--main", "README.md"] - - if !s.respond_to?(:add_development_dependency) - puts "Cannot build Gem with this version of RubyGems." - exit(1) - end - - s.required_ruby_version = ">= 2.2" - - s.add_runtime_dependency "public_suffix", ">= 2.0.2", "< 7.0" - s.add_development_dependency "bundler", ">= 1.0", "< 3.0" - - s.require_path = "lib" - - s.author = "Bob Aman" - s.email = "bob@sporkmonger.com" - s.homepage = "https://github.com/sporkmonger/addressable" - s.license = "Apache-2.0" - s.metadata = { - "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v#{PKG_VERSION}" - } - end - - Gem::PackageTask.new(GEM_SPEC) do |p| - p.gem_spec = GEM_SPEC - p.need_tar = true - p.need_zip = true - end - - desc "Generates .gemspec file" - task :gemspec do - spec_string = GEM_SPEC.to_ruby - File.open("#{GEM_SPEC.name}.gemspec", "w") do |file| - file.write spec_string - end - end - - desc "Show information about the gem" - task :debug do - puts GEM_SPEC.to_ruby - end - - desc "Install the gem" - task :install => ["clobber", "gem:package"] do - sh "gem install --local ./pkg/#{GEM_SPEC.full_name}.gem" - end - - desc "Uninstall the gem" - task :uninstall do - installed_list = Gem.source_index.find_name(PKG_NAME) - if installed_list && - (installed_list.collect { |s| s.version.to_s}.include?(PKG_VERSION)) - sh( - "gem uninstall --version '#{PKG_VERSION}' " + - "--ignore-dependencies --executables #{PKG_NAME}" - ) - end - end - - desc "Reinstall the gem" - task :reinstall => [:uninstall, :install] - - desc "Package for release" - task :release => ["gem:package", "gem:gemspec"] do |t| - v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" - abort "Versions don't match #{v} vs #{PROJ.version}" if v != PKG_VERSION - pkg = "pkg/#{GEM_SPEC.full_name}" - - changelog = File.open("CHANGELOG.md") { |file| file.read } - - puts "Releasing #{PKG_NAME} v. #{PKG_VERSION}" - Rake::Task["git:tag:create"].invoke - end -end - -desc "Alias to gem:package" -task "gem" => "gem:package" - -task "gem:release" => "gem:gemspec" - -task "clobber" => ["gem:clobber_package"] diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/git.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/git.rake deleted file mode 100644 index 1238c8d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/git.rake +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -namespace :git do - namespace :tag do - desc "List tags from the Git repository" - task :list do - tags = `git tag -l` - tags.gsub!("\r", "") - tags = tags.split("\n").sort {|a, b| b <=> a } - puts tags.join("\n") - end - - desc "Create a new tag in the Git repository" - task :create do - changelog = File.open("CHANGELOG.md", "r") { |file| file.read } - puts "-" * 80 - puts changelog - puts "-" * 80 - puts - - v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" - abort "Versions don't match #{v} vs #{PKG_VERSION}" if v != PKG_VERSION - - git_status = `git status` - if git_status !~ /^nothing to commit/ - abort "Working directory isn't clean." - end - - tag = "#{PKG_NAME}-#{PKG_VERSION}" - msg = "Release #{PKG_NAME}-#{PKG_VERSION}" - - existing_tags = `git tag -l #{PKG_NAME}-*`.split('\n') - if existing_tags.include?(tag) - warn("Tag already exists, deleting...") - unless system "git tag -d #{tag}" - abort "Tag deletion failed." - end - end - puts "Creating git tag '#{tag}'..." - unless system "git tag -a -m \"#{msg}\" #{tag}" - abort "Tag creation failed." - end - end - end -end - -task "gem:release" => "git:tag:create" diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/metrics.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/metrics.rake deleted file mode 100644 index 107cc24..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/metrics.rake +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -namespace :metrics do - task :lines do - lines, codelines, total_lines, total_codelines = 0, 0, 0, 0 - for file_name in FileList["lib/**/*.rb"] - f = File.open(file_name) - while line = f.gets - lines += 1 - next if line =~ /^\s*$/ - next if line =~ /^\s*#/ - codelines += 1 - end - puts "L: #{sprintf("%4d", lines)}, " + - "LOC #{sprintf("%4d", codelines)} | #{file_name}" - total_lines += lines - total_codelines += codelines - - lines, codelines = 0, 0 - end - - puts "Total: Lines #{total_lines}, LOC #{total_codelines}" - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/profile.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/profile.rake deleted file mode 100644 index b697d48..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/profile.rake +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -namespace :profile do - desc "Profile Template match memory allocations" - task :template_match_memory do - require "memory_profiler" - require "addressable/template" - - start_at = Time.now.to_f - template = Addressable::Template.new("http://example.com/{?one,two,three}") - report = MemoryProfiler.report do - 30_000.times do - template.match( - "http://example.com/?one=one&two=floo&three=me" - ) - end - end - end_at = Time.now.to_f - print_options = { scale_bytes: true, normalize_paths: true } - puts "\n\n" - - if ENV["CI"] - report.pretty_print(print_options) - else - t_allocated = report.scale_bytes(report.total_allocated_memsize) - t_retained = report.scale_bytes(report.total_retained_memsize) - - puts "Total allocated: #{t_allocated} (#{report.total_allocated} objects)" - puts "Total retained: #{t_retained} (#{report.total_retained} objects)" - puts "Took #{end_at - start_at} seconds" - - FileUtils.mkdir_p("tmp") - report.pretty_print(to_file: "tmp/memprof.txt", **print_options) - end - end - - desc "Profile URI parse memory allocations" - task :memory do - require "memory_profiler" - require "addressable/uri" - if ENV["IDNA_MODE"] == "pure" - Addressable.send(:remove_const, :IDNA) - load "addressable/idna/pure.rb" - end - - start_at = Time.now.to_f - report = MemoryProfiler.report do - 30_000.times do - Addressable::URI.parse( - "http://google.com/stuff/../?with_lots=of¶ms=asdff#!stuff" - ).normalize - end - end - end_at = Time.now.to_f - print_options = { scale_bytes: true, normalize_paths: true } - puts "\n\n" - - if ENV["CI"] - report.pretty_print(**print_options) - else - t_allocated = report.scale_bytes(report.total_allocated_memsize) - t_retained = report.scale_bytes(report.total_retained_memsize) - - puts "Total allocated: #{t_allocated} (#{report.total_allocated} objects)" - puts "Total retained: #{t_retained} (#{report.total_retained} objects)" - puts "Took #{end_at - start_at} seconds" - - FileUtils.mkdir_p("tmp") - report.pretty_print(to_file: "tmp/memprof.txt", **print_options) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/rspec.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/rspec.rake deleted file mode 100644 index e3d9f01..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/rspec.rake +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require "rspec/core/rake_task" - -namespace :spec do - RSpec::Core::RakeTask.new(:simplecov) do |t| - t.pattern = FileList['spec/**/*_spec.rb'] - t.rspec_opts = %w[--color --format documentation] unless ENV["CI"] - end - - namespace :simplecov do - desc "Browse the code coverage report." - task :browse => "spec:simplecov" do - require "launchy" - Launchy.open("coverage/index.html") - end - end -end - -desc "Alias to spec:simplecov" -task "spec" => "spec:simplecov" - -task "clobber" => ["spec:clobber_simplecov"] diff --git a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/yard.rake b/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/yard.rake deleted file mode 100644 index 515f960..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/addressable-2.8.7/tasks/yard.rake +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "rake" - -begin - require "yard" - require "yard/rake/yardoc_task" - - namespace :doc do - desc "Generate Yardoc documentation" - YARD::Rake::YardocTask.new do |yardoc| - yardoc.name = "yard" - yardoc.options = ["--verbose", "--markup", "markdown"] - yardoc.files = FileList[ - "lib/**/*.rb", "ext/**/*.c", - "README.md", "CHANGELOG.md", "LICENSE.txt" - ].exclude(/idna/) - end - end - - task "clobber" => ["doc:clobber_yard"] - - desc "Alias to doc:yard" - task "doc" => "doc:yard" -rescue LoadError - # If yard isn't available, it's not the end of the world - desc "Alias to doc:rdoc" - task "doc" => "doc:rdoc" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Gemfile b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Gemfile deleted file mode 100644 index 044fba3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Gemfile +++ /dev/null @@ -1,11 +0,0 @@ -source "https://rubygems.org" -gemspec - -gem "rake" -group :development do - gem "rspec-helpers", :require => false - gem "luna-rspec-formatters", :require => false - gem "pry", :require => false unless ENV[ - "CI" - ] -end diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/History.markdown b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/History.markdown deleted file mode 100644 index bac4270..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/History.markdown +++ /dev/null @@ -1,25 +0,0 @@ -## 1.1.0 / 2016-06-28 - -### Minor Enhancements - -* Support jruby (#8) - -## 1.0.0 / 2016-04-28 - -### Major enhancements - -- Merge Simple::ANSI and Colorator. (#7) - -### Minor Enhancements - -- Delete unnecessary `Symbol#to_sym` (#2) -- Change argument name of `Enumerator#each` for better code legibility (#3) - -### Development Fixes - -- Convert to new RSpec expectation syntax (#1) -- Fix `String#blue` result in README (#4) - -## 0.1 / 2013-04-13 - -Birthday! diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/LICENSE b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/LICENSE deleted file mode 100644 index b3b6be9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) Parker Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/README.markdown b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/README.markdown deleted file mode 100644 index 9cf886d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/README.markdown +++ /dev/null @@ -1,47 +0,0 @@ -# colorator - -Colorize your text for the terminal - -[![Build Status](https://travis-ci.org/octopress/colorator.png?branch=master)](https://travis-ci.org/octopress/colorator) - -## Example - -```ruby -"this string".red -# => \e[31mthis string\e[0m -"my string".blue -# => \e[34mmy string\e[0m -# etc... -``` - -## Supported Colors - -- `red` -- `black` -- `green` -- `yellow` -- `magenta` -- `white` -- `blue` -- `cyan` -- `bold` - -## Other supported Ansi methods - -- `clear_line` -- `has_ansi?`, `has_color?` -- `strip_ansi`, `strip_color` -- `reset_ansi`, `reset_color` -- `clear_screen` -- `ansi_jump` - -## Why - -There are a bunch of gems that provide functionality like this, but none have -as simple an API as this. Just call `"string".color` and your text will be -colorized. - -## License - -MIT. Written as a single Ruby file by Brandon Mathis, converted into a gem by -Parker Moore. diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Rakefile b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Rakefile deleted file mode 100644 index b7e9ed5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" - -RSpec::Core::RakeTask.new(:spec) - -task :default => :spec diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/colorator.gemspec b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/colorator.gemspec deleted file mode 100644 index a4bd0cd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/colorator.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -# coding: utf-8 - -require File.expand_path('lib/colorator.rb', __dir__) - -Gem::Specification.new do |spec| - spec.name = "colorator" - spec.summary = "Colorize your text in the terminal." - spec.version = Colorator::VERSION - spec.authors = ["Parker Moore", "Brandon Mathis"] - spec.email = ["parkrmoore@gmail.com", "brandon@imathis.com"] - spec.homepage = "https://github.com/octopress/colorator" - spec.licenses = ["MIT"] - - all = `git ls-files -z`.split("\x0").reject { |f| f.start_with?(".") } - spec.files = all.select { |f| File.basename(f) == f || f =~ %r{^(bin|lib)/} } - spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } - spec.require_paths = ["lib"] - - spec.extra_rdoc_files = ["README.markdown", "LICENSE"] - spec.rdoc_options = ["--charset=UTF-8"] - - spec.add_development_dependency "rspec", "~> 3.1" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator.rb b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator.rb deleted file mode 100644 index 107f6e3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator.rb +++ /dev/null @@ -1,111 +0,0 @@ -$:.unshift File.dirname(__FILE__) - -module Colorator - module_function - VERSION = "1.1.0" - - # -------------------------------------------------------------------------- - - ANSI_MATCHR = /\x1b.*?[jkmsuABGKH]/ - ANSI_COLORS = { - :black => 30, - :red => 31, - :green => 32, - :yellow => 33, - :blue => 34, - :magenta => 35, - :cyan => 36, - :white => 37, - :bold => 1 - } - - # -------------------------------------------------------------------------- - # Allows you to check if a string currently has ansi. - # -------------------------------------------------------------------------- - - def has_ansi?(str) - str.match(ANSI_MATCHR).is_a?( - MatchData - ) - end - - # -------------------------------------------------------------------------- - # Jump the cursor, moving it up and then back down to it's spot, allowing - # you to do fancy things like multiple output (downloads) the way that Docker - # does them in an async way without breaking term. - # -------------------------------------------------------------------------- - - def ansi_jump(str, num) - "\x1b[#{num}A#{clear_line(str)}\x1b[#{ - num - }B" - end - - # -------------------------------------------------------------------------- - - def reset_ansi(str = "") - "\x1b[0m#{ - str - }" - end - - # -------------------------------------------------------------------------- - - def clear_line(str = "") - "\x1b[2K\r#{ - str - }" - end - - # -------------------------------------------------------------------------- - # Strip ANSI from the current string, making it just a normal string. - # -------------------------------------------------------------------------- - - def strip_ansi(str) - str.gsub( - ANSI_MATCHR, "" - ) - end - - # -------------------------------------------------------------------------- - # Clear the screen's current view, so the user gets a clean output. - # -------------------------------------------------------------------------- - - def clear_screen(str = "") - "\x1b[H\x1b[2J#{ - str - }" - end - - # -------------------------------------------------------------------------- - - def colorize(str = "", color) - "\x1b[#{color}m#{str}\x1b[0m" - end - - # -------------------------------------------------------------------------- - - Colorator::ANSI_COLORS.each do |color, code| - define_singleton_method color do |str| - colorize( - str, code - ) - end - end - - # -------------------------------------------------------------------------- - - class << self - alias reset_color reset_ansi - alias strip_color strip_ansi - alias has_color? has_ansi? - end - - # -------------------------------------------------------------------------- - - CORE_METHODS = ( - public_methods - Object.methods - ) -end - -require "colorator/core_ext" diff --git a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator/core_ext.rb b/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator/core_ext.rb deleted file mode 100644 index f2e0bf0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/colorator-1.1.0/lib/colorator/core_ext.rb +++ /dev/null @@ -1,9 +0,0 @@ -class String - Colorator::CORE_METHODS.each do |method| - define_method method do |*args| - Colorator.public_send(method, - self, *args - ) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/CHANGELOG.md b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/CHANGELOG.md deleted file mode 100644 index 2c0375c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/CHANGELOG.md +++ /dev/null @@ -1,593 +0,0 @@ -## Current - -## Release v1.3.4 (10 August 2024) - -* (#1060) Fix bug with return value of `Concurrent.available_processor_count` when `cpu.cfs_quota_us` is -1. -* (#1058) Add `Concurrent.cpu_shares` that is cgroups aware. - -## Release v1.3.3 (9 June 2024) - -* (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows. - -## Release v1.3.2, edge v0.7.1 (7 June 2024) - -concurrent-ruby: - -* (#1051) Remove dependency on `win32ole`. - -concurrent-ruby-edge: - -* (#1052) Fix dependency on `concurrent-ruby` to allow the latest release. - -## Release v1.3.1 (29 May 2024) - -* Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix. - -## Release v1.3.0 (28 May 2024) - -* (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?` -* (#1038) Add `Concurrent.available_processor_count` that is cgroups aware. - -## Release v1.2.3 (16 Jan 2024) - -* See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details. - -## Release v1.2.2 (24 Feb 2023) - -* (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`. - -## Release v1.2.1 (24 Feb 2023) - -* (#990) Add missing `require 'fiber'` for `FiberLocalVar`. -* (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`. - -## Release v1.2.0 (23 Jan 2023) - -* (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses. -* (#983) Add FiberLocalVar -* (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'` -* (#976) Let `Promises.any_fulfilled_future` take an `Event` -* Improve documentation of various classes -* (#975) Set the Ruby compatibility version at 2.3 -* (#972) Remove Rubinius-related code - -## Release v1.1.10 (22 Mar 2022) - -concurrent-ruby: - -* (#951) Set the Ruby compatibility version at 2.2 -* (#939, #933) The `caller_runs` fallback policy no longer blocks reads from the job queue by worker threads -* (#938, #761, #652) You can now explicitly `prune_pool` a thread pool (Sylvain Joyeux) -* (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso) -* (#932, #931) We changed how `SafeTaskExecutor` handles local jump errors (Aaron Jensen) -* (#927) You can use keyword arguments in your initialize when using `Async` (Matt Larraz) -* (#926, #639) We removed timeout from `TimerTask` because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen) -* (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan) -* (#915) `monotonic_time` now accepts an optional unit parameter, as Ruby's `clock_gettime` (Jean Boussier) - -## Release v1.1.9 (5 Jun 2021) - -concurrent-ruby: - -* (#866) Child promise state not set to :pending immediately after #execute when parent has completed -* (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method -* (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned -* (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby -* (#907) Add new ConcurrentMap backend for TruffleRuby - -## Release v1.1.8 (20 January 2021) - -concurrent-ruby: - -* (#885) Fix race condition in TVar for stale reads -* (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition - -## Release v1.1.7 (6 August 2020) - -concurrent-ruby: - -* (#879) Consider falsy value on `Concurrent::Map#compute_if_absent` for fast non-blocking path -* (#876) Reset Async queue on forking, makes Async fork-safe -* (#856) Avoid running problematic code in RubyThreadLocalVar on MRI that occasionally results in segfault -* (#853) Introduce ThreadPoolExecutor without a Queue - -## Release v1.1.6, edge v0.6.0 (10 Feb 2020) - -concurrent-ruby: - -* (#841) Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated. -* (#841) AbstractExecutorService#auto_terminate= was deprecated and has no effect. - Set :auto_terminate option instead when executor is initialized. - -## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020) - -concurrent-ruby: - -* (#828) Allow to name executors, the name is also used to name their threads -* (#838) Implement #dup and #clone for structs -* (#821) Safer finalizers for thread local variables -* Documentation fixes -* (#814) Use Ruby's Etc.nprocessors if available -* (#812) Fix directory structure not to mess with packaging tools -* (#840) Fix termination of pools on JRuby - -concurrent-ruby-edge: - -* Add WrappingExecutor (#830) - -## Release v1.1.5, edge v0.5.0 (10 Mar 2019) - -concurrent-ruby: - -* fix potential leak of context on JRuby and Java 7 - -concurrent-ruby-edge: - -* Add finalized Concurrent::Cancellation -* Add finalized Concurrent::Throttle -* Add finalized Concurrent::Promises::Channel -* Add new Concurrent::ErlangActor - -## Release v1.1.4 (14 Dec 2018) - -* (#780) Remove java_alias of 'submit' method of Runnable to let executor service work on java 11 -* (#776) Fix NameError on defining a struct with a name which is already taken in an ancestor - -## Release v1.1.3 (7 Nov 2018) - -* (#775) fix partial require of the gem (although not officially supported) - -## Release v1.1.2 (6 Nov 2018) - -* (#773) more defensive 1.9.3 support - -## Release v1.1.1, edge v0.4.1 (1 Nov 2018) - -* (#768) add support for 1.9.3 back - -## Release v1.1.0, edge v0.4.0 (31 OCt 2018) (yanked) - -* (#768) yanked because of issues with removed 1.9.3 support - -## Release v1.1.0.pre2, edge v0.4.0.pre2 (18 Sep 2018) - -concurrent-ruby: - -* fixed documentation and README links -* fix Set for TruffleRuby and Rubinius -* use properly supported TruffleRuby APIs - -concurrent-ruby-edge: - -* add Promises.zip_futures_over_on - -## Release v1.1.0.pre1, edge v0.4.0.pre1 (15 Aug 2018) - -concurrent-ruby: - -* requires at least Ruby 2.0 -* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/1.1.0/Concurrent/Promises.html) - are moved from `concurrent-ruby-edge` to `concurrent-ruby` -* Add support for TruffleRuby - * (#734) Fix Array/Hash/Set construction broken on TruffleRuby - * AtomicReference fixed -* CI stabilization -* remove sharp dependency edge -> core -* remove warnings -* documentation updates -* Exchanger is no longer documented as edge since it was already available in - `concurrent-ruby` -* (#644) Fix Map#each and #each_pair not returning enumerator outside of MRI -* (#659) Edge promises fail during error handling -* (#741) Raise on recursive Delay#value call -* (#727) #717 fix global IO executor on JRuby -* (#740) Drop support for CRuby 1.9, JRuby 1.7, Rubinius. -* (#737) Move AtomicMarkableReference out of Edge -* (#708) Prefer platform specific memory barriers -* (#735) Fix wrong expected exception in channel spec assertion -* (#729) Allow executor option in `Promise#then` -* (#725) fix timeout check to use timeout_interval -* (#719) update engine detection -* (#660) Add specs for Promise#zip/Promise.zip ordering -* (#654) Promise.zip execution changes -* (#666) Add thread safe set implementation -* (#651) #699 #to_s, #inspect should not output negative object IDs. -* (#685) Avoid RSpec warnings about raise_error -* (#680) Avoid RSpec monkey patching, persist spec results locally, use RSpec - v3.7.0 -* (#665) Initialize the monitor for new subarrays on Rubinius -* (#661) Fix error handling in edge promises - -concurrent-ruby-edge: - -* (#659) Edge promises fail during error handling -* Edge files clearly separated in `lib-edge` -* added ReInclude - -## Release v1.0.5, edge v0.3.1 (26 Feb 2017) - -concurrent-ruby: - -* Documentation for Event and Semaphore -* Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby -* Do not depend on org.jruby.util.unsafe.UnsafeHolder - -concurrent-ruby-edge: - -* (#620) Actors on Pool raise an error -* (#624) Delayed promises did not interact correctly with flatting - * Fix arguments yielded by callback methods -* Overridable default executor in promises factory methods -* Asking actor to terminate will always resolve to `true` - -## Release v1.0.4, edge v0.3.0 (27 Dec 2016) - -concurrent-ruby: - -* Nothing - -concurrent-ruby-edge: - -* New promises' API renamed, lots of improvements, edge bumped to 0.3.0 - * **Incompatible** with previous 0.2.3 version - * see https://github.com/ruby-concurrency/concurrent-ruby/pull/522 - -## Release v1.0.3 (17 Dec 2016) - -* Trigger execution of flattened delayed futures -* Avoid forking for processor_count if possible -* Semaphore Mutex and JRuby parity -* Adds Map#each as alias to Map#each_pair -* Fix uninitialized instance variables -* Make Fixnum, Bignum merger ready -* Allows Promise#then to receive an executor -* TimerSet now survives a fork -* Reject promise on any exception -* Allow ThreadLocalVar to be initialized with a block -* Support Alpha with `Concurrent::processor_count` -* Fixes format-security error when compiling ruby_193_compatible.h -* Concurrent::Atom#swap fixed: reraise the exceptions from block - -## Release v1.0.2 (2 May 2016) - -* Fix bug with `Concurrent::Map` MRI backend `#inspect` method -* Fix bug with `Concurrent::Map` MRI backend using `Hash#value?` -* Improved documentation and examples -* Minor updates to Edge - -## Release v1.0.1 (27 February 2016) - -* Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error. -* Better handling of `autoload` vs. `require`. -* Improved API for Edge `Future` zipping. -* Fix reference leak in Edge `Future` constructor . -* Fix bug which prevented thread pools from surviving a `fork`. -* Fix bug in which `TimerTask` did not correctly specify all its dependencies. -* Improved support for JRuby+Truffle -* Improved error messages. -* Improved documentation. -* Updated README and CONTRIBUTING. - -## Release v1.0.0 (13 November 2015) - -* Rename `attr_volatile_with_cas` to `attr_atomic` -* Add `clear_each` to `LockFreeStack` -* Update `AtomicReference` documentation -* Further updates and improvements to the synchronization layer. -* Performance and memory usage performance with `Actor` logging. -* Fixed `ThreadPoolExecutor` task count methods. -* Improved `Async` performance for both short and long-lived objects. -* Fixed bug in `LockFreeLinkedSet`. -* Fixed bug in which `Agent#await` triggered a validation failure. -* Further `Channel` updates. -* Adopted a project Code of Conduct -* Cleared interpreter warnings -* Fixed bug in `ThreadPoolExecutor` task count methods -* Fixed bug in 'LockFreeLinkedSet' -* Improved Java extension loading -* Handle Exception children in Edge::Future -* Continued improvements to channel -* Removed interpreter warnings. -* Shared constants now in `lib/concurrent/constants.rb` -* Refactored many tests. -* Improved synchronization layer/memory model documentation. -* Bug fix in Edge `Future#flat` -* Brand new `Channel` implementation in Edge gem. -* Simplification of `RubySingleThreadExecutor` -* `Async` improvements - - Each object uses its own `SingleThreadExecutor` instead of the global thread pool. - - No longers supports executor injection - - Much better documentation -* `Atom` updates - - No longer `Dereferenceable` - - Now `Observable` - - Added a `#reset` method -* Brand new `Agent` API and implementation. Now functionally equivalent to Clojure. -* Continued improvements to the synchronization layer -* Merged in the `thread_safe` gem - - `Concurrent::Array` - - `Concurrent::Hash` - - `Concurrent::Map` (formerly ThreadSafe::Cache) - - `Concurrent::Tuple` -* Minor improvements to Concurrent::Map -* Complete rewrite of `Exchanger` -* Removed all deprecated code (classes, methods, constants, etc.) -* Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object. -* Many improved tests -* Some internal reorganization - -## Release v0.9.1 (09 August 2015) - -* Fixed a Rubiniux bug in synchronization object -* Fixed all interpreter warnings (except circular references) -* Fixed require statements when requiring `Atom` alone -* Significantly improved `ThreadLocalVar` on non-JRuby platforms -* Fixed error handling in Edge `Concurrent.zip` -* `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta -* New `AtomicFixnum#update` method -* Minor optimizations in `ReadWriteLock` -* New `ReentrantReadWriteLock` class -* `ThreadLocalVar#bind` method is now public -* Refactored many tests - -## Release v0.9.0 (10 July 2015) - -* Updated `AtomicReference` - - `AtomicReference#try_update` now simply returns instead of raising exception - - `AtomicReference#try_update!` was added to raise exceptions if an update - fails. Note: this is the same behavior as the old `try_update` -* Pure Java implementations of - - `AtomicBoolean` - - `AtomicFixnum` - - `Semaphore` -* Fixed bug when pruning Ruby thread pools -* Fixed bug in time calculations within `ScheduledTask` -* Default `count` in `CountDownLatch` to 1 -* Use monotonic clock for all timers via `Concurrent.monotonic_time` - - Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available - - Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions - - Pure Ruby implementation for everything else - - Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask` -* Deprecated all clock-time based timer scheduling - - Only support scheduling by delay - - Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask` -* Added new `ReadWriteLock` class -* Consistent `at_exit` behavior for Java and Ruby thread pools. -* Added `at_exit` handler to Ruby thread pools (already in Java thread pools) - - Ruby handler stores the object id and retrieves from `ObjectSpace` - - JRuby disables `ObjectSpace` by default so that handler stores the object reference -* Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler -* Updated thread pool docs to better explain shutting down thread pools -* Simpler `:executor` option syntax for all abstractions which support this option -* Added `Executor#auto_terminate?` predicate method (for thread pools) -* Added `at_exit` handler to `TimerSet` -* Simplified auto-termination of the global executors - - Can now disable auto-termination of global executors - - Added shutdown/kill/wait_for_termination variants for global executors -* Can now disable auto-termination for *all* executors (the nuclear option) -* Simplified auto-termination of the global executors -* Deprecated terms "task pool" and "operation pool" - - New terms are "io executor" and "fast executor" - - New functions added with new names - - Deprecation warnings added to functions referencing old names -* Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent` - - Old functions still exist with deprecation warnings - - New functions have updated names as appropriate -* All high-level abstractions default to the "io executor" -* Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load - - This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby -* Moved global logger up to the `Concurrent` namespace and refactored the code -* Optimized the performance of `Delay` - - Fixed a bug in which no executor option on construction caused block execution on a global thread pool -* Numerous improvements and bug fixes to `TimerSet` -* Fixed deadlock of `Future` when the handler raises Exception -* Added shared specs for more classes -* New concurrency abstractions including: - - `Atom` - - `Maybe` - - `ImmutableStruct` - - `MutableStruct` - - `SettableStruct` -* Created an Edge gem for unstable abstractions including - - `Actor` - - `Agent` - - `Channel` - - `Exchanger` - - `LazyRegister` - - **new Future Framework** - unified - implementation of Futures and Promises which combines Features of previous `Future`, - `Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively - new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`. - It offers better performance and does not block threads when not required. -* Actor framework changes: - - fixed reset loop in Pool - - Pool can use any actor as a worker, abstract worker class is no longer needed. - - Actor events not have format `[:event_name, *payload]` instead of just the Symbol. - - Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability - - Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]` - - Linking behavior responds to :linked message by returning array of linked actors - - Supervised behavior is removed in favour of just Linking - - RestartingContext is supervised by default now, `supervise: true` is not required any more - - Events can be private and public, so far only difference is that Linking will - pass to linked actors only public messages. Adding private :restarting and - :resetting events which are send before the actor restarts or resets allowing - to add callbacks to cleanup current child actors. - - Print also object_id in Reference to_s - - Add AbstractContext#default_executor to be able to override executor class wide - - Add basic IO example - - Documentation somewhat improved - - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and - be sure that both jobs are processed first. -* Refactored `Channel` to use newer synchronization objects -* Added `#reset` and `#cancel` methods to `TimerSet` -* Added `#cancel` method to `Future` and `ScheduledTask` -* Refactored `TimerSet` to use `ScheduledTask` -* Updated `Async` with a factory that initializes the object -* Deprecated `Concurrent.timer` and `Concurrent.timeout` -* Reduced max threads on pure-Ruby thread pools (abends around 14751 threads) -* Moved many private/internal classes/modules into "namespace" modules -* Removed brute-force killing of threads in tests -* Fixed a thread pool bug when the operating system cannot allocate more threads - -## Release v0.8.0 (25 January 2015) - -* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem. - Please see the README for more detail. -* Better variable isolation in `Promise` and `Future` via an `:args` option -* Continued to update intermittently failing tests - -## Release v0.7.2 (24 January 2015) - -* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html) -* New `Promise.all?` and `Promise.any?` class methods -* Renamed `:overflow_policy` on thread pools to `:fallback_policy` -* Thread pools still accept the `:overflow_policy` option but display a warning -* Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks) -* Fixed minor `set_deref_options` constructor bug in `Promise` class -* Fixed minor `require` bug in `ThreadLocalVar` class -* Fixed race condition bug in `TimerSet` class -* Fixed race condition bug in `TimerSet` class -* Fixed signal bug in `TimerSet#post` method -* Numerous non-functional updates to clear warning when running in debug mode -* Fixed more intermittently failing tests -* Tests now run on new Travis build environment -* Multiple documentation updates - -## Release v0.7.1 (4 December 2014) - -Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release. - -* Added `flat_map` method to `Promise` -* Added `zip` method to `Promise` -* Fixed bug with logging in `Actor` -* Improvements to `Promise` tests -* Removed actor-experimental warning -* Added an `IndirectImmediateExecutor` class -* Allow disabling auto termination of global executors -* Fix thread leaking in `ThreadLocalVar` (uses `Ref` gem on non-JRuby systems) -* Fix thread leaking when pruning pure-Ruby thread pools -* Prevent `Actor` from using an `ImmediateExecutor` (causes deadlock) -* Added missing synchronizations to `TimerSet` -* Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask` -* Fixed timing bug in `TimerTask` -* Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero -* Removed confusing warning when not using native extenstions -* Improved documentation - -## Release v0.7.0 (13 August 2014) - -* Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem - - Pure Ruby `MutexAtomic` atomic reference class - - Platform native atomic reference classes `CAtomic`, `JavaAtomic`, and `RbxAtomic` - - Automated [build process](https://github.com/ruby-concurrency/rake-compiler-dev-box) - - Fat binary releases for [multiple platforms](https://rubygems.org/gems/concurrent-ruby/versions) including Windows (32/64), Linux (32/64), OS X (64-bit), Solaris (64-bit), and JRuby -* C native `CAtomicBoolean` -* C native `CAtomicFixnum` -* Refactored intermittently failing tests -* Added `dataflow!` and `dataflow_with!` methods to match `Future#value!` method -* Better handling of timeout in `Agent` -* Actor Improvements - - Fine-grained implementation using chain of behaviors. Each behavior is responsible for single aspect like: `Termination`, `Pausing`, `Linking`, `Supervising`, etc. Users can create custom Actors easily based on their needs. - - Supervision was added. `RestartingContext` will pause on error waiting on its supervisor to decide what to do next ( options are `:terminate!`, `:resume!`, `:reset!`, `:restart!`). Supervising behavior also supports strategies `:one_for_one` and `:one_for_all`. - - Linking was added to be able to monitor actor's events like: `:terminated`, `:paused`, `:restarted`, etc. - - Dead letter routing added. Rejected envelopes are collected in a configurable actor (default: `Concurrent::Actor.root.ask!(:dead_letter_routing)`) - - Old `Actor` class removed and replaced by new implementation previously called `Actress`. `Actress` was kept as an alias for `Actor` to keep compatibility. - - `Utils::Broadcast` actor which allows Publish–subscribe pattern. -* More executors for managing serialized operations - - `SerializedExecution` mixin module - - `SerializedExecutionDelegator` for serializing *any* executor -* Updated `Async` with serialized execution -* Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle -* Added a `Delay` to root `Actress` initialization -* Minor bug fixes to thread pools -* Refactored many intermittently failing specs -* Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)` -* Fixed minor bug in `RubyCachedThreadPool` overflow policy -* Updated tests to use [RSpec 3.0](http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3) -* Removed deprecated `Actor` class -* Better support for Rubinius - -## Release v0.6.1 (14 June 2014) - -* Many improvements to `Concurrent::Actress` -* Bug fixes to `Concurrent::RubyThreadPoolExecutor` -* Fixed several brittle tests -* Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html - -## Release v0.6.0 (25 May 2014) - -* Added `Concurrent::Observable` to encapsulate our thread safe observer sets -* Improvements to new `Channel` -* Major improvements to `CachedThreadPool` and `FixedThreadPool` -* Added `SingleThreadExecutor` -* Added `Current::timer` function -* Added `TimerSet` executor -* Added `AtomicBoolean` -* `ScheduledTask` refactoring -* Pure Ruby and JRuby-optimized `PriorityQueue` classes -* Updated `Agent` behavior to more closely match Clojure -* Observer sets support block callbacks to the `add_observer` method -* New algorithm for thread creation in `RubyThreadPoolExecutor` -* Minor API updates to `Event` -* Rewritten `TimerTask` now an `Executor` instead of a `Runnable` -* Fixed many brittle specs -* Renamed `FixedThreadPool` and `CachedThreadPool` to `RubyFixedThreadPool` and `RubyCachedThreadPool` -* Created JRuby optimized `JavaFixedThreadPool` and `JavaCachedThreadPool` -* Consolidated fixed thread pool tests into `spec/concurrent/fixed_thread_pool_shared.rb` and `spec/concurrent/cached_thread_pool_shared.rb` -* `FixedThreadPool` now subclasses `RubyFixedThreadPool` or `JavaFixedThreadPool` as appropriate -* `CachedThreadPool` now subclasses `RubyCachedThreadPool` or `JavaCachedThreadPool` as appropriate -* New `Delay` class -* `Concurrent::processor_count` helper function -* New `Async` module -* Renamed `NullThreadPool` to `PerThreadExecutor` -* Deprecated `Channel` (we are planning a new implementation based on [Go](http://golangtutorials.blogspot.com/2011/06/channels-in-go.html)) -* Added gem-level [configuration](http://robots.thoughtbot.com/mygem-configure-block) -* Deprecated `$GLOBAL_THREAD_POOL` in lieu of gem-level configuration -* Removed support for Ruby [1.9.2](https://www.ruby-lang.org/en/news/2013/12/17/maintenance-of-1-8-7-and-1-9-2/) -* New `RubyThreadPoolExecutor` and `JavaThreadPoolExecutor` classes -* All thread pools now extend the appropriate thread pool executor classes -* All thread pools now support `:overflow_policy` (based on Java's [reject policies](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)) -* Deprecated `UsesGlobalThreadPool` in lieu of explicit `:executor` option (dependency injection) on `Future`, `Promise`, and `Agent` -* Added `Concurrent::dataflow_with(executor, *inputs)` method to support executor dependency injection for dataflow -* Software transactional memory with `TVar` and `Concurrent::atomically` -* First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel` -* `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release. - -## Release v0.5.0 - -This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were: - -* Stability improvements on Ruby versions with thread-level parallelism ([JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) -* Creation of new low-level concurrency abstractions -* Internal refactoring to use the new low-level abstractions - -Most of these updates had no effect on the gem API. There are a few notable exceptions which were unavoidable. Please read the [release notes](API-Updates-in-v0.5.0) for more information. - -Specific changes include: - -* New class `IVar` -* New class `MVar` -* New class `ThreadLocalVar` -* New class `AtomicFixnum` -* New class method `dataflow` -* New class `Condition` -* New class `CountDownLatch` -* New class `DependencyCounter` -* New class `SafeTaskExecutor` -* New class `CopyOnNotifyObserverSet` -* New class `CopyOnWriteObserverSet` -* `Future` updated with `execute` API -* `ScheduledTask` updated with `execute` API -* New `Promise` API -* `Future` now extends `IVar` -* `Postable#post?` now returns an `IVar` -* Thread safety fixes to `Dereferenceable` -* Thread safety fixes to `Obligation` -* Thread safety fixes to `Supervisor` -* Thread safety fixes to `Event` -* Various other thread safety (race condition) fixes -* Refactored brittle tests -* Implemented pending tests -* Added JRuby and Rubinius as Travis CI build targets -* Added [CodeClimate](https://codeclimate.com/) code review -* Improved YARD documentation diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Gemfile b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Gemfile deleted file mode 100644 index 1786c8b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Gemfile +++ /dev/null @@ -1,36 +0,0 @@ -source 'https://rubygems.org' - -version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise -edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise - -no_path = ENV['NO_PATH'] -options = no_path ? {} : { path: '.' } - -gem 'concurrent-ruby', version, options -gem 'concurrent-ruby-edge', edge_version, options -gem 'concurrent-ruby-ext', version, options.merge(platform: :mri) - -group :development do - gem 'rake', '~> 13.0' - gem 'rake-compiler', '~> 1.0', '>= 1.0.7', '!= 1.2.4' - gem 'rake-compiler-dock', '~> 1.0' - gem 'pry', '~> 0.11', platforms: :mri -end - -group :documentation, optional: true do - gem 'yard', '~> 0.9.0', require: false - gem 'redcarpet', '~> 3.0', platforms: :mri # understands github markdown - gem 'md-ruby-eval', '~> 0.6' -end - -group :testing do - gem 'rspec', '~> 3.7' - gem 'timecop', '~> 0.9' - gem 'sigdump', require: false -end - -# made opt-in since it will not install on jruby 1.7 -group :coverage, optional: !ENV['COVERAGE'] do - gem 'simplecov', '~> 0.16.0', require: false - gem 'coveralls', '~> 0.8.2', require: false -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/LICENSE.txt b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/LICENSE.txt deleted file mode 100644 index 1026f28..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) Jerry D'Antonio -- released under the MIT license. - -http://www.opensource.org/licenses/mit-license.php - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/README.md b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/README.md deleted file mode 100644 index 66a6983..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/README.md +++ /dev/null @@ -1,407 +0,0 @@ -# Concurrent Ruby - -[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) -[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT) -[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby) - -Modern concurrency tools for Ruby. Inspired by -[Erlang](http://www.erlang.org/doc/reference_manual/processes.html), -[Clojure](http://clojure.org/concurrent_programming), -[Scala](http://akka.io/), -[Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell), -[F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx), -[C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx), -[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html), -and classic concurrency patterns. - - - -The design goals of this gem are: - -* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better - or why -* Remain free of external gem dependencies -* Stay true to the spirit of the languages providing inspiration -* But implement in a way that makes sense for Ruby -* Keep the semantics as idiomatic Ruby as possible -* Support features that make sense in Ruby -* Exclude features that don't make sense in Ruby -* Be small, lean, and loosely coupled -* Thread-safety -* Backward compatibility - -## Contributing - -**This gem depends on -[contributions](https://github.com/ruby-concurrency/concurrent-ruby/graphs/contributors) and we -appreciate your help. Would you like to contribute? Great! Have a look at -[issues with `looking-for-contributor` label](https://github.com/ruby-concurrency/concurrent-ruby/issues?q=is%3Aissue+is%3Aopen+label%3Alooking-for-contributor).** And if you pick something up let us know on the issue. - -You can also get started by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to concurrent-ruby on CodeTriage](https://www.codetriage.com/ruby-concurrency/concurrent-ruby). [![Open Source Helpers](https://www.codetriage.com/ruby-concurrency/concurrent-ruby/badges/users.svg)](https://www.codetriage.com/ruby-concurrency/concurrent-ruby) - -## Thread Safety - -*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency -library, providing consistent behavior and guarantees on all three main Ruby interpreters -(MRI/CRuby, JRuby, TruffleRuby).* - -Every abstraction in this library is thread safe. Specific thread safety guarantees are documented -with each abstraction. - -It is critical to remember, however, that Ruby is a language of mutable references. *No* -concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as -sharing a mutable object between threads and modifying it on both threads) or from creating -deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which -encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any -other Ruby library, many of which support the mantra of -["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating). -Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and -immutable variable types and data structures. - -We've also initiated discussion to document the [memory model](docs-source/synchronization.md) of Ruby which -would provide consistent behaviour and guarantees on all three main Ruby interpreters -(MRI/CRuby, JRuby, TruffleRuby). - -## Features & Documentation - -**The primary site for documentation is the automatically generated -[API documentation](http://ruby-concurrency.github.io/concurrent-ruby/index.html) which is up to -date with latest release.** This readme matches the master so may contain new stuff not yet -released. - -We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby). - -### Versioning - -* `concurrent-ruby` uses [Semantic Versioning](http://semver.org/) -* `concurrent-ruby-ext` has always same version as `concurrent-ruby` -* `concurrent-ruby-edge` will always be 0.y.z therefore following - [point 4](http://semver.org/#spec-item-4) applies *"Major version zero - (0.y.z) is for initial development. Anything may change at any time. The - public API should not be considered stable."* However we additionally use - following rules: - * Minor version increment means incompatible changes were made - * Patch version increment means only compatible changes were made - - -#### General-purpose Concurrency Abstractions - -* [Async](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Async.html): - A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's - [gen_server](http://www.erlang.org/doc/man/gen_server.html). -* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ScheduledTask.html): - Like a Future scheduled for a specific future time. -* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TimerTask.html): - A Thread that periodically wakes up to perform work at regular intervals. -* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html): - Unified implementation of futures and promises which combines features of previous `Future`, - `Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and (partially) `TimerTask` into a single - framework. It extensively uses the new synchronization layer to make all the features - **non-blocking** and **lock-free**, with the exception of obviously blocking operations like - `#wait`, `#value`. It also offers better performance. - -#### Thread-safe Value Objects, Structures, and Collections - -Collection classes that were originally part of the (deprecated) `thread_safe` gem: - -* [Array](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Array.html) A thread-safe - subclass of Ruby's standard [Array](http://ruby-doc.org/core/Array.html). -* [Hash](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Hash.html) A thread-safe - subclass of Ruby's standard [Hash](http://ruby-doc.org/core/Hash.html). -* [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe - subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html). -* [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object - that should have much better performance characteristics, especially under high concurrency, - than `Concurrent::Hash`. -* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Tuple.html) A fixed size - array with volatile (synchronized, thread safe) getters/setters. - -Value objects inspired by other languages: - -* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Maybe.html) A thread-safe, - immutable object representing an optional value, based on - [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html). - -Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core/Struct.html): - -* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html) - Immutable struct where values are set at construction and cannot be changed later. -* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutableStruct.html) - Synchronized, mutable struct where values can be safely changed at any time. -* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/SettableStruct.html) - Synchronized, write-once struct where values can be set at most once, either at construction - or any time thereafter. - -Thread-safe variables: - -* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Agent.html): A way to - manage shared, mutable, *asynchronous*, independent state. Based on Clojure's - [Agent](http://clojure.org/agents). -* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atom.html): A way to manage - shared, mutable, *synchronous*, independent state. Based on Clojure's - [Atom](http://clojure.org/atoms). -* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicBoolean.html) - A boolean value that can be updated atomically. -* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicFixnum.html) - A numeric value that can be updated atomically. -* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicReference.html) - An object reference that may be updated atomically. -* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Exchanger.html) - A synchronization point at which threads can pair and swap elements within pairs. Based on - Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html). -* [MVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MVar.html) A synchronized - single element container. Based on Haskell's - [MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and - Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$). -* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadLocalVar.html) - A variable where the value is different for each thread. -* [TVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TVar.html) A transactional - variable implementing software transactional memory (STM). Based on Clojure's - [Ref](http://clojure.org/refs). - -#### Java-inspired ThreadPools and Other Executors - -* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html) - overview, which also contains a list of other Executors available. - -#### Thread Synchronization Classes and Algorithms - -* [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CountDownLatch.html) - A synchronization object that allows one thread to wait on multiple other threads. -* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CyclicBarrier.html) - A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. -* [Event](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Event.html) Old school - kernel-style event. -* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReadWriteLock.html) - A lock that supports multiple readers but only one writer. -* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReentrantReadWriteLock.html) - A read/write lock with reentrant and upgrade features. -* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Semaphore.html) - A counting-based locking mechanism that uses permits. -* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicMarkableReference.html) - -#### Deprecated - -Deprecated features are still available and bugs are being fixed, but new features will not be added. - -* ~~[Future](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future.html): - An asynchronous operation that produces a value.~~ Replaced by - [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). - * ~~[.dataflow](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#dataflow-class_method): - Built on Futures, Dataflow allows you to create a task that will be scheduled when all of - its data dependencies are available.~~ Replaced by - [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). -* ~~[Promise](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promise.html): Similar - to Futures, with more features.~~ Replaced by - [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). -* ~~[Delay](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Delay.html) Lazy evaluation - of a block yielding an immutable result. Based on Clojure's - [delay](https://clojuredocs.org/clojure.core/delay).~~ Replaced by - [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). -* ~~[IVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/IVar.html) Similar to a - "future" but can be manually assigned once, after which it becomes immutable.~~ Replaced by - [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). - -### Edge Features - -These are available in the `concurrent-ruby-edge` companion gem. - -These features are under active development and may change frequently. They are expected not to -keep backward compatibility (there may also lack tests and documentation). Semantic versions will -be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to -`concurrent-ruby` when final. - -* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Actor.html): Implements - the Actor Model, where concurrent actors exchange messages. - *Status: Partial documentation and tests; depends on new future/promise framework; stability is good.* -* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Channel.html): - Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)). - Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional - inspiration from Clojure [core.async](https://clojure.github.io/core.async/). - *Status: Partial documentation and tests.* -* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LazyRegister.html) -* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Edge/LockFreeLinkedSet.html) - *Status: will be moved to core soon.* -* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LockFreeStack.html) - *Status: missing documentation and tests.* -* [Promises::Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises/Channel.html) - A first in first out channel that accepts messages with push family of methods and returns - messages with pop family of methods. - Pop and push operations can be represented as futures, see `#pop_op` and `#push_op`. - The capacity of the channel can be limited to support back pressure, use capacity option in `#initialize`. - `#pop` method blocks ans `#pop_op` returns pending future if there is no message in the channel. - If the capacity is limited the `#push` method blocks and `#push_op` returns pending future. -* [Cancellation](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Cancellation.html) - The Cancellation abstraction provides cooperative cancellation. - - The standard methods `Thread#raise` of `Thread#kill` available in Ruby - are very dangerous (see linked the blog posts bellow). - Therefore concurrent-ruby provides an alternative. - - * - * - * - - It provides an object which represents a task which can be executed, - the task has to get the reference to the object and periodically cooperatively check that it is not cancelled. - Good practices to make tasks cancellable: - * check cancellation every cycle of a loop which does significant work, - * do all blocking actions in a loop with a timeout then on timeout check cancellation - and if ok block again with the timeout -* [Throttle](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Throttle.html) - A tool managing concurrency level of tasks. -* [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html) - Actor implementation which precisely matches Erlang actor behaviour. - Requires at least Ruby 2.1 otherwise it's not loaded. -* [WrappingExecutor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/WrappingExecutor.html) - A delegating executor which modifies each task before the task is given to - the target executor it delegates to. - -## Supported Ruby versions - -* MRI 2.3 and above -* Latest JRuby 9000 -* Latest TruffleRuby - -## Usage - -Everything within this gem can be loaded simply by requiring it: - -```ruby -require 'concurrent' -``` - -You can also require a specific abstraction [part of the public documentation](https://ruby-concurrency.github.io/concurrent-ruby/master/index.html) since concurrent-ruby 1.2.0, for example: -```ruby -require 'concurrent/map' -require 'concurrent/atomic/atomic_reference' -require 'concurrent/executor/fixed_thread_pool' -``` - -To use the tools in the Edge gem it must be required separately: - -```ruby -require 'concurrent-edge' -``` - -If the library does not behave as expected, `Concurrent.use_stdlib_logger(Logger::DEBUG)` could -help to reveal the problem. - -## Installation - -```shell -gem install concurrent-ruby -``` - -or add the following line to Gemfile: - -```ruby -gem 'concurrent-ruby', require: 'concurrent' -``` - -and run `bundle install` from your shell. - -### Edge Gem Installation - -The Edge gem must be installed separately from the core gem: - -```shell -gem install concurrent-ruby-edge -``` - -or add the following line to Gemfile: - -```ruby -gem 'concurrent-ruby-edge', require: 'concurrent-edge' -``` - -and run `bundle install` from your shell. - - -### C Extensions for MRI - -Potential performance improvements may be achieved under MRI by installing optional C extensions. -To minimise installation errors the C extensions are available in the `concurrent-ruby-ext` -extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same -version. Simply install the extension gem too: - -```ruby -gem install concurrent-ruby-ext -``` - -or add the following line to Gemfile: - -```ruby -gem 'concurrent-ruby-ext' -``` - -and run `bundle install` from your shell. - -In code it is only necessary to - -```ruby -require 'concurrent' -``` - -The `concurrent-ruby` gem will automatically detect the presence of the `concurrent-ruby-ext` gem -and load the appropriate C extensions. - -#### Note For gem developers - -No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The -best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions. - -## Building the gem - -### Requirements - -* Recent CRuby -* JRuby, `rbenv install jruby-9.2.17.0` -* Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0` -* Install Docker, required for Windows builds - -### Publishing the Gem - -* Update `version.rb` -* Update the CHANGELOG -* Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation. -* Commit (and push) the changes. -* Use `bundle exec rake release` to release the gem. - It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. - It will ask at the end before publishing anything. Steps can also be executed individually. - -## Maintainers - -* [Benoit Daloze](https://github.com/eregon) -* [Matthew Draper](https://github.com/matthewd) -* [Rafael França](https://github.com/rafaelfranca) -* [Charles Oliver Nutter](https://github.com/headius) -* [Ben Sheldon](https://github.com/bensheldon) -* [Samuel Williams](https://github.com/ioquatix) - -### Special Thanks to - -* [Jerry D'Antonio](https://github.com/jdantonio) for creating the gem -* [Brian Durand](https://github.com/bdurand) for the `ref` gem -* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems -* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem - -to the past maintainers - -* [Chris Seaton](https://github.com/chrisseaton) -* [Petr Chalupa](https://github.com/pitr-ch) -* [Michele Della Torre](https://github.com/mighe) -* [Paweł Obrok](https://github.com/obrok) -* [Lucas Allan](https://github.com/lucasallan) - -and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project -["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018. - -## License and Copyright - -*Concurrent Ruby* is free software released under the -[MIT License](http://www.opensource.org/licenses/MIT). - -The *Concurrent Ruby* [logo](https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png) was -designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014 -[Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved. diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Rakefile b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Rakefile deleted file mode 100644 index c52b564..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/Rakefile +++ /dev/null @@ -1,342 +0,0 @@ -version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise -edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise - -core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec') -ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec') -edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec') - -require 'rake/javaextensiontask' - -ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && RUBY_ENGINE != 'jruby' - -Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext| - ext.ext_dir = 'ext/concurrent-ruby' - ext.lib_dir = 'lib/concurrent-ruby/concurrent' -end - -if RUBY_ENGINE == 'ruby' - require 'rake/extensiontask' - - Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext| - ext.ext_dir = 'ext/concurrent-ruby-ext' - ext.lib_dir = 'lib/concurrent-ruby/concurrent' - ext.source_pattern = '*.{c,h}' - - ext.cross_compile = true - ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] - end -end - -def which?(executable) - !`which #{executable} 2>/dev/null`.empty? -end - -require 'rake_compiler_dock' -namespace :repackage do - desc '* with Windows fat distributions' - task :all do - Dir.chdir(__dir__) do - # store gems in vendor cache for docker - Bundler.with_original_env do - sh 'bundle package' - end - - # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem - Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke - - # build all gem files - rack_compiler_dock_kwargs = {} - if which?('podman') and (!which?('docker') || `docker --version`.include?('podman')) - # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker - rack_compiler_dock_kwargs = { - options: ['--privileged'], # otherwise the directory in the image is empty - runas: false - } - end - %w[x86-mingw32 x64-mingw32].each do |plat| - RakeCompilerDock.sh( - "bundle install --local && bundle exec rake native:#{plat} gem --trace", - platform: plat, - **rack_compiler_dock_kwargs) - end - end - end -end - -require 'rubygems' -require 'rubygems/package_task' - -Gem::PackageTask.new(core_gemspec) {} if core_gemspec -Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && RUBY_ENGINE != 'jruby' -Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec - -CLEAN.include( - 'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*', - 'lib/concurrent-ruby/concurrent/2.*', - 'lib/concurrent-ruby/concurrent/*.jar') - -begin - require 'rspec' - require 'rspec/core/rake_task' - - RSpec::Core::RakeTask.new(:spec) - - namespace :spec do - desc '* Configured for ci' - RSpec::Core::RakeTask.new(:ci) do |t| - options = %w[ --color - --backtrace - --order defined - --format documentation ] - t.rspec_opts = [*options].join(' ') - end - - desc '* test packaged and installed gems instead of local files' - task :installed do - Bundler.with_original_env do - Dir.chdir(__dir__) do - sh "gem install pkg/concurrent-ruby-#{version}.gem" - sh "gem install pkg/concurrent-ruby-ext-#{version}.gem" if RUBY_ENGINE == 'ruby' - sh "gem install pkg/concurrent-ruby-edge-#{edge_version}.gem" - ENV['NO_PATH'] = 'true' - sh 'bundle update' - sh 'bundle exec rake spec:ci' - end - end - end - end - - desc 'executed in CI' - task :ci => [:compile, 'spec:ci'] - - desc 'run each spec file in a separate process to help find missing requires' - task 'spec:isolated' do - glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb" - from = ENV['FROM'] - env = { 'ISOLATED' => 'true' } - Dir[glob].each do |spec| - next if from and from != spec - from = nil if from == spec - - sh env, 'rspec', spec - end - end - - task :default => [:clobber, :compile, :spec] -rescue LoadError => e - puts 'RSpec is not installed, skipping test task definitions: ' + e.message -end - -current_yard_version_name = version - -begin - require 'yard' - require 'md_ruby_eval' - require_relative 'support/yard_full_types' - - common_yard_options = ['--no-yardopts', - '--no-document', - '--no-private', - '--embed-mixins', - '--markup', 'markdown', - '--title', 'Concurrent Ruby', - '--template', 'default', - '--template-path', 'yard-template', - '--default-return', 'undocumented'] - - desc 'Generate YARD Documentation (signpost, master)' - task :yard => ['yard:signpost', 'yard:master'] - - namespace :yard do - - desc '* eval markdown files' - task :eval_md do - Dir.chdir File.join(__dir__, 'docs-source') do - sh 'bundle exec md-ruby-eval --auto' - end - end - - task :update_readme do - Dir.chdir __dir__ do - content = File.read(File.join('README.md')). - gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_| - case $1 - when 'LockFreeLinkedSet' - "{Concurrent::Edge::#{$1} #{$1}}" - when '.dataflow' - '{Concurrent.dataflow Concurrent.dataflow}' - when 'thread pool' - '{file:thread_pools.md thread pool}' - else - "{Concurrent::#{$1} #{$1}}" - end - end - FileUtils.mkpath 'tmp' - File.write 'tmp/README.md', content - end - end - - define_yard_task = -> name do - output_dir = "docs/#{name}" - - removal_name = "remove.#{name}" - task removal_name do - Dir.chdir __dir__ do - FileUtils.rm_rf output_dir - end - end - - desc "* of #{name} into subdir #{name}" - YARD::Rake::YardocTask.new(name) do |yard| - yard.options.push( - '--output-dir', output_dir, - '--main', 'tmp/README.md', - *common_yard_options) - yard.files = ['./lib/concurrent-ruby/**/*.rb', - './lib/concurrent-ruby-edge/**/*.rb', - './ext/concurrent_ruby_ext/**/*.c', - '-', - 'docs-source/thread_pools.md', - 'docs-source/promises.out.md', - 'docs-source/medium-example.out.rb', - 'LICENSE.txt', - 'CHANGELOG.md'] - end - Rake::Task[name].prerequisites.push removal_name, - # 'yard:eval_md', - 'yard:update_readme' - end - - define_yard_task.call current_yard_version_name - define_yard_task.call 'master' - - desc "* signpost for versions" - YARD::Rake::YardocTask.new(:signpost) do |yard| - yard.options.push( - '--output-dir', 'docs', - '--main', 'docs-source/signpost.md', - *common_yard_options) - yard.files = ['no-lib'] - end - end - -rescue LoadError => e - puts 'YARD is not installed, skipping documentation task definitions: ' + e.message -end - -desc 'build, test, and publish the gem' -task :release => ['release:checks', 'release:build', 'release:test', 'release:publish'] - -namespace :release do - # Depends on environment of @pitr-ch - - task :checks do - raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] - - Dir.chdir(__dir__) do - sh 'test -z "$(git status --porcelain)"' do |ok, res| - unless ok - begin - status = `git status --porcelain` - STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)' - input = STDIN.gets.strip.downcase - end until %w(y n).include?(input) - exit 1 if input == 'n' - end - end - sh 'git fetch' - sh 'test $(git show-ref --verify --hash refs/heads/master) = ' + - '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res| - unless ok - begin - STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)' - input = STDIN.gets.strip.downcase - end until %w(y n).include?(input) - exit 1 if input == 'n' - end - end - end - end - - desc '* build all *.gem files necessary for release' - task :build => [:clobber, 'repackage:all'] - - desc '* test actual installed gems instead of cloned repository on MRI and JRuby' - task :test do - raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] - - Dir.chdir(__dir__) do - puts "Testing with the installed gem" - - Bundler.with_original_env do - sh 'ruby -v' - sh 'bundle install' - sh 'bundle exec rake spec:installed' - - env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" } - sh env, 'ruby -v' - sh env, 'bundle install' - sh env, 'bundle exec rake spec:installed' - end - - puts 'Windows build is untested' - end - end - - desc '* do all nested steps' - task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps'] - - namespace :publish do - publish_base = nil - publish_edge = nil - - task :ask do - begin - STDOUT.puts 'Do you want to publish anything now? (y/n)' - input = STDIN.gets.strip.downcase - end until %w(y n).include?(input) - exit 1 if input == 'n' - - begin - STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)' - input = STDIN.gets.strip.downcase - end until %w(y n).include?(input) - publish_base = input == 'y' - - begin - STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)' - input = STDIN.gets.strip.downcase - end until %w(y n).include?(input) - publish_edge = input == 'y' - end - - desc '** tag HEAD with current version and push to github' - task :tag => :ask do - Dir.chdir(__dir__) do - sh "git tag v#{version}" if publish_base - sh "git push origin v#{version}" if publish_base - sh "git tag edge-v#{edge_version}" if publish_edge - sh "git push origin edge-v#{edge_version}" if publish_edge - end - end - - desc '** push all *.gem files to rubygems' - task :rubygems => :ask do - Dir.chdir(__dir__) do - sh "gem push pkg/concurrent-ruby-#{version}.gem" if publish_base - sh "gem push pkg/concurrent-ruby-edge-#{edge_version}.gem" if publish_edge - sh "gem push pkg/concurrent-ruby-ext-#{version}.gem" if publish_base - sh "gem push pkg/concurrent-ruby-ext-#{version}-x64-mingw32.gem" if publish_base - sh "gem push pkg/concurrent-ruby-ext-#{version}-x86-mingw32.gem" if publish_base - end - end - - desc '** print post release steps' - task :post_steps do - # TODO: (petr 05-Jun-2021) automate and renew the process - puts 'Manually: create a release on GitHub with relevant changelog part' - puts 'Manually: send email same as release with relevant changelog part' - puts 'Manually: tweet' - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/ConcurrentRubyService.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/ConcurrentRubyService.java deleted file mode 100644 index fb6be96..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/ConcurrentRubyService.java +++ /dev/null @@ -1,17 +0,0 @@ -import org.jruby.Ruby; -import org.jruby.runtime.load.BasicLibraryService; - -import java.io.IOException; - -public class ConcurrentRubyService implements BasicLibraryService { - - public boolean basicLoad(final Ruby runtime) throws IOException { - new com.concurrent_ruby.ext.AtomicReferenceLibrary().load(runtime, false); - new com.concurrent_ruby.ext.JavaAtomicBooleanLibrary().load(runtime, false); - new com.concurrent_ruby.ext.JavaAtomicFixnumLibrary().load(runtime, false); - new com.concurrent_ruby.ext.JavaSemaphoreLibrary().load(runtime, false); - new com.concurrent_ruby.ext.SynchronizationLibrary().load(runtime, false); - new com.concurrent_ruby.ext.JRubyMapBackendLibrary().load(runtime, false); - return true; - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java deleted file mode 100644 index dfa9e77..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.concurrent_ruby.ext; - -import java.lang.reflect.Field; -import java.io.IOException; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import org.jruby.Ruby; -import org.jruby.RubyClass; -import org.jruby.RubyModule; -import org.jruby.RubyNumeric; -import org.jruby.RubyObject; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.runtime.load.Library; - -/** - * This library adds an atomic reference type to JRuby for use in the atomic - * library. We do a native version to avoid the implicit value coercion that - * normally happens through JI. - * - * @author headius - */ -public class AtomicReferenceLibrary implements Library { - public void load(Ruby runtime, boolean wrap) throws IOException { - RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); - try { - sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class); - atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR); - } catch (Exception e) { - // leave it as Java 6/7 version - } - atomicCls.defineAnnotatedMethods(JRubyReference.class); - } - - private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JRubyReference(runtime, klazz); - } - }; - - private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JRubyReference8(runtime, klazz); - } - }; - - @JRubyClass(name="JRubyReference", parent="Object") - public static class JRubyReference extends RubyObject { - volatile IRubyObject reference; - - static final sun.misc.Unsafe UNSAFE; - static final long referenceOffset; - - static { - try { - UNSAFE = UnsafeHolder.U; - Class k = JRubyReference.class; - referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference")); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public JRubyReference(Ruby runtime, RubyClass klass) { - super(runtime, klass); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context) { - UNSAFE.putObject(this, referenceOffset, context.nil); - return context.nil; - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context, IRubyObject value) { - UNSAFE.putObject(this, referenceOffset, value); - return context.nil; - } - - @JRubyMethod(name = {"get", "value"}) - public IRubyObject get() { - return reference; - } - - @JRubyMethod(name = {"set", "value="}) - public IRubyObject set(IRubyObject newValue) { - UNSAFE.putObjectVolatile(this, referenceOffset, newValue); - return newValue; - } - - @JRubyMethod(name = {"compare_and_set", "compare_and_swap"}) - public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) { - Ruby runtime = context.runtime; - - if (expectedValue instanceof RubyNumeric) { - // numerics are not always idempotent in Ruby, so we need to do slower logic - return compareAndSetNumeric(context, expectedValue, newValue); - } - - return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue)); - } - - @JRubyMethod(name = {"get_and_set", "swap"}) - public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { - // less-efficient version for Java 6 and 7 - while (true) { - IRubyObject oldValue = get(); - if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) { - return oldValue; - } - } - } - - private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) { - Ruby runtime = context.runtime; - - // loop until: - // * reference CAS would succeed for same-valued objects - // * current and expected have different values as determined by #equals - while (true) { - IRubyObject current = reference; - - if (!(current instanceof RubyNumeric)) { - // old value is not numeric, CAS fails - return runtime.getFalse(); - } - - RubyNumeric currentNumber = (RubyNumeric)current; - if (!currentNumber.equals(expectedValue)) { - // current number does not equal expected, fail CAS - return runtime.getFalse(); - } - - // check that current has not changed, or else allow loop to repeat - boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue); - if (success) { - // value is same and did not change in interim...success - return runtime.getTrue(); - } - } - } - } - - private static final class UnsafeHolder { - private UnsafeHolder(){} - - public static final sun.misc.Unsafe U = loadUnsafe(); - - private static sun.misc.Unsafe loadUnsafe() { - try { - Class unsafeClass = Class.forName("sun.misc.Unsafe"); - Field f = unsafeClass.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (sun.misc.Unsafe) f.get(null); - } catch (Exception e) { - return null; - } - } - } - - public static class JRubyReference8 extends JRubyReference { - public JRubyReference8(Ruby runtime, RubyClass klass) { - super(runtime, klass); - } - - @Override - public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { - // efficient version for Java 8 - return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue); - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java deleted file mode 100644 index a09f916..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.concurrent_ruby.ext; - -import org.jruby.*; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; -import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8; -import com.concurrent_ruby.ext.jsr166e.nounsafe.*; -import org.jruby.runtime.Block; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.runtime.load.Library; - -import java.io.IOException; -import java.util.Map; - -import static org.jruby.runtime.Visibility.PRIVATE; - -/** - * Native Java implementation to avoid the JI overhead. - * - * @author thedarkone - */ -public class JRubyMapBackendLibrary implements Library { - public void load(Ruby runtime, boolean wrap) throws IOException { - - RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyModule thread_safeMod = concurrentMod.defineModuleUnder("Collection"); - RubyClass jrubyRefClass = thread_safeMod.defineClassUnder("JRubyMapBackend", runtime.getObject(), BACKEND_ALLOCATOR); - jrubyRefClass.setAllocator(BACKEND_ALLOCATOR); - jrubyRefClass.defineAnnotatedMethods(JRubyMapBackend.class); - } - - private static final ObjectAllocator BACKEND_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JRubyMapBackend(runtime, klazz); - } - }; - - @JRubyClass(name="JRubyMapBackend", parent="Object") - public static class JRubyMapBackend extends RubyObject { - // Defaults used by the CHM - static final int DEFAULT_INITIAL_CAPACITY = 16; - static final float DEFAULT_LOAD_FACTOR = 0.75f; - - public static final boolean CAN_USE_UNSAFE_CHM = canUseUnsafeCHM(); - - private ConcurrentHashMap map; - - private static ConcurrentHashMap newCHM(int initialCapacity, float loadFactor) { - if (CAN_USE_UNSAFE_CHM) { - return new ConcurrentHashMapV8(initialCapacity, loadFactor); - } else { - return new com.concurrent_ruby.ext.jsr166e.nounsafe.ConcurrentHashMapV8(initialCapacity, loadFactor); - } - } - - private static ConcurrentHashMap newCHM() { - return newCHM(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); - } - - private static boolean canUseUnsafeCHM() { - try { - new com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8(); // force class load and initialization - return true; - } catch (Throwable t) { // ensuring we really do catch everything - // Doug's Unsafe setup errors always have this "Could not ini.." message - if (isCausedBySecurityException(t)) { - return false; - } - throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t)); - } - } - - private static boolean isCausedBySecurityException(Throwable t) { - while (t != null) { - if ((t.getMessage() != null && t.getMessage().contains("Could not initialize intrinsics")) || t instanceof SecurityException) { - return true; - } - t = t.getCause(); - } - return false; - } - - public JRubyMapBackend(Ruby runtime, RubyClass klass) { - super(runtime, klass); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context) { - map = newCHM(); - return context.getRuntime().getNil(); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context, IRubyObject options) { - map = toCHM(context, options); - return context.getRuntime().getNil(); - } - - private ConcurrentHashMap toCHM(ThreadContext context, IRubyObject options) { - Ruby runtime = context.getRuntime(); - if (!options.isNil() && options.respondsTo("[]")) { - IRubyObject rInitialCapacity = options.callMethod(context, "[]", runtime.newSymbol("initial_capacity")); - IRubyObject rLoadFactor = options.callMethod(context, "[]", runtime.newSymbol("load_factor")); - int initialCapacity = !rInitialCapacity.isNil() ? RubyNumeric.num2int(rInitialCapacity.convertToInteger()) : DEFAULT_INITIAL_CAPACITY; - float loadFactor = !rLoadFactor.isNil() ? (float)RubyNumeric.num2dbl(rLoadFactor.convertToFloat()) : DEFAULT_LOAD_FACTOR; - return newCHM(initialCapacity, loadFactor); - } else { - return newCHM(); - } - } - - @JRubyMethod(name = "[]", required = 1) - public IRubyObject op_aref(ThreadContext context, IRubyObject key) { - IRubyObject value; - return ((value = map.get(key)) == null) ? context.getRuntime().getNil() : value; - } - - @JRubyMethod(name = {"[]="}, required = 2) - public IRubyObject op_aset(IRubyObject key, IRubyObject value) { - map.put(key, value); - return value; - } - - @JRubyMethod - public IRubyObject put_if_absent(IRubyObject key, IRubyObject value) { - IRubyObject result = map.putIfAbsent(key, value); - return result == null ? getRuntime().getNil() : result; - } - - @JRubyMethod - public IRubyObject compute_if_absent(final ThreadContext context, final IRubyObject key, final Block block) { - return map.computeIfAbsent(key, new ConcurrentHashMap.Fun() { - @Override - public IRubyObject apply(IRubyObject key) { - return block.yieldSpecific(context); - } - }); - } - - @JRubyMethod - public IRubyObject compute_if_present(final ThreadContext context, final IRubyObject key, final Block block) { - IRubyObject result = map.computeIfPresent(key, new ConcurrentHashMap.BiFun() { - @Override - public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { - IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); - return result.isNil() ? null : result; - } - }); - return result == null ? context.getRuntime().getNil() : result; - } - - @JRubyMethod - public IRubyObject compute(final ThreadContext context, final IRubyObject key, final Block block) { - IRubyObject result = map.compute(key, new ConcurrentHashMap.BiFun() { - @Override - public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { - IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); - return result.isNil() ? null : result; - } - }); - return result == null ? context.getRuntime().getNil() : result; - } - - @JRubyMethod - public IRubyObject merge_pair(final ThreadContext context, final IRubyObject key, final IRubyObject value, final Block block) { - IRubyObject result = map.merge(key, value, new ConcurrentHashMap.BiFun() { - @Override - public IRubyObject apply(IRubyObject oldValue, IRubyObject newValue) { - IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); - return result.isNil() ? null : result; - } - }); - return result == null ? context.getRuntime().getNil() : result; - } - - @JRubyMethod - public RubyBoolean replace_pair(IRubyObject key, IRubyObject oldValue, IRubyObject newValue) { - return getRuntime().newBoolean(map.replace(key, oldValue, newValue)); - } - - @JRubyMethod(name = "key?", required = 1) - public RubyBoolean has_key_p(IRubyObject key) { - return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse(); - } - - @JRubyMethod - public IRubyObject key(IRubyObject value) { - final IRubyObject key = map.findKey(value); - return key == null ? getRuntime().getNil() : key; - } - - @JRubyMethod - public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) { - IRubyObject result = map.replace(key, value); - return result == null ? getRuntime().getNil() : result; - } - - @JRubyMethod - public IRubyObject get_and_set(IRubyObject key, IRubyObject value) { - IRubyObject result = map.put(key, value); - return result == null ? getRuntime().getNil() : result; - } - - @JRubyMethod - public IRubyObject delete(IRubyObject key) { - IRubyObject result = map.remove(key); - return result == null ? getRuntime().getNil() : result; - } - - @JRubyMethod - public RubyBoolean delete_pair(IRubyObject key, IRubyObject value) { - return getRuntime().newBoolean(map.remove(key, value)); - } - - @JRubyMethod - public IRubyObject clear() { - map.clear(); - return this; - } - - @JRubyMethod - public IRubyObject each_pair(ThreadContext context, Block block) { - for (Map.Entry entry : map.entrySet()) { - block.yieldSpecific(context, entry.getKey(), entry.getValue()); - } - return this; - } - - @JRubyMethod - public RubyFixnum size(ThreadContext context) { - return context.getRuntime().newFixnum(map.size()); - } - - @JRubyMethod - public IRubyObject get_or_default(IRubyObject key, IRubyObject defaultValue) { - return map.getValueOrDefault(key, defaultValue); - } - - @JRubyMethod(visibility = PRIVATE) - public JRubyMapBackend initialize_copy(ThreadContext context, IRubyObject other) { - map = newCHM(); - return this; - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java deleted file mode 100644 index b566076..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.concurrent_ruby.ext; - -import org.jruby.Ruby; -import org.jruby.RubyBoolean; -import org.jruby.RubyClass; -import org.jruby.RubyModule; -import org.jruby.RubyNil; -import org.jruby.RubyObject; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.runtime.load.Library; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; - -public class JavaAtomicBooleanLibrary implements Library { - - public void load(Ruby runtime, boolean wrap) throws IOException { - RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicBoolean", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); - atomicCls.defineAnnotatedMethods(JavaAtomicBoolean.class); - } - - private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JavaAtomicBoolean(runtime, klazz); - } - }; - - @JRubyClass(name = "JavaAtomicBoolean", parent = "Object") - public static class JavaAtomicBoolean extends RubyObject { - - private AtomicBoolean atomicBoolean; - - public JavaAtomicBoolean(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context, IRubyObject value) { - atomicBoolean = new AtomicBoolean(convertRubyBooleanToJavaBoolean(value)); - return context.nil; - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context) { - atomicBoolean = new AtomicBoolean(); - return context.nil; - } - - @JRubyMethod(name = "value") - public IRubyObject value() { - return getRuntime().newBoolean(atomicBoolean.get()); - } - - @JRubyMethod(name = "true?") - public IRubyObject isAtomicTrue() { - return getRuntime().newBoolean(atomicBoolean.get()); - } - - @JRubyMethod(name = "false?") - public IRubyObject isAtomicFalse() { - return getRuntime().newBoolean((atomicBoolean.get() == false)); - } - - @JRubyMethod(name = "value=") - public IRubyObject setAtomic(ThreadContext context, IRubyObject newValue) { - atomicBoolean.set(convertRubyBooleanToJavaBoolean(newValue)); - return context.nil; - } - - @JRubyMethod(name = "make_true") - public IRubyObject makeTrue() { - return getRuntime().newBoolean(atomicBoolean.compareAndSet(false, true)); - } - - @JRubyMethod(name = "make_false") - public IRubyObject makeFalse() { - return getRuntime().newBoolean(atomicBoolean.compareAndSet(true, false)); - } - - private boolean convertRubyBooleanToJavaBoolean(IRubyObject newValue) { - if (newValue instanceof RubyBoolean.False || newValue instanceof RubyNil) { - return false; - } else { - return true; - } - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java deleted file mode 100644 index 672bfc0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.concurrent_ruby.ext; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicLong; -import org.jruby.Ruby; -import org.jruby.RubyClass; -import org.jruby.RubyFixnum; -import org.jruby.RubyModule; -import org.jruby.RubyObject; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.runtime.load.Library; -import org.jruby.runtime.Block; - -public class JavaAtomicFixnumLibrary implements Library { - - public void load(Ruby runtime, boolean wrap) throws IOException { - RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicFixnum", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); - - atomicCls.defineAnnotatedMethods(JavaAtomicFixnum.class); - } - - private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JavaAtomicFixnum(runtime, klazz); - } - }; - - @JRubyClass(name = "JavaAtomicFixnum", parent = "Object") - public static class JavaAtomicFixnum extends RubyObject { - - private AtomicLong atomicLong; - - public JavaAtomicFixnum(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context) { - this.atomicLong = new AtomicLong(0); - return context.nil; - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context, IRubyObject value) { - this.atomicLong = new AtomicLong(rubyFixnumToLong(value)); - return context.nil; - } - - @JRubyMethod(name = "value") - public IRubyObject getValue() { - return getRuntime().newFixnum(atomicLong.get()); - } - - @JRubyMethod(name = "value=") - public IRubyObject setValue(ThreadContext context, IRubyObject newValue) { - atomicLong.set(rubyFixnumToLong(newValue)); - return context.nil; - } - - @JRubyMethod(name = {"increment", "up"}) - public IRubyObject increment() { - return getRuntime().newFixnum(atomicLong.incrementAndGet()); - } - - @JRubyMethod(name = {"increment", "up"}) - public IRubyObject increment(IRubyObject value) { - long delta = rubyFixnumToLong(value); - return getRuntime().newFixnum(atomicLong.addAndGet(delta)); - } - - @JRubyMethod(name = {"decrement", "down"}) - public IRubyObject decrement() { - return getRuntime().newFixnum(atomicLong.decrementAndGet()); - } - - @JRubyMethod(name = {"decrement", "down"}) - public IRubyObject decrement(IRubyObject value) { - long delta = rubyFixnumToLong(value); - return getRuntime().newFixnum(atomicLong.addAndGet(-delta)); - } - - @JRubyMethod(name = "compare_and_set") - public IRubyObject compareAndSet(ThreadContext context, IRubyObject expect, IRubyObject update) { - return getRuntime().newBoolean(atomicLong.compareAndSet(rubyFixnumToLong(expect), rubyFixnumToLong(update))); - } - - @JRubyMethod - public IRubyObject update(ThreadContext context, Block block) { - for (;;) { - long _oldValue = atomicLong.get(); - IRubyObject oldValue = getRuntime().newFixnum(_oldValue); - IRubyObject newValue = block.yield(context, oldValue); - if (atomicLong.compareAndSet(_oldValue, rubyFixnumToLong(newValue))) { - return newValue; - } - } - } - - private long rubyFixnumToLong(IRubyObject value) { - if (value instanceof RubyFixnum) { - RubyFixnum fixNum = (RubyFixnum) value; - return fixNum.getLongValue(); - } else { - throw getRuntime().newArgumentError("value must be a Fixnum"); - } - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java deleted file mode 100644 index d887f25..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.concurrent_ruby.ext; - -import java.io.IOException; -import java.util.concurrent.Semaphore; -import org.jruby.Ruby; -import org.jruby.RubyClass; -import org.jruby.RubyFixnum; -import org.jruby.RubyModule; -import org.jruby.RubyNumeric; -import org.jruby.RubyObject; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.Block; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; - -public class JavaSemaphoreLibrary { - - public void load(Ruby runtime, boolean wrap) throws IOException { - RubyModule concurrentMod = runtime.defineModule("Concurrent"); - RubyClass atomicCls = concurrentMod.defineClassUnder("JavaSemaphore", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); - - atomicCls.defineAnnotatedMethods(JavaSemaphore.class); - } - - private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JavaSemaphore(runtime, klazz); - } - }; - - @JRubyClass(name = "JavaSemaphore", parent = "Object") - public static class JavaSemaphore extends RubyObject { - - private JRubySemaphore semaphore; - - public JavaSemaphore(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - - @JRubyMethod - public IRubyObject initialize(ThreadContext context, IRubyObject value) { - this.semaphore = new JRubySemaphore(rubyFixnumInt(value, "count")); - return context.nil; - } - - @JRubyMethod - public IRubyObject acquire(ThreadContext context, final Block block) throws InterruptedException { - return this.acquire(context, 1, block); - } - - @JRubyMethod - public IRubyObject acquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { - return this.acquire(context, rubyFixnumToPositiveInt(permits, "permits"), block); - } - - @JRubyMethod(name = "available_permits") - public IRubyObject availablePermits(ThreadContext context) { - return getRuntime().newFixnum(this.semaphore.availablePermits()); - } - - @JRubyMethod(name = "drain_permits") - public IRubyObject drainPermits(ThreadContext context) { - return getRuntime().newFixnum(this.semaphore.drainPermits()); - } - - @JRubyMethod(name = "try_acquire") - public IRubyObject tryAcquire(ThreadContext context, final Block block) throws InterruptedException { - int permitsInt = 1; - boolean acquired = semaphore.tryAcquire(permitsInt); - - return triedAcquire(context, permitsInt, acquired, block); - } - - @JRubyMethod(name = "try_acquire") - public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { - int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); - boolean acquired = semaphore.tryAcquire(permitsInt); - - return triedAcquire(context, permitsInt, acquired, block); - } - - @JRubyMethod(name = "try_acquire") - public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout, final Block block) throws InterruptedException { - int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); - boolean acquired = semaphore.tryAcquire( - permitsInt, - rubyNumericToLong(timeout, "timeout"), - java.util.concurrent.TimeUnit.SECONDS - ); - - return triedAcquire(context, permitsInt, acquired, block); - } - - @JRubyMethod - public IRubyObject release(ThreadContext context) { - this.semaphore.release(1); - return getRuntime().newBoolean(true); - } - - @JRubyMethod - public IRubyObject release(ThreadContext context, IRubyObject permits) { - this.semaphore.release(rubyFixnumToPositiveInt(permits, "permits")); - return getRuntime().newBoolean(true); - } - - @JRubyMethod(name = "reduce_permits") - public IRubyObject reducePermits(ThreadContext context, IRubyObject reduction) throws InterruptedException { - this.semaphore.publicReducePermits(rubyFixnumToNonNegativeInt(reduction, "reduction")); - return context.nil; - } - - private IRubyObject acquire(ThreadContext context, int permits, final Block block) throws InterruptedException { - this.semaphore.acquire(permits); - - if (!block.isGiven()) return context.nil; - - try { - return block.yieldSpecific(context); - } finally { - this.semaphore.release(permits); - } - } - - private IRubyObject triedAcquire(ThreadContext context, int permits, boolean acquired, final Block block) { - if (!block.isGiven()) return getRuntime().newBoolean(acquired); - if (!acquired) return context.nil; - - try { - return block.yieldSpecific(context); - } finally { - this.semaphore.release(permits); - } - } - - private int rubyFixnumInt(IRubyObject value, String paramName) { - if (value instanceof RubyFixnum) { - RubyFixnum fixNum = (RubyFixnum) value; - return (int) fixNum.getLongValue(); - } else { - throw getRuntime().newArgumentError(paramName + " must be integer"); - } - } - - private int rubyFixnumToNonNegativeInt(IRubyObject value, String paramName) { - if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() >= 0) { - RubyFixnum fixNum = (RubyFixnum) value; - return (int) fixNum.getLongValue(); - } else { - throw getRuntime().newArgumentError(paramName + " must be a non-negative integer"); - } - } - - private int rubyFixnumToPositiveInt(IRubyObject value, String paramName) { - if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() > 0) { - RubyFixnum fixNum = (RubyFixnum) value; - return (int) fixNum.getLongValue(); - } else { - throw getRuntime().newArgumentError(paramName + " must be an integer greater than zero"); - } - } - - private long rubyNumericToLong(IRubyObject value, String paramName) { - if (value instanceof RubyNumeric && ((RubyNumeric) value).getDoubleValue() > 0) { - RubyNumeric fixNum = (RubyNumeric) value; - return fixNum.getLongValue(); - } else { - throw getRuntime().newArgumentError(paramName + " must be a float greater than zero"); - } - } - - class JRubySemaphore extends Semaphore { - - public JRubySemaphore(int permits) { - super(permits); - } - - public JRubySemaphore(int permits, boolean value) { - super(permits, value); - } - - public void publicReducePermits(int i) { - reducePermits(i); - } - - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java deleted file mode 100644 index f0c75ee..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.concurrent_ruby.ext; - -import org.jruby.Ruby; -import org.jruby.RubyBasicObject; -import org.jruby.RubyClass; -import org.jruby.RubyModule; -import org.jruby.RubyObject; -import org.jruby.RubyThread; -import org.jruby.anno.JRubyClass; -import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.Block; -import org.jruby.runtime.ObjectAllocator; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.Visibility; -import org.jruby.runtime.builtin.IRubyObject; -import org.jruby.runtime.load.Library; -import sun.misc.Unsafe; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -public class SynchronizationLibrary implements Library { - - private static final Unsafe UNSAFE = loadUnsafe(); - private static final boolean FULL_FENCE = supportsFences(); - - private static Unsafe loadUnsafe() { - try { - Class ncdfe = Class.forName("sun.misc.Unsafe"); - Field f = ncdfe.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (Unsafe) f.get((java.lang.Object) null); - } catch (Exception var2) { - return null; - } catch (NoClassDefFoundError var3) { - return null; - } - } - - private static boolean supportsFences() { - if (UNSAFE == null) { - return false; - } else { - try { - Method m = UNSAFE.getClass().getDeclaredMethod("fullFence", new Class[0]); - if (m != null) { - return true; - } - } catch (Exception var1) { - // nothing - } - - return false; - } - } - - private static final ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new Object(runtime, klazz); - } - }; - - private static final ObjectAllocator ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new AbstractLockableObject(runtime, klazz); - } - }; - - private static final ObjectAllocator JRUBY_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JRubyLockableObject(runtime, klazz); - } - }; - - public void load(Ruby runtime, boolean wrap) throws IOException { - RubyModule synchronizationModule = runtime. - defineModule("Concurrent"). - defineModuleUnder("Synchronization"); - - RubyModule jrubyAttrVolatileModule = synchronizationModule.defineModuleUnder("JRubyAttrVolatile"); - jrubyAttrVolatileModule.defineAnnotatedMethods(JRubyAttrVolatile.class); - - defineClass(runtime, synchronizationModule, "AbstractObject", "Object", - Object.class, OBJECT_ALLOCATOR); - - defineClass(runtime, synchronizationModule, "Object", "AbstractLockableObject", - AbstractLockableObject.class, ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR); - - defineClass(runtime, synchronizationModule, "AbstractLockableObject", "JRubyLockableObject", - JRubyLockableObject.class, JRUBY_LOCKABLE_OBJECT_ALLOCATOR); - - defineClass(runtime, synchronizationModule, "Object", "JRuby", - JRuby.class, new ObjectAllocator() { - @Override - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new JRuby(runtime, klazz); - } - }); - } - - private RubyClass defineClass( - Ruby runtime, - RubyModule namespace, - String parentName, - String name, - Class javaImplementation, - ObjectAllocator allocator) { - final RubyClass parentClass = namespace.getClass(parentName); - - if (parentClass == null) { - System.out.println("not found " + parentName); - throw runtime.newRuntimeError(namespace.toString() + "::" + parentName + " is missing"); - } - - final RubyClass newClass = namespace.defineClassUnder(name, parentClass, allocator); - newClass.defineAnnotatedMethods(javaImplementation); - return newClass; - } - - // Facts: - // - all ivar reads are without any synchronisation of fences see - // https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/VariableAccessor.java#L110-110 - // - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor - // SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or - // volatilePut - // TODO (pitr 16-Sep-2015): what do we do in Java 9 ? - - // module JRubyAttrVolatile - public static class JRubyAttrVolatile { - - // volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic - // on volatile fields. any volatile field could have been used but using the thread context is an - // attempt to avoid code elimination. - private static volatile int volatileField; - - @JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC, module = true) - public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject module) { - // Prevent reordering of ivar writes with publication of this instance - if (!FULL_FENCE) { - // Assuming that following volatile read and write is not eliminated it simulates fullFence. - // If it's eliminated it'll cause problems only on non-x86 platforms. - // http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding - final int volatileRead = volatileField; - volatileField = context.getLine(); - } else { - UNSAFE.fullFence(); - } - return context.nil; - } - - @JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC, module = true) - public static IRubyObject instanceVariableGetVolatile( - ThreadContext context, - IRubyObject module, - IRubyObject self, - IRubyObject name) { - // Ensure we ses latest value with loadFence - if (!FULL_FENCE) { - // piggybacking on volatile read, simulating loadFence - final int volatileRead = volatileField; - return ((RubyBasicObject) self).instance_variable_get(context, name); - } else { - UNSAFE.loadFence(); - return ((RubyBasicObject) self).instance_variable_get(context, name); - } - } - - @JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC, module = true) - public static IRubyObject InstanceVariableSetVolatile( - ThreadContext context, - IRubyObject module, - IRubyObject self, - IRubyObject name, - IRubyObject value) { - // Ensure we make last update visible - if (!FULL_FENCE) { - // piggybacking on volatile write, simulating storeFence - final IRubyObject result = ((RubyBasicObject) self).instance_variable_set(name, value); - volatileField = context.getLine(); - return result; - } else { - // JRuby uses StampedVariableAccessor which calls fullFence - // so no additional steps needed. - // See https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/StampedVariableAccessor.java#L151-L159 - return ((RubyBasicObject) self).instance_variable_set(name, value); - } - } - } - - @JRubyClass(name = "Object", parent = "AbstractObject") - public static class Object extends RubyObject { - - public Object(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - } - - @JRubyClass(name = "AbstractLockableObject", parent = "Object") - public static class AbstractLockableObject extends Object { - - public AbstractLockableObject(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - } - - @JRubyClass(name = "JRubyLockableObject", parent = "AbstractLockableObject") - public static class JRubyLockableObject extends AbstractLockableObject { - - public JRubyLockableObject(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - - @JRubyMethod(name = "synchronize", visibility = Visibility.PROTECTED) - public IRubyObject rubySynchronize(ThreadContext context, Block block) { - synchronized (this) { - return block.yield(context, null); - } - } - - @JRubyMethod(name = "ns_wait", optional = 1, visibility = Visibility.PROTECTED) - public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) { - Ruby runtime = context.runtime; - if (args.length > 1) { - throw runtime.newArgumentError(args.length, 1); - } - Double timeout = null; - if (args.length > 0 && !args[0].isNil()) { - timeout = args[0].convertToFloat().getDoubleValue(); - if (timeout < 0) { - throw runtime.newArgumentError("time interval must be positive"); - } - } - if (Thread.interrupted()) { - throw runtime.newConcurrencyError("thread interrupted"); - } - boolean success = false; - try { - success = context.getThread().wait_timeout(this, timeout); - } catch (InterruptedException ie) { - throw runtime.newConcurrencyError(ie.getLocalizedMessage()); - } finally { - // An interrupt or timeout may have caused us to miss - // a notify that we consumed, so do another notify in - // case someone else is available to pick it up. - if (!success) { - this.notify(); - } - } - return this; - } - - @JRubyMethod(name = "ns_signal", visibility = Visibility.PROTECTED) - public IRubyObject nsSignal(ThreadContext context) { - notify(); - return this; - } - - @JRubyMethod(name = "ns_broadcast", visibility = Visibility.PROTECTED) - public IRubyObject nsBroadcast(ThreadContext context) { - notifyAll(); - return this; - } - } - - @JRubyClass(name = "JRuby") - public static class JRuby extends RubyObject { - public JRuby(Ruby runtime, RubyClass metaClass) { - super(runtime, metaClass); - } - - @JRubyMethod(name = "sleep_interruptibly", visibility = Visibility.PUBLIC, module = true) - public static IRubyObject sleepInterruptibly(final ThreadContext context, IRubyObject receiver, final Block block) { - try { - context.getThread().executeBlockingTask(new RubyThread.BlockingTask() { - @Override - public void run() throws InterruptedException { - block.call(context); - } - - @Override - public void wakeup() { - context.getThread().getNativeThread().interrupt(); - } - }); - } catch (InterruptedException e) { - throw context.runtime.newThreadError("interrupted in Concurrent::Synchronization::JRuby.sleep_interruptibly"); - } - return context.nil; - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java deleted file mode 100644 index e11e15a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.concurrent_ruby.ext.jsr166e; - -import java.util.Map; -import java.util.Set; - -public interface ConcurrentHashMap { - /** Interface describing a function of one argument */ - public interface Fun { T apply(A a); } - /** Interface describing a function of two arguments */ - public interface BiFun { T apply(A a, B b); } - - public V get(K key); - public V put(K key, V value); - public V putIfAbsent(K key, V value); - public V computeIfAbsent(K key, Fun mf); - public V computeIfPresent(K key, BiFun mf); - public V compute(K key, BiFun mf); - public V merge(K key, V value, BiFun mf); - public boolean replace(K key, V oldVal, V newVal); - public V replace(K key, V value); - public boolean containsKey(K key); - public boolean remove(Object key, Object value); - public V remove(K key); - public void clear(); - public Set> entrySet(); - public int size(); - public V getValueOrDefault(Object key, V defaultValue); - - public boolean containsValue(V value); - public K findKey(V value); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java deleted file mode 100644 index 86aa4eb..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +++ /dev/null @@ -1,3863 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on the 1.79 version. - -package com.concurrent_ruby.ext.jsr166e; - -import org.jruby.RubyClass; -import org.jruby.RubyNumeric; -import org.jruby.RubyObject; -import org.jruby.exceptions.RaiseException; -import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; - -import java.util.Arrays; -import java.util.Map; -import java.util.Set; -import java.util.Collection; -import java.util.Hashtable; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Enumeration; -import java.util.ConcurrentModificationException; -import java.util.NoSuchElementException; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.AbstractQueuedSynchronizer; - -import java.io.Serializable; - -/** - * A hash table supporting full concurrency of retrievals and - * high expected concurrency for updates. This class obeys the - * same functional specification as {@link java.util.Hashtable}, and - * includes versions of methods corresponding to each method of - * {@code Hashtable}. However, even though all operations are - * thread-safe, retrieval operations do not entail locking, - * and there is not any support for locking the entire table - * in a way that prevents all access. This class is fully - * interoperable with {@code Hashtable} in programs that rely on its - * thread safety but not on its synchronization details. - * - *

Retrieval operations (including {@code get}) generally do not - * block, so may overlap with update operations (including {@code put} - * and {@code remove}). Retrievals reflect the results of the most - * recently completed update operations holding upon their - * onset. (More formally, an update operation for a given key bears a - * happens-before relation with any (non-null) retrieval for - * that key reporting the updated value.) For aggregate operations - * such as {@code putAll} and {@code clear}, concurrent retrievals may - * reflect insertion or removal of only some entries. Similarly, - * Iterators and Enumerations return elements reflecting the state of - * the hash table at some point at or since the creation of the - * iterator/enumeration. They do not throw {@link - * ConcurrentModificationException}. However, iterators are designed - * to be used by only one thread at a time. Bear in mind that the - * results of aggregate status methods including {@code size}, {@code - * isEmpty}, and {@code containsValue} are typically useful only when - * a map is not undergoing concurrent updates in other threads. - * Otherwise the results of these methods reflect transient states - * that may be adequate for monitoring or estimation purposes, but not - * for program control. - * - *

The table is dynamically expanded when there are too many - * collisions (i.e., keys that have distinct hash codes but fall into - * the same slot modulo the table size), with the expected average - * effect of maintaining roughly two bins per mapping (corresponding - * to a 0.75 load factor threshold for resizing). There may be much - * variance around this average as mappings are added and removed, but - * overall, this maintains a commonly accepted time/space tradeoff for - * hash tables. However, resizing this or any other kind of hash - * table may be a relatively slow operation. When possible, it is a - * good idea to provide a size estimate as an optional {@code - * initialCapacity} constructor argument. An additional optional - * {@code loadFactor} constructor argument provides a further means of - * customizing initial table capacity by specifying the table density - * to be used in calculating the amount of space to allocate for the - * given number of elements. Also, for compatibility with previous - * versions of this class, constructors may optionally specify an - * expected {@code concurrencyLevel} as an additional hint for - * internal sizing. Note that using many keys with exactly the same - * {@code hashCode()} is a sure way to slow down performance of any - * hash table. - * - *

A {@link Set} projection of a ConcurrentHashMapV8 may be created - * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed - * (using {@link #keySet(Object)} when only keys are of interest, and the - * mapped values are (perhaps transiently) not used or all take the - * same mapping value. - * - *

A ConcurrentHashMapV8 can be used as scalable frequency map (a - * form of histogram or multiset) by using {@link LongAdder} values - * and initializing via {@link #computeIfAbsent}. For example, to add - * a count to a {@code ConcurrentHashMapV8 freqs}, you - * can use {@code freqs.computeIfAbsent(k -> new - * LongAdder()).increment();} - * - *

This class and its views and iterators implement all of the - * optional methods of the {@link Map} and {@link Iterator} - * interfaces. - * - *

Like {@link Hashtable} but unlike {@link HashMap}, this class - * does not allow {@code null} to be used as a key or value. - * - *

ConcurrentHashMapV8s support parallel operations using the {@link - * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts - * are available in class {@link ForkJoinTasks}). These operations are - * designed to be safely, and often sensibly, applied even with maps - * that are being concurrently updated by other threads; for example, - * when computing a snapshot summary of the values in a shared - * registry. There are three kinds of operation, each with four - * forms, accepting functions with Keys, Values, Entries, and (Key, - * Value) arguments and/or return values. (The first three forms are - * also available via the {@link #keySet()}, {@link #values()} and - * {@link #entrySet()} views). Because the elements of a - * ConcurrentHashMapV8 are not ordered in any particular way, and may be - * processed in different orders in different parallel executions, the - * correctness of supplied functions should not depend on any - * ordering, or on any other objects or values that may transiently - * change while computation is in progress; and except for forEach - * actions, should ideally be side-effect-free. - * - *

    - *
  • forEach: Perform a given action on each element. - * A variant form applies a given transformation on each element - * before performing the action.
  • - * - *
  • search: Return the first available non-null result of - * applying a given function on each element; skipping further - * search when a result is found.
  • - * - *
  • reduce: Accumulate each element. The supplied reduction - * function cannot rely on ordering (more formally, it should be - * both associative and commutative). There are five variants: - * - *
      - * - *
    • Plain reductions. (There is not a form of this method for - * (key, value) function arguments since there is no corresponding - * return type.)
    • - * - *
    • Mapped reductions that accumulate the results of a given - * function applied to each element.
    • - * - *
    • Reductions to scalar doubles, longs, and ints, using a - * given basis value.
    • - * - * - *
    - *
- * - *

The concurrency properties of bulk operations follow - * from those of ConcurrentHashMapV8: Any non-null result returned - * from {@code get(key)} and related access methods bears a - * happens-before relation with the associated insertion or - * update. The result of any bulk operation reflects the - * composition of these per-element relations (but is not - * necessarily atomic with respect to the map as a whole unless it - * is somehow known to be quiescent). Conversely, because keys - * and values in the map are never null, null serves as a reliable - * atomic indicator of the current lack of any result. To - * maintain this property, null serves as an implicit basis for - * all non-scalar reduction operations. For the double, long, and - * int versions, the basis should be one that, when combined with - * any other value, returns that other value (more formally, it - * should be the identity element for the reduction). Most common - * reductions have these properties; for example, computing a sum - * with basis 0 or a minimum with basis MAX_VALUE. - * - *

Search and transformation functions provided as arguments - * should similarly return null to indicate the lack of any result - * (in which case it is not used). In the case of mapped - * reductions, this also enables transformations to serve as - * filters, returning null (or, in the case of primitive - * specializations, the identity basis) if the element should not - * be combined. You can create compound transformations and - * filterings by composing them yourself under this "null means - * there is nothing there now" rule before using them in search or - * reduce operations. - * - *

Methods accepting and/or returning Entry arguments maintain - * key-value associations. They may be useful for example when - * finding the key for the greatest value. Note that "plain" Entry - * arguments can be supplied using {@code new - * AbstractMap.SimpleEntry(k,v)}. - * - *

Bulk operations may complete abruptly, throwing an - * exception encountered in the application of a supplied - * function. Bear in mind when handling such exceptions that other - * concurrently executing functions could also have thrown - * exceptions, or would have done so if the first exception had - * not occurred. - * - *

Parallel speedups for bulk operations compared to sequential - * processing are common but not guaranteed. Operations involving - * brief functions on small maps may execute more slowly than - * sequential loops if the underlying work to parallelize the - * computation is more expensive than the computation itself. - * Similarly, parallelization may not lead to much actual parallelism - * if all processors are busy performing unrelated tasks. - * - *

All arguments to all task methods must be non-null. - * - *

jsr166e note: During transition, this class - * uses nested functional interfaces with different names but the - * same forms as those expected for JDK8. - * - *

This class is a member of the - * - * Java Collections Framework. - * - * @since 1.5 - * @author Doug Lea - * @param the type of keys maintained by this map - * @param the type of mapped values - */ -public class ConcurrentHashMapV8 - implements ConcurrentMap, Serializable, ConcurrentHashMap { - private static final long serialVersionUID = 7249069246763182397L; - - /** - * A partitionable iterator. A Spliterator can be traversed - * directly, but can also be partitioned (before traversal) by - * creating another Spliterator that covers a non-overlapping - * portion of the elements, and so may be amenable to parallel - * execution. - * - *

This interface exports a subset of expected JDK8 - * functionality. - * - *

Sample usage: Here is one (of the several) ways to compute - * the sum of the values held in a map using the ForkJoin - * framework. As illustrated here, Spliterators are well suited to - * designs in which a task repeatedly splits off half its work - * into forked subtasks until small enough to process directly, - * and then joins these subtasks. Variants of this style can also - * be used in completion-based designs. - * - *

-     * {@code ConcurrentHashMapV8 m = ...
-     * // split as if have 8 * parallelism, for load balance
-     * int n = m.size();
-     * int p = aForkJoinPool.getParallelism() * 8;
-     * int split = (n < p)? n : p;
-     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
-     * // ...
-     * static class SumValues extends RecursiveTask {
-     *   final Spliterator s;
-     *   final int split;             // split while > 1
-     *   final SumValues nextJoin;    // records forked subtasks to join
-     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
-     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
-     *   }
-     *   public Long compute() {
-     *     long sum = 0;
-     *     SumValues subtasks = null; // fork subtasks
-     *     for (int s = split >>> 1; s > 0; s >>>= 1)
-     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
-     *     while (s.hasNext())        // directly process remaining elements
-     *       sum += s.next();
-     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
-     *       sum += t.join();         // collect subtask results
-     *     return sum;
-     *   }
-     * }
-     * }
- */ - public static interface Spliterator extends Iterator { - /** - * Returns a Spliterator covering approximately half of the - * elements, guaranteed not to overlap with those subsequently - * returned by this Spliterator. After invoking this method, - * the current Spliterator will not produce any of - * the elements of the returned Spliterator, but the two - * Spliterators together will produce all of the elements that - * would have been produced by this Spliterator had this - * method not been called. The exact number of elements - * produced by the returned Spliterator is not guaranteed, and - * may be zero (i.e., with {@code hasNext()} reporting {@code - * false}) if this Spliterator cannot be further split. - * - * @return a Spliterator covering approximately half of the - * elements - * @throws IllegalStateException if this Spliterator has - * already commenced traversing elements - */ - Spliterator split(); - } - - - /* - * Overview: - * - * The primary design goal of this hash table is to maintain - * concurrent readability (typically method get(), but also - * iterators and related methods) while minimizing update - * contention. Secondary goals are to keep space consumption about - * the same or better than java.util.HashMap, and to support high - * initial insertion rates on an empty table by many threads. - * - * Each key-value mapping is held in a Node. Because Node fields - * can contain special values, they are defined using plain Object - * types. Similarly in turn, all internal methods that use them - * work off Object types. And similarly, so do the internal - * methods of auxiliary iterator and view classes. All public - * generic typed methods relay in/out of these internal methods, - * supplying null-checks and casts as needed. This also allows - * many of the public methods to be factored into a smaller number - * of internal methods (although sadly not so for the five - * variants of put-related operations). The validation-based - * approach explained below leads to a lot of code sprawl because - * retry-control precludes factoring into smaller methods. - * - * The table is lazily initialized to a power-of-two size upon the - * first insertion. Each bin in the table normally contains a - * list of Nodes (most often, the list has only zero or one Node). - * Table accesses require volatile/atomic reads, writes, and - * CASes. Because there is no other way to arrange this without - * adding further indirections, we use intrinsics - * (sun.misc.Unsafe) operations. The lists of nodes within bins - * are always accurately traversable under volatile reads, so long - * as lookups check hash code and non-nullness of value before - * checking key equality. - * - * We use the top two bits of Node hash fields for control - * purposes -- they are available anyway because of addressing - * constraints. As explained further below, these top bits are - * used as follows: - * 00 - Normal - * 01 - Locked - * 11 - Locked and may have a thread waiting for lock - * 10 - Node is a forwarding node - * - * The lower 30 bits of each Node's hash field contain a - * transformation of the key's hash code, except for forwarding - * nodes, for which the lower bits are zero (and so always have - * hash field == MOVED). - * - * Insertion (via put or its variants) of the first node in an - * empty bin is performed by just CASing it to the bin. This is - * by far the most common case for put operations under most - * key/hash distributions. Other update operations (insert, - * delete, and replace) require locks. We do not want to waste - * the space required to associate a distinct lock object with - * each bin, so instead use the first node of a bin list itself as - * a lock. Blocking support for these locks relies on the builtin - * "synchronized" monitors. However, we also need a tryLock - * construction, so we overlay these by using bits of the Node - * hash field for lock control (see above), and so normally use - * builtin monitors only for blocking and signalling using - * wait/notifyAll constructions. See Node.tryAwaitLock. - * - * Using the first node of a list as a lock does not by itself - * suffice though: When a node is locked, any update must first - * validate that it is still the first node after locking it, and - * retry if not. Because new nodes are always appended to lists, - * once a node is first in a bin, it remains first until deleted - * or the bin becomes invalidated (upon resizing). However, - * operations that only conditionally update may inspect nodes - * until the point of update. This is a converse of sorts to the - * lazy locking technique described by Herlihy & Shavit. - * - * The main disadvantage of per-bin locks is that other update - * operations on other nodes in a bin list protected by the same - * lock can stall, for example when user equals() or mapping - * functions take a long time. However, statistically, under - * random hash codes, this is not a common problem. Ideally, the - * frequency of nodes in bins follows a Poisson distribution - * (http://en.wikipedia.org/wiki/Poisson_distribution) with a - * parameter of about 0.5 on average, given the resizing threshold - * of 0.75, although with a large variance because of resizing - * granularity. Ignoring variance, the expected occurrences of - * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The - * first values are: - * - * 0: 0.60653066 - * 1: 0.30326533 - * 2: 0.07581633 - * 3: 0.01263606 - * 4: 0.00157952 - * 5: 0.00015795 - * 6: 0.00001316 - * 7: 0.00000094 - * 8: 0.00000006 - * more: less than 1 in ten million - * - * Lock contention probability for two threads accessing distinct - * elements is roughly 1 / (8 * #elements) under random hashes. - * - * Actual hash code distributions encountered in practice - * sometimes deviate significantly from uniform randomness. This - * includes the case when N > (1<<30), so some keys MUST collide. - * Similarly for dumb or hostile usages in which multiple keys are - * designed to have identical hash codes. Also, although we guard - * against the worst effects of this (see method spread), sets of - * hashes may differ only in bits that do not impact their bin - * index for a given power-of-two mask. So we use a secondary - * strategy that applies when the number of nodes in a bin exceeds - * a threshold, and at least one of the keys implements - * Comparable. These TreeBins use a balanced tree to hold nodes - * (a specialized form of red-black trees), bounding search time - * to O(log N). Each search step in a TreeBin is around twice as - * slow as in a regular list, but given that N cannot exceed - * (1<<64) (before running out of addresses) this bounds search - * steps, lock hold times, etc, to reasonable constants (roughly - * 100 nodes inspected per operation worst case) so long as keys - * are Comparable (which is very common -- String, Long, etc). - * TreeBin nodes (TreeNodes) also maintain the same "next" - * traversal pointers as regular nodes, so can be traversed in - * iterators in the same way. - * - * The table is resized when occupancy exceeds a percentage - * threshold (nominally, 0.75, but see below). Only a single - * thread performs the resize (using field "sizeCtl", to arrange - * exclusion), but the table otherwise remains usable for reads - * and updates. Resizing proceeds by transferring bins, one by - * one, from the table to the next table. Because we are using - * power-of-two expansion, the elements from each bin must either - * stay at same index, or move with a power of two offset. We - * eliminate unnecessary node creation by catching cases where old - * nodes can be reused because their next fields won't change. On - * average, only about one-sixth of them need cloning when a table - * doubles. The nodes they replace will be garbage collectable as - * soon as they are no longer referenced by any reader thread that - * may be in the midst of concurrently traversing table. Upon - * transfer, the old table bin contains only a special forwarding - * node (with hash field "MOVED") that contains the next table as - * its key. On encountering a forwarding node, access and update - * operations restart, using the new table. - * - * Each bin transfer requires its bin lock. However, unlike other - * cases, a transfer can skip a bin if it fails to acquire its - * lock, and revisit it later (unless it is a TreeBin). Method - * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that - * have been skipped because of failure to acquire a lock, and - * blocks only if none are available (i.e., only very rarely). - * The transfer operation must also ensure that all accessible - * bins in both the old and new table are usable by any traversal. - * When there are no lock acquisition failures, this is arranged - * simply by proceeding from the last bin (table.length - 1) up - * towards the first. Upon seeing a forwarding node, traversals - * (see class Iter) arrange to move to the new table - * without revisiting nodes. However, when any node is skipped - * during a transfer, all earlier table bins may have become - * visible, so are initialized with a reverse-forwarding node back - * to the old table until the new ones are established. (This - * sometimes requires transiently locking a forwarding node, which - * is possible under the above encoding.) These more expensive - * mechanics trigger only when necessary. - * - * The traversal scheme also applies to partial traversals of - * ranges of bins (via an alternate Traverser constructor) - * to support partitioned aggregate operations. Also, read-only - * operations give up if ever forwarded to a null table, which - * provides support for shutdown-style clearing, which is also not - * currently implemented. - * - * Lazy table initialization minimizes footprint until first use, - * and also avoids resizings when the first operation is from a - * putAll, constructor with map argument, or deserialization. - * These cases attempt to override the initial capacity settings, - * but harmlessly fail to take effect in cases of races. - * - * The element count is maintained using a LongAdder, which avoids - * contention on updates but can encounter cache thrashing if read - * too frequently during concurrent access. To avoid reading so - * often, resizing is attempted either when a bin lock is - * contended, or upon adding to a bin already holding two or more - * nodes (checked before adding in the xIfAbsent methods, after - * adding in others). Under uniform hash distributions, the - * probability of this occurring at threshold is around 13%, - * meaning that only about 1 in 8 puts check threshold (and after - * resizing, many fewer do so). But this approximation has high - * variance for small table sizes, so we check on any collision - * for sizes <= 64. The bulk putAll operation further reduces - * contention by only committing count updates upon these size - * checks. - * - * Maintaining API and serialization compatibility with previous - * versions of this class introduces several oddities. Mainly: We - * leave untouched but unused constructor arguments refering to - * concurrencyLevel. We accept a loadFactor constructor argument, - * but apply it only to initial table capacity (which is the only - * time that we can guarantee to honor it.) We also declare an - * unused "Segment" class that is instantiated in minimal form - * only when serializing. - */ - - /* ---------------- Constants -------------- */ - - /** - * The largest possible table capacity. This value must be - * exactly 1<<30 to stay within Java array allocation and indexing - * bounds for power of two table sizes, and is further required - * because the top two bits of 32bit hash fields are used for - * control purposes. - */ - private static final int MAXIMUM_CAPACITY = 1 << 30; - - /** - * The default initial table capacity. Must be a power of 2 - * (i.e., at least 1) and at most MAXIMUM_CAPACITY. - */ - private static final int DEFAULT_CAPACITY = 16; - - /** - * The largest possible (non-power of two) array size. - * Needed by toArray and related methods. - */ - static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - /** - * The default concurrency level for this table. Unused but - * defined for compatibility with previous versions of this class. - */ - private static final int DEFAULT_CONCURRENCY_LEVEL = 16; - - /** - * The load factor for this table. Overrides of this value in - * constructors affect only the initial table capacity. The - * actual floating point value isn't normally used -- it is - * simpler to use expressions such as {@code n - (n >>> 2)} for - * the associated resizing threshold. - */ - private static final float LOAD_FACTOR = 0.75f; - - /** - * The buffer size for skipped bins during transfers. The - * value is arbitrary but should be large enough to avoid - * most locking stalls during resizes. - */ - private static final int TRANSFER_BUFFER_SIZE = 32; - - /** - * The bin count threshold for using a tree rather than list for a - * bin. The value reflects the approximate break-even point for - * using tree-based operations. - * Note that Doug's version defaults to 8, but when dealing with - * Ruby objects it is actually beneficial to avoid TreeNodes - * as long as possible as it usually means going into Ruby land. - */ - private static final int TREE_THRESHOLD = 16; - - /* - * Encodings for special uses of Node hash fields. See above for - * explanation. - */ - static final int MOVED = 0x80000000; // hash field for forwarding nodes - static final int LOCKED = 0x40000000; // set/tested only as a bit - static final int WAITING = 0xc0000000; // both bits set/tested together - static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash - - /* ---------------- Fields -------------- */ - - /** - * The array of bins. Lazily initialized upon first insertion. - * Size is always a power of two. Accessed directly by iterators. - */ - transient volatile Node[] table; - - /** - * The counter maintaining number of elements. - */ - private transient final LongAdder counter; - - /** - * Table initialization and resizing control. When negative, the - * table is being initialized or resized. Otherwise, when table is - * null, holds the initial table size to use upon creation, or 0 - * for default. After initialization, holds the next element count - * value upon which to resize the table. - */ - private transient volatile int sizeCtl; - - // views - private transient KeySetView keySet; - private transient ValuesView values; - private transient EntrySetView entrySet; - - /** For serialization compatibility. Null unless serialized; see below */ - private Segment[] segments; - - /* ---------------- Table element access -------------- */ - - /* - * Volatile access methods are used for table elements as well as - * elements of in-progress next table while resizing. Uses are - * null checked by callers, and implicitly bounds-checked, relying - * on the invariants that tab arrays have non-zero size, and all - * indices are masked with (tab.length - 1) which is never - * negative and always less than length. Note that, to be correct - * wrt arbitrary concurrency errors by users, bounds checks must - * operate on local variables, which accounts for some odd-looking - * inline assignments below. - */ - - static final Node tabAt(Node[] tab, int i) { // used by Iter - return (Node)UNSAFE.getObjectVolatile(tab, ((long)i< 1 ? 64 : 1; - - /** - * Spins a while if LOCKED bit set and this node is the first - * of its bin, and then sets WAITING bits on hash field and - * blocks (once) if they are still set. It is OK for this - * method to return even if lock is not available upon exit, - * which enables these simple single-wait mechanics. - * - * The corresponding signalling operation is performed within - * callers: Upon detecting that WAITING has been set when - * unlocking lock (via a failed CAS from non-waiting LOCKED - * state), unlockers acquire the sync lock and perform a - * notifyAll. - * - * The initial sanity check on tab and bounds is not currently - * necessary in the only usages of this method, but enables - * use in other future contexts. - */ - final void tryAwaitLock(Node[] tab, int i) { - if (tab != null && i >= 0 && i < tab.length) { // sanity check - int r = ThreadLocalRandom.current().nextInt(); // randomize spins - int spins = MAX_SPINS, h; - while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { - if (spins >= 0) { - r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift - if (r >= 0 && --spins == 0) - Thread.yield(); // yield before block - } - else if (casHash(h, h | WAITING)) { - synchronized (this) { - if (tabAt(tab, i) == this && - (hash & WAITING) == WAITING) { - try { - wait(); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - } - else - notifyAll(); // possibly won race vs signaller - } - break; - } - } - } - } - - // Unsafe mechanics for casHash - private static final sun.misc.Unsafe UNSAFE; - private static final long hashOffset; - - static { - try { - UNSAFE = getUnsafe(); - Class k = Node.class; - hashOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("hash")); - } catch (Exception e) { - throw new Error(e); - } - } - } - - /* ---------------- TreeBins -------------- */ - - /** - * Nodes for use in TreeBins - */ - static final class TreeNode extends Node { - TreeNode parent; // red-black tree links - TreeNode left; - TreeNode right; - TreeNode prev; // needed to unlink next upon deletion - boolean red; - - TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { - super(hash, key, val, next); - this.parent = parent; - } - } - - /** - * A specialized form of red-black tree for use in bins - * whose size exceeds a threshold. - * - * TreeBins use a special form of comparison for search and - * related operations (which is the main reason we cannot use - * existing collections such as TreeMaps). TreeBins contain - * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by getClass().getName() order, and then by Comparator order - * among elements of the same class. On lookup at a node, if - * elements are not comparable or compare as 0, both left and - * right children may need to be searched in the case of tied hash - * values. (This corresponds to the full list search that would be - * necessary if all elements were non-Comparable and had tied - * hashes.) The red-black balancing code is updated from - * pre-jdk-collections - * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) - * based in turn on Cormen, Leiserson, and Rivest "Introduction to - * Algorithms" (CLR). - * - * TreeBins also maintain a separate locking discipline than - * regular bins. Because they are forwarded via special MOVED - * nodes at bin heads (which can never change once established), - * we cannot use those nodes as locks. Instead, TreeBin - * extends AbstractQueuedSynchronizer to support a simple form of - * read-write lock. For update operations and table validation, - * the exclusive form of lock behaves in the same way as bin-head - * locks. However, lookups use shared read-lock mechanics to allow - * multiple readers in the absence of writers. Additionally, - * these lookups do not ever block: While the lock is not - * available, they proceed along the slow traversal path (via - * next-pointers) until the lock becomes available or the list is - * exhausted, whichever comes first. (These cases are not fast, - * but maximize aggregate expected throughput.) The AQS mechanics - * for doing this are straightforward. The lock state is held as - * AQS getState(). Read counts are negative; the write count (1) - * is positive. There are no signalling preferences among readers - * and writers. Since we don't need to export full Lock API, we - * just override the minimal AQS methods and use them directly. - */ - static final class TreeBin extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 2249069246763182397L; - transient TreeNode root; // root of tree - transient TreeNode first; // head of next-pointer list - - /* AQS overrides */ - public final boolean isHeldExclusively() { return getState() > 0; } - public final boolean tryAcquire(int ignore) { - if (compareAndSetState(0, 1)) { - setExclusiveOwnerThread(Thread.currentThread()); - return true; - } - return false; - } - public final boolean tryRelease(int ignore) { - setExclusiveOwnerThread(null); - setState(0); - return true; - } - public final int tryAcquireShared(int ignore) { - for (int c;;) { - if ((c = getState()) > 0) - return -1; - if (compareAndSetState(c, c -1)) - return 1; - } - } - public final boolean tryReleaseShared(int ignore) { - int c; - do {} while (!compareAndSetState(c = getState(), c + 1)); - return c == -1; - } - - /** From CLR */ - private void rotateLeft(TreeNode p) { - if (p != null) { - TreeNode r = p.right, pp, rl; - if ((rl = p.right = r.left) != null) - rl.parent = p; - if ((pp = r.parent = p.parent) == null) - root = r; - else if (pp.left == p) - pp.left = r; - else - pp.right = r; - r.left = p; - p.parent = r; - } - } - - /** From CLR */ - private void rotateRight(TreeNode p) { - if (p != null) { - TreeNode l = p.left, pp, lr; - if ((lr = p.left = l.right) != null) - lr.parent = p; - if ((pp = l.parent = p.parent) == null) - root = l; - else if (pp.right == p) - pp.right = l; - else - pp.left = l; - l.right = p; - p.parent = l; - } - } - - @SuppressWarnings("unchecked") final TreeNode getTreeNode - (int h, Object k, TreeNode p) { - return getTreeNode(h, (RubyObject)k, p); - } - - /** - * Returns the TreeNode (or null if not found) for the given key - * starting at given root. - */ - @SuppressWarnings("unchecked") final TreeNode getTreeNode - (int h, RubyObject k, TreeNode p) { - RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); - while (p != null) { - int dir, ph; RubyObject pk; RubyClass pc; - if ((ph = p.hash) == h) { - if ((pk = (RubyObject)p.key) == k || k.equals(pk)) - return p; - if (c != (pc = (RubyClass)pk.getMetaClass()) || - kNotComparable || - (dir = rubyCompare(k, pk)) == 0) { - dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); - if (dir == 0) { // if still stuck, need to check both sides - TreeNode r = null, pl, pr; - // try to recurse on the right - if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) - return r; - // try to continue iterating on the left side - else if ((pl = p.left) != null && h <= pl.hash) - dir = -1; - else // no matching node found - return null; - } - } - } - else - dir = (h < ph) ? -1 : 1; - p = (dir > 0) ? p.right : p.left; - } - return null; - } - - int rubyCompare(RubyObject l, RubyObject r) { - ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); - IRubyObject result; - try { - result = l.callMethod(context, "<=>", r); - } catch (RaiseException e) { - // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys - if (context.runtime.getNoMethodError().isInstance(e.getException())) { - return 0; - } - throw e; - } - - return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); - } - - /** - * Wrapper for getTreeNode used by CHM.get. Tries to obtain - * read-lock to call getTreeNode, but during failure to get - * lock, searches along next links. - */ - final Object getValue(int h, Object k) { - Node r = null; - int c = getState(); // Must read lock state first - for (Node e = first; e != null; e = e.next) { - if (c <= 0 && compareAndSetState(c, c - 1)) { - try { - r = getTreeNode(h, k, root); - } finally { - releaseShared(0); - } - break; - } - else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { - r = e; - break; - } - else - c = getState(); - } - return r == null ? null : r.val; - } - - @SuppressWarnings("unchecked") final TreeNode putTreeNode - (int h, Object k, Object v) { - return putTreeNode(h, (RubyObject)k, v); - } - - /** - * Finds or adds a node. - * @return null if added - */ - @SuppressWarnings("unchecked") final TreeNode putTreeNode - (int h, RubyObject k, Object v) { - RubyClass c = k.getMetaClass(); - boolean kNotComparable = !k.respondsTo("<=>"); - TreeNode pp = root, p = null; - int dir = 0; - while (pp != null) { // find existing node or leaf to insert at - int ph; RubyObject pk; RubyClass pc; - p = pp; - if ((ph = p.hash) == h) { - if ((pk = (RubyObject)p.key) == k || k.equals(pk)) - return p; - if (c != (pc = pk.getMetaClass()) || - kNotComparable || - (dir = rubyCompare(k, pk)) == 0) { - dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); - if (dir == 0) { // if still stuck, need to check both sides - TreeNode r = null, pr; - // try to recurse on the right - if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) - return r; - else // continue descending down the left subtree - dir = -1; - } - } - } - else - dir = (h < ph) ? -1 : 1; - pp = (dir > 0) ? p.right : p.left; - } - - TreeNode f = first; - TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); - if (p == null) - root = x; - else { // attach and rebalance; adapted from CLR - TreeNode xp, xpp; - if (f != null) - f.prev = x; - if (dir <= 0) - p.left = x; - else - p.right = x; - x.red = true; - while (x != null && (xp = x.parent) != null && xp.red && - (xpp = xp.parent) != null) { - TreeNode xppl = xpp.left; - if (xp == xppl) { - TreeNode y = xpp.right; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } - else { - if (x == xp.right) { - rotateLeft(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateRight(xpp); - } - } - } - } - else { - TreeNode y = xppl; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } - else { - if (x == xp.left) { - rotateRight(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateLeft(xpp); - } - } - } - } - } - TreeNode r = root; - if (r != null && r.red) - r.red = false; - } - return null; - } - - /** - * Removes the given node, that must be present before this - * call. This is messier than typical red-black deletion code - * because we cannot swap the contents of an interior node - * with a leaf successor that is pinned by "next" pointers - * that are accessible independently of lock. So instead we - * swap the tree linkages. - */ - final void deleteTreeNode(TreeNode p) { - TreeNode next = (TreeNode)p.next; // unlink traversal pointers - TreeNode pred = p.prev; - if (pred == null) - first = next; - else - pred.next = next; - if (next != null) - next.prev = pred; - TreeNode replacement; - TreeNode pl = p.left; - TreeNode pr = p.right; - if (pl != null && pr != null) { - TreeNode s = pr, sl; - while ((sl = s.left) != null) // find successor - s = sl; - boolean c = s.red; s.red = p.red; p.red = c; // swap colors - TreeNode sr = s.right; - TreeNode pp = p.parent; - if (s == pr) { // p was s's direct parent - p.parent = s; - s.right = p; - } - else { - TreeNode sp = s.parent; - if ((p.parent = sp) != null) { - if (s == sp.left) - sp.left = p; - else - sp.right = p; - } - if ((s.right = pr) != null) - pr.parent = s; - } - p.left = null; - if ((p.right = sr) != null) - sr.parent = p; - if ((s.left = pl) != null) - pl.parent = s; - if ((s.parent = pp) == null) - root = s; - else if (p == pp.left) - pp.left = s; - else - pp.right = s; - replacement = sr; - } - else - replacement = (pl != null) ? pl : pr; - TreeNode pp = p.parent; - if (replacement == null) { - if (pp == null) { - root = null; - return; - } - replacement = p; - } - else { - replacement.parent = pp; - if (pp == null) - root = replacement; - else if (p == pp.left) - pp.left = replacement; - else - pp.right = replacement; - p.left = p.right = p.parent = null; - } - if (!p.red) { // rebalance, from CLR - TreeNode x = replacement; - while (x != null) { - TreeNode xp, xpl; - if (x.red || (xp = x.parent) == null) { - x.red = false; - break; - } - if (x == (xpl = xp.left)) { - TreeNode sib = xp.right; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateLeft(xp); - sib = (xp = x.parent) == null ? null : xp.right; - } - if (sib == null) - x = xp; - else { - TreeNode sl = sib.left, sr = sib.right; - if ((sr == null || !sr.red) && - (sl == null || !sl.red)) { - sib.red = true; - x = xp; - } - else { - if (sr == null || !sr.red) { - if (sl != null) - sl.red = false; - sib.red = true; - rotateRight(sib); - sib = (xp = x.parent) == null ? null : xp.right; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sr = sib.right) != null) - sr.red = false; - } - if (xp != null) { - xp.red = false; - rotateLeft(xp); - } - x = root; - } - } - } - else { // symmetric - TreeNode sib = xpl; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateRight(xp); - sib = (xp = x.parent) == null ? null : xp.left; - } - if (sib == null) - x = xp; - else { - TreeNode sl = sib.left, sr = sib.right; - if ((sl == null || !sl.red) && - (sr == null || !sr.red)) { - sib.red = true; - x = xp; - } - else { - if (sl == null || !sl.red) { - if (sr != null) - sr.red = false; - sib.red = true; - rotateLeft(sib); - sib = (xp = x.parent) == null ? null : xp.left; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sl = sib.left) != null) - sl.red = false; - } - if (xp != null) { - xp.red = false; - rotateRight(xp); - } - x = root; - } - } - } - } - } - if (p == replacement && (pp = p.parent) != null) { - if (p == pp.left) // detach pointers - pp.left = null; - else if (p == pp.right) - pp.right = null; - p.parent = null; - } - } - } - - /* ---------------- Collision reduction methods -------------- */ - - /** - * Spreads higher bits to lower, and also forces top 2 bits to 0. - * Because the table uses power-of-two masking, sets of hashes - * that vary only in bits above the current mask will always - * collide. (Among known examples are sets of Float keys holding - * consecutive whole numbers in small tables.) To counter this, - * we apply a transform that spreads the impact of higher bits - * downward. There is a tradeoff between speed, utility, and - * quality of bit-spreading. Because many common sets of hashes - * are already reasonably distributed across bits (so don't benefit - * from spreading), and because we use trees to handle large sets - * of collisions in bins, we don't need excessively high quality. - */ - private static final int spread(int h) { - h ^= (h >>> 18) ^ (h >>> 12); - return (h ^ (h >>> 10)) & HASH_BITS; - } - - /** - * Replaces a list bin with a tree bin. Call only when locked. - * Fails to replace if the given key is non-comparable or table - * is, or needs, resizing. - */ - private final void replaceWithTreeBin(Node[] tab, int index, Object key) { - if ((key instanceof Comparable) && - (tab.length >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { - TreeBin t = new TreeBin(); - for (Node e = tabAt(tab, index); e != null; e = e.next) - t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); - setTabAt(tab, index, new Node(MOVED, t, null, null)); - } - } - - /* ---------------- Internal access and update methods -------------- */ - - /** Implementation for get and containsKey */ - private final Object internalGet(Object k) { - int h = spread(k.hashCode()); - retry: for (Node[] tab = table; tab != null;) { - Node e, p; Object ek, ev; int eh; // locals to read fields once - for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) { - if ((eh = e.hash) == MOVED) { - if ((ek = e.key) instanceof TreeBin) // search TreeBin - return ((TreeBin)ek).getValue(h, k); - else { // restart with new table - tab = (Node[])ek; - continue retry; - } - } - else if ((eh & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - } - break; - } - return null; - } - - /** - * Implementation for the four public remove/replace methods: - * Replaces node value with v, conditional upon match of cv if - * non-null. If resulting value is null, delete. - */ - private final Object internalReplace(Object k, Object v, Object cv) { - int h = spread(k.hashCode()); - Object oldVal = null; - for (Node[] tab = table;;) { - Node f; int i, fh; Object fk; - if (tab == null || - (f = tabAt(tab, i = (tab.length - 1) & h)) == null) - break; - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - boolean deleted = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) { - Object pv = p.val; - if (cv == null || cv == pv || cv.equals(pv)) { - oldVal = pv; - if ((p.val = v) == null) { - deleted = true; - t.deleteTreeNode(p); - } - } - } - } - } finally { - t.release(0); - } - if (validated) { - if (deleted) - counter.add(-1L); - break; - } - } - else - tab = (Node[])fk; - } - else if ((fh & HASH_BITS) != h && f.next == null) // precheck - break; // rules out possible existence - else if ((fh & LOCKED) != 0) { - checkForResize(); // try resizing if can't get lock - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - boolean validated = false; - boolean deleted = false; - try { - if (tabAt(tab, i) == f) { - validated = true; - for (Node e = f, pred = null;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - ((ev = e.val) != null) && - ((ek = e.key) == k || k.equals(ek))) { - if (cv == null || cv == ev || cv.equals(ev)) { - oldVal = ev; - if ((e.val = v) == null) { - deleted = true; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - } - break; - } - pred = e; - if ((e = e.next) == null) - break; - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (validated) { - if (deleted) - counter.add(-1L); - break; - } - } - } - return oldVal; - } - - /* - * Internal versions of the six insertion methods, each a - * little more complicated than the last. All have - * the same basic structure as the first (internalPut): - * 1. If table uninitialized, create - * 2. If bin empty, try to CAS new node - * 3. If bin stale, use new table - * 4. if bin converted to TreeBin, validate and relay to TreeBin methods - * 5. Lock and validate; if valid, scan and add or update - * - * The others interweave other checks and/or alternative actions: - * * Plain put checks for and performs resize after insertion. - * * putIfAbsent prescans for mapping without lock (and fails to add - * if present), which also makes pre-emptive resize checks worthwhile. - * * computeIfAbsent extends form used in putIfAbsent with additional - * mechanics to deal with, calls, potential exceptions and null - * returns from function call. - * * compute uses the same function-call mechanics, but without - * the prescans - * * merge acts as putIfAbsent in the absent case, but invokes the - * update function if present - * * putAll attempts to pre-allocate enough table space - * and more lazily performs count updates and checks. - * - * Someday when details settle down a bit more, it might be worth - * some factoring to reduce sprawl. - */ - - /** Implementation for put */ - private final Object internalPut(Object k, Object v) { - int h = spread(k.hashCode()); - int count = 0; - for (Node[] tab = table;;) { - int i; Node f; int fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) - break; // no lock when adding to empty bin - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - Object oldVal = null; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 2; - TreeNode p = t.putTreeNode(h, k, v); - if (p != null) { - oldVal = p.val; - p.val = v; - } - } - } finally { - t.release(0); - } - if (count != 0) { - if (oldVal != null) - return oldVal; - break; - } - } - else - tab = (Node[])fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - Object oldVal = null; - try { // needed in case equals() throws - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - oldVal = ev; - e.val = v; - break; - } - Node last = e; - if ((e = e.next) == null) { - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { // unlock and signal if needed - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (oldVal != null) - return oldVal; - if (tab.length <= 64) - count = 2; - break; - } - } - } - counter.add(1L); - if (count > 1) - checkForResize(); - return null; - } - - /** Implementation for putIfAbsent */ - private final Object internalPutIfAbsent(Object k, Object v) { - int h = spread(k.hashCode()); - int count = 0; - for (Node[] tab = table;;) { - int i; Node f; int fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - Object oldVal = null; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 2; - TreeNode p = t.putTreeNode(h, k, v); - if (p != null) - oldVal = p.val; - } - } finally { - t.release(0); - } - if (count != 0) { - if (oldVal != null) - return oldVal; - break; - } - } - else - tab = (Node[])fk; - } - else if ((fh & HASH_BITS) == h && (fv = f.val) != null && - ((fk = f.key) == k || k.equals(fk))) - return fv; - else { - Node g = f.next; - if (g != null) { // at least 2 nodes -- search and maybe resize - for (Node e = g;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - if ((e = e.next) == null) { - checkForResize(); - break; - } - } - } - if (((fh = f.hash) & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { - Object oldVal = null; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - oldVal = ev; - break; - } - Node last = e; - if ((e = e.next) == null) { - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (oldVal != null) - return oldVal; - if (tab.length <= 64) - count = 2; - break; - } - } - } - } - counter.add(1L); - if (count > 1) - checkForResize(); - return null; - } - - /** Implementation for computeIfAbsent */ - private final Object internalComputeIfAbsent(K k, - Fun mf) { - int h = spread(k.hashCode()); - Object val = null; - int count = 0; - for (Node[] tab = table;;) { - Node f; int i, fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { - Node node = new Node(fh = h | LOCKED, k, null, null); - if (casTabAt(tab, i, null, node)) { - count = 1; - try { - if ((val = mf.apply(k)) != null) - node.val = val; - } finally { - if (val == null) - setTabAt(tab, i, null); - if (!node.casHash(fh, h)) { - node.hash = h; - synchronized (node) { node.notifyAll(); }; - } - } - } - if (count != 0) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean added = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) - val = p.val; - else if ((val = mf.apply(k)) != null) { - added = true; - count = 2; - t.putTreeNode(h, k, val); - } - } - } finally { - t.release(0); - } - if (count != 0) { - if (!added) - return val; - break; - } - } - else - tab = (Node[])fk; - } - else if ((fh & HASH_BITS) == h && (fv = f.val) != null && - ((fk = f.key) == k || k.equals(fk))) - return fv; - else { - Node g = f.next; - if (g != null) { - for (Node e = g;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - if ((e = e.next) == null) { - checkForResize(); - break; - } - } - } - if (((fh = f.hash) & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { - boolean added = false; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = ev; - break; - } - Node last = e; - if ((e = e.next) == null) { - if ((val = mf.apply(k)) != null) { - added = true; - last.next = new Node(h, k, val, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - } - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (!added) - return val; - if (tab.length <= 64) - count = 2; - break; - } - } - } - } - if (val != null) { - counter.add(1L); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for compute */ - @SuppressWarnings("unchecked") private final Object internalCompute - (K k, boolean onlyIfPresent, BiFun mf) { - int h = spread(k.hashCode()); - Object val = null; - int delta = 0; - int count = 0; - for (Node[] tab = table;;) { - Node f; int i, fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { - if (onlyIfPresent) - break; - Node node = new Node(fh = h | LOCKED, k, null, null); - if (casTabAt(tab, i, null, node)) { - try { - count = 1; - if ((val = mf.apply(k, null)) != null) { - node.val = val; - delta = 1; - } - } finally { - if (delta == 0) - setTabAt(tab, i, null); - if (!node.casHash(fh, h)) { - node.hash = h; - synchronized (node) { node.notifyAll(); }; - } - } - } - if (count != 0) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - Object pv; - if (p == null) { - if (onlyIfPresent) - break; - pv = null; - } else - pv = p.val; - if ((val = mf.apply(k, (V)pv)) != null) { - if (p != null) - p.val = val; - else { - count = 2; - delta = 1; - t.putTreeNode(h, k, val); - } - } - else if (p != null) { - delta = -1; - t.deleteTreeNode(p); - } - } - } finally { - t.release(0); - } - if (count != 0) - break; - } - else - tab = (Node[])fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f, pred = null;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = mf.apply(k, (V)ev); - if (val != null) - e.val = val; - else { - delta = -1; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - break; - } - pred = e; - if ((e = e.next) == null) { - if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { - pred.next = new Node(h, k, val, null); - delta = 1; - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - } - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (tab.length <= 64) - count = 2; - break; - } - } - } - if (delta != 0) { - counter.add((long)delta); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for merge */ - @SuppressWarnings("unchecked") private final Object internalMerge - (K k, V v, BiFun mf) { - int h = spread(k.hashCode()); - Object val = null; - int delta = 0; - int count = 0; - for (Node[] tab = table;;) { - int i; Node f; int fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) { - delta = 1; - val = v; - break; - } - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - val = (p == null) ? v : mf.apply((V)p.val, v); - if (val != null) { - if (p != null) - p.val = val; - else { - count = 2; - delta = 1; - t.putTreeNode(h, k, val); - } - } - else if (p != null) { - delta = -1; - t.deleteTreeNode(p); - } - } - } finally { - t.release(0); - } - if (count != 0) - break; - } - else - tab = (Node[])fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f, pred = null;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = mf.apply((V)ev, v); - if (val != null) - e.val = val; - else { - delta = -1; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - break; - } - pred = e; - if ((e = e.next) == null) { - val = v; - pred.next = new Node(h, k, val, null); - delta = 1; - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (tab.length <= 64) - count = 2; - break; - } - } - } - if (delta != 0) { - counter.add((long)delta); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for putAll */ - private final void internalPutAll(Map m) { - tryPresize(m.size()); - long delta = 0L; // number of uncommitted additions - boolean npe = false; // to throw exception on exit for nulls - try { // to clean up counts on other exceptions - for (Map.Entry entry : m.entrySet()) { - Object k, v; - if (entry == null || (k = entry.getKey()) == null || - (v = entry.getValue()) == null) { - npe = true; - break; - } - int h = spread(k.hashCode()); - for (Node[] tab = table;;) { - int i; Node f; int fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){ - if (casTabAt(tab, i, null, new Node(h, k, v, null))) { - ++delta; - break; - } - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) - p.val = v; - else { - t.putTreeNode(h, k, v); - ++delta; - } - } - } finally { - t.release(0); - } - if (validated) - break; - } - else - tab = (Node[])fk; - } - else if ((fh & LOCKED) != 0) { - counter.add(delta); - delta = 0L; - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - int count = 0; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - e.val = v; - break; - } - Node last = e; - if ((e = e.next) == null) { - ++delta; - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (count > 1) { - counter.add(delta); - delta = 0L; - checkForResize(); - } - break; - } - } - } - } - } finally { - if (delta != 0) - counter.add(delta); - } - if (npe) - throw new NullPointerException(); - } - - /* ---------------- Table Initialization and Resizing -------------- */ - - /** - * Returns a power of two table size for the given desired capacity. - * See Hackers Delight, sec 3.2 - */ - private static final int tableSizeFor(int c) { - int n = c - 1; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; - } - - /** - * Initializes table, using the size recorded in sizeCtl. - */ - private final Node[] initTable() { - Node[] tab; int sc; - while ((tab = table) == null) { - if ((sc = sizeCtl) < 0) - Thread.yield(); // lost initialization race; just spin - else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { - try { - if ((tab = table) == null) { - int n = (sc > 0) ? sc : DEFAULT_CAPACITY; - tab = table = new Node[n]; - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - break; - } - } - return tab; - } - - /** - * If table is too small and not already resizing, creates next - * table and transfers bins. Rechecks occupancy after a transfer - * to see if another resize is already needed because resizings - * are lagging additions. - */ - private final void checkForResize() { - Node[] tab; int n, sc; - while ((tab = table) != null && - (n = tab.length) < MAXIMUM_CAPACITY && - (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && - UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { - try { - if (tab == table) { - table = rebuild(tab); - sc = (n << 1) - (n >>> 1); - } - } finally { - sizeCtl = sc; - } - } - } - - /** - * Tries to presize table to accommodate the given number of elements. - * - * @param size number of elements (doesn't need to be perfectly accurate) - */ - private final void tryPresize(int size) { - int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : - tableSizeFor(size + (size >>> 1) + 1); - int sc; - while ((sc = sizeCtl) >= 0) { - Node[] tab = table; int n; - if (tab == null || (n = tab.length) == 0) { - n = (sc > c) ? sc : c; - if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { - try { - if (table == tab) { - table = new Node[n]; - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - } - } - else if (c <= sc || n >= MAXIMUM_CAPACITY) - break; - else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { - try { - if (table == tab) { - table = rebuild(tab); - sc = (n << 1) - (n >>> 1); - } - } finally { - sizeCtl = sc; - } - } - } - } - - /* - * Moves and/or copies the nodes in each bin to new table. See - * above for explanation. - * - * @return the new table - */ - private static final Node[] rebuild(Node[] tab) { - int n = tab.length; - Node[] nextTab = new Node[n << 1]; - Node fwd = new Node(MOVED, nextTab, null, null); - int[] buffer = null; // holds bins to revisit; null until needed - Node rev = null; // reverse forwarder; null until needed - int nbuffered = 0; // the number of bins in buffer list - int bufferIndex = 0; // buffer index of current buffered bin - int bin = n - 1; // current non-buffered bin or -1 if none - - for (int i = bin;;) { // start upwards sweep - int fh; Node f; - if ((f = tabAt(tab, i)) == null) { - if (bin >= 0) { // Unbuffered; no lock needed (or available) - if (!casTabAt(tab, i, f, fwd)) - continue; - } - else { // transiently use a locked forwarding node - Node g = new Node(MOVED|LOCKED, nextTab, null, null); - if (!casTabAt(tab, i, f, g)) - continue; - setTabAt(nextTab, i, null); - setTabAt(nextTab, i + n, null); - setTabAt(tab, i, fwd); - if (!g.casHash(MOVED|LOCKED, MOVED)) { - g.hash = MOVED; - synchronized (g) { g.notifyAll(); } - } - } - } - else if ((fh = f.hash) == MOVED) { - Object fk = f.key; - if (fk instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - splitTreeBin(nextTab, i, t); - setTabAt(tab, i, fwd); - } - } finally { - t.release(0); - } - if (!validated) - continue; - } - } - else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { - boolean validated = false; - try { // split to lo and hi lists; copying as needed - if (tabAt(tab, i) == f) { - validated = true; - splitBin(nextTab, i, f); - setTabAt(tab, i, fwd); - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (!validated) - continue; - } - else { - if (buffer == null) // initialize buffer for revisits - buffer = new int[TRANSFER_BUFFER_SIZE]; - if (bin < 0 && bufferIndex > 0) { - int j = buffer[--bufferIndex]; - buffer[bufferIndex] = i; - i = j; // swap with another bin - continue; - } - if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { - f.tryAwaitLock(tab, i); - continue; // no other options -- block - } - if (rev == null) // initialize reverse-forwarder - rev = new Node(MOVED, tab, null, null); - if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) - continue; // recheck before adding to list - buffer[nbuffered++] = i; - setTabAt(nextTab, i, rev); // install place-holders - setTabAt(nextTab, i + n, rev); - } - - if (bin > 0) - i = --bin; - else if (buffer != null && nbuffered > 0) { - bin = -1; - i = buffer[bufferIndex = --nbuffered]; - } - else - return nextTab; - } - } - - /** - * Splits a normal bin with list headed by e into lo and hi parts; - * installs in given table. - */ - private static void splitBin(Node[] nextTab, int i, Node e) { - int bit = nextTab.length >>> 1; // bit to split on - int runBit = e.hash & bit; - Node lastRun = e, lo = null, hi = null; - for (Node p = e.next; p != null; p = p.next) { - int b = p.hash & bit; - if (b != runBit) { - runBit = b; - lastRun = p; - } - } - if (runBit == 0) - lo = lastRun; - else - hi = lastRun; - for (Node p = e; p != lastRun; p = p.next) { - int ph = p.hash & HASH_BITS; - Object pk = p.key, pv = p.val; - if ((ph & bit) == 0) - lo = new Node(ph, pk, pv, lo); - else - hi = new Node(ph, pk, pv, hi); - } - setTabAt(nextTab, i, lo); - setTabAt(nextTab, i + bit, hi); - } - - /** - * Splits a tree bin into lo and hi parts; installs in given table. - */ - private static void splitTreeBin(Node[] nextTab, int i, TreeBin t) { - int bit = nextTab.length >>> 1; - TreeBin lt = new TreeBin(); - TreeBin ht = new TreeBin(); - int lc = 0, hc = 0; - for (Node e = t.first; e != null; e = e.next) { - int h = e.hash & HASH_BITS; - Object k = e.key, v = e.val; - if ((h & bit) == 0) { - ++lc; - lt.putTreeNode(h, k, v); - } - else { - ++hc; - ht.putTreeNode(h, k, v); - } - } - Node ln, hn; // throw away trees if too small - if (lc <= (TREE_THRESHOLD >>> 1)) { - ln = null; - for (Node p = lt.first; p != null; p = p.next) - ln = new Node(p.hash, p.key, p.val, ln); - } - else - ln = new Node(MOVED, lt, null, null); - setTabAt(nextTab, i, ln); - if (hc <= (TREE_THRESHOLD >>> 1)) { - hn = null; - for (Node p = ht.first; p != null; p = p.next) - hn = new Node(p.hash, p.key, p.val, hn); - } - else - hn = new Node(MOVED, ht, null, null); - setTabAt(nextTab, i + bit, hn); - } - - /** - * Implementation for clear. Steps through each bin, removing all - * nodes. - */ - private final void internalClear() { - long delta = 0L; // negative number of deletions - int i = 0; - Node[] tab = table; - while (tab != null && i < tab.length) { - int fh; Object fk; - Node f = tabAt(tab, i); - if (f == null) - ++i; - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - for (Node p = t.first; p != null; p = p.next) { - if (p.val != null) { // (currently always true) - p.val = null; - --delta; - } - } - t.first = null; - t.root = null; - ++i; - } - } finally { - t.release(0); - } - } - else - tab = (Node[])fk; - } - else if ((fh & LOCKED) != 0) { - counter.add(delta); // opportunistically update count - delta = 0L; - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - for (Node e = f; e != null; e = e.next) { - if (e.val != null) { // (currently always true) - e.val = null; - --delta; - } - } - setTabAt(tab, i, null); - ++i; - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - } - } - if (delta != 0) - counter.add(delta); - } - - /* ----------------Table Traversal -------------- */ - - /** - * Encapsulates traversal for methods such as containsValue; also - * serves as a base class for other iterators and bulk tasks. - * - * At each step, the iterator snapshots the key ("nextKey") and - * value ("nextVal") of a valid node (i.e., one that, at point of - * snapshot, has a non-null user value). Because val fields can - * change (including to null, indicating deletion), field nextVal - * might not be accurate at point of use, but still maintains the - * weak consistency property of holding a value that was once - * valid. To support iterator.remove, the nextKey field is not - * updated (nulled out) when the iterator cannot advance. - * - * Internal traversals directly access these fields, as in: - * {@code while (it.advance() != null) { process(it.nextKey); }} - * - * Exported iterators must track whether the iterator has advanced - * (in hasNext vs next) (by setting/checking/nulling field - * nextVal), and then extract key, value, or key-value pairs as - * return values of next(). - * - * The iterator visits once each still-valid node that was - * reachable upon iterator construction. It might miss some that - * were added to a bin after the bin was visited, which is OK wrt - * consistency guarantees. Maintaining this property in the face - * of possible ongoing resizes requires a fair amount of - * bookkeeping state that is difficult to optimize away amidst - * volatile accesses. Even so, traversal maintains reasonable - * throughput. - * - * Normally, iteration proceeds bin-by-bin traversing lists. - * However, if the table has been resized, then all future steps - * must traverse both the bin at the current index as well as at - * (index + baseSize); and so on for further resizings. To - * paranoically cope with potential sharing by users of iterators - * across threads, iteration terminates if a bounds checks fails - * for a table read. - * - * This class extends ForkJoinTask to streamline parallel - * iteration in bulk operations (see BulkTask). This adds only an - * int of space overhead, which is close enough to negligible in - * cases where it is not needed to not worry about it. Because - * ForkJoinTask is Serializable, but iterators need not be, we - * need to add warning suppressions. - */ - @SuppressWarnings("serial") static class Traverser { - final ConcurrentHashMapV8 map; - Node next; // the next entry to use - K nextKey; // cached key field of next - V nextVal; // cached val field of next - Node[] tab; // current table; updated if resized - int index; // index of bin to use next - int baseIndex; // current index of initial table - int baseLimit; // index bound for initial table - int baseSize; // initial table size - - /** Creates iterator for all entries in the table. */ - Traverser(ConcurrentHashMapV8 map) { - this.map = map; - } - - /** Creates iterator for split() methods */ - Traverser(Traverser it) { - ConcurrentHashMapV8 m; Node[] t; - if ((m = this.map = it.map) == null) - t = null; - else if ((t = it.tab) == null && // force parent tab initialization - (t = it.tab = m.table) != null) - it.baseLimit = it.baseSize = t.length; - this.tab = t; - this.baseSize = it.baseSize; - it.baseLimit = this.index = this.baseIndex = - ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; - } - - /** - * Advances next; returns nextVal or null if terminated. - * See above for explanation. - */ - final V advance() { - Node e = next; - V ev = null; - outer: do { - if (e != null) // advance past used/skipped node - e = e.next; - while (e == null) { // get to next non-null bin - ConcurrentHashMapV8 m; - Node[] t; int b, i, n; Object ek; // checks must use locals - if ((t = tab) != null) - n = t.length; - else if ((m = map) != null && (t = tab = m.table) != null) - n = baseLimit = baseSize = t.length; - else - break outer; - if ((b = baseIndex) >= baseLimit || - (i = index) < 0 || i >= n) - break outer; - if ((e = tabAt(t, i)) != null && e.hash == MOVED) { - if ((ek = e.key) instanceof TreeBin) - e = ((TreeBin)ek).first; - else { - tab = (Node[])ek; - continue; // restarts due to null val - } - } // visit upper slots if present - index = (i += baseSize) < n ? i : (baseIndex = b + 1); - } - nextKey = (K) e.key; - } while ((ev = (V) e.val) == null); // skip deleted or special nodes - next = e; - return nextVal = ev; - } - - public final void remove() { - Object k = nextKey; - if (k == null && (advance() == null || (k = nextKey) == null)) - throw new IllegalStateException(); - map.internalReplace(k, null, null); - } - - public final boolean hasNext() { - return nextVal != null || advance() != null; - } - - public final boolean hasMoreElements() { return hasNext(); } - public final void setRawResult(Object x) { } - public R getRawResult() { return null; } - public boolean exec() { return true; } - } - - /* ---------------- Public operations -------------- */ - - /** - * Creates a new, empty map with the default initial table size (16). - */ - public ConcurrentHashMapV8() { - this.counter = new LongAdder(); - } - - /** - * Creates a new, empty map with an initial table size - * accommodating the specified number of elements without the need - * to dynamically resize. - * - * @param initialCapacity The implementation performs internal - * sizing to accommodate this many elements. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative - */ - public ConcurrentHashMapV8(int initialCapacity) { - if (initialCapacity < 0) - throw new IllegalArgumentException(); - int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? - MAXIMUM_CAPACITY : - tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); - this.counter = new LongAdder(); - this.sizeCtl = cap; - } - - /** - * Creates a new map with the same mappings as the given map. - * - * @param m the map - */ - public ConcurrentHashMapV8(Map m) { - this.counter = new LongAdder(); - this.sizeCtl = DEFAULT_CAPACITY; - internalPutAll(m); - } - - /** - * Creates a new, empty map with an initial table size based on - * the given number of elements ({@code initialCapacity}) and - * initial table density ({@code loadFactor}). - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements, - * given the specified load factor. - * @param loadFactor the load factor (table density) for - * establishing the initial table size - * @throws IllegalArgumentException if the initial capacity of - * elements is negative or the load factor is nonpositive - * - * @since 1.6 - */ - public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { - this(initialCapacity, loadFactor, 1); - } - - /** - * Creates a new, empty map with an initial table size based on - * the given number of elements ({@code initialCapacity}), table - * density ({@code loadFactor}), and number of concurrently - * updating threads ({@code concurrencyLevel}). - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements, - * given the specified load factor. - * @param loadFactor the load factor (table density) for - * establishing the initial table size - * @param concurrencyLevel the estimated number of concurrently - * updating threads. The implementation may use this value as - * a sizing hint. - * @throws IllegalArgumentException if the initial capacity is - * negative or the load factor or concurrencyLevel are - * nonpositive - */ - public ConcurrentHashMapV8(int initialCapacity, - float loadFactor, int concurrencyLevel) { - if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) - throw new IllegalArgumentException(); - if (initialCapacity < concurrencyLevel) // Use at least as many bins - initialCapacity = concurrencyLevel; // as estimated threads - long size = (long)(1.0 + (long)initialCapacity / loadFactor); - int cap = (size >= (long)MAXIMUM_CAPACITY) ? - MAXIMUM_CAPACITY : tableSizeFor((int)size); - this.counter = new LongAdder(); - this.sizeCtl = cap; - } - - /** - * Creates a new {@link Set} backed by a ConcurrentHashMapV8 - * from the given type to {@code Boolean.TRUE}. - * - * @return the new set - */ - public static KeySetView newKeySet() { - return new KeySetView(new ConcurrentHashMapV8(), - Boolean.TRUE); - } - - /** - * Creates a new {@link Set} backed by a ConcurrentHashMapV8 - * from the given type to {@code Boolean.TRUE}. - * - * @param initialCapacity The implementation performs internal - * sizing to accommodate this many elements. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative - * @return the new set - */ - public static KeySetView newKeySet(int initialCapacity) { - return new KeySetView(new ConcurrentHashMapV8(initialCapacity), - Boolean.TRUE); - } - - /** - * {@inheritDoc} - */ - public boolean isEmpty() { - return counter.sum() <= 0L; // ignore transient negative values - } - - /** - * {@inheritDoc} - */ - public int size() { - long n = counter.sum(); - return ((n < 0L) ? 0 : - (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : - (int)n); - } - - /** - * Returns the number of mappings. This method should be used - * instead of {@link #size} because a ConcurrentHashMapV8 may - * contain more mappings than can be represented as an int. The - * value returned is a snapshot; the actual count may differ if - * there are ongoing concurrent insertions or removals. - * - * @return the number of mappings - */ - public long mappingCount() { - long n = counter.sum(); - return (n < 0L) ? 0L : n; // ignore transient negative values - } - - /** - * Returns the value to which the specified key is mapped, - * or {@code null} if this map contains no mapping for the key. - * - *

More formally, if this map contains a mapping from a key - * {@code k} to a value {@code v} such that {@code key.equals(k)}, - * then this method returns {@code v}; otherwise it returns - * {@code null}. (There can be at most one such mapping.) - * - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V get(Object key) { - if (key == null) - throw new NullPointerException(); - return (V)internalGet(key); - } - - /** - * Returns the value to which the specified key is mapped, - * or the given defaultValue if this map contains no mapping for the key. - * - * @param key the key - * @param defaultValue the value to return if this map contains - * no mapping for the given key - * @return the mapping for the key, if present; else the defaultValue - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { - if (key == null) - throw new NullPointerException(); - V v = (V) internalGet(key); - return v == null ? defaultValue : v; - } - - /** - * Tests if the specified object is a key in this table. - * - * @param key possible key - * @return {@code true} if and only if the specified object - * is a key in this table, as determined by the - * {@code equals} method; {@code false} otherwise - * @throws NullPointerException if the specified key is null - */ - public boolean containsKey(Object key) { - if (key == null) - throw new NullPointerException(); - return internalGet(key) != null; - } - - /** - * Returns {@code true} if this map maps one or more keys to the - * specified value. Note: This method may require a full traversal - * of the map, and is much slower than method {@code containsKey}. - * - * @param value value whose presence in this map is to be tested - * @return {@code true} if this map maps one or more keys to the - * specified value - * @throws NullPointerException if the specified value is null - */ - public boolean containsValue(Object value) { - if (value == null) - throw new NullPointerException(); - Object v; - Traverser it = new Traverser(this); - while ((v = it.advance()) != null) { - if (v == value || value.equals(v)) - return true; - } - return false; - } - - public K findKey(Object value) { - if (value == null) - throw new NullPointerException(); - Object v; - Traverser it = new Traverser(this); - while ((v = it.advance()) != null) { - if (v == value || value.equals(v)) - return it.nextKey; - } - return null; - } - - /** - * Legacy method testing if some key maps into the specified value - * in this table. This method is identical in functionality to - * {@link #containsValue}, and exists solely to ensure - * full compatibility with class {@link java.util.Hashtable}, - * which supported this method prior to introduction of the - * Java Collections framework. - * - * @param value a value to search for - * @return {@code true} if and only if some key maps to the - * {@code value} argument in this table as - * determined by the {@code equals} method; - * {@code false} otherwise - * @throws NullPointerException if the specified value is null - */ - public boolean contains(Object value) { - return containsValue(value); - } - - /** - * Maps the specified key to the specified value in this table. - * Neither the key nor the value can be null. - * - *

The value can be retrieved by calling the {@code get} method - * with a key that is equal to the original key. - * - * @param key key with which the specified value is to be associated - * @param value value to be associated with the specified key - * @return the previous value associated with {@code key}, or - * {@code null} if there was no mapping for {@code key} - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V put(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalPut(key, value); - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or {@code null} if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalPutIfAbsent(key, value); - } - - /** - * Copies all of the mappings from the specified map to this one. - * These mappings replace any mappings that this map had for any of the - * keys currently in the specified map. - * - * @param m mappings to be stored in this map - */ - public void putAll(Map m) { - internalPutAll(m); - } - - /** - * If the specified key is not already associated with a value, - * computes its value using the given mappingFunction and enters - * it into the map unless null. This is equivalent to - *

 {@code
-     * if (map.containsKey(key))
-     *   return map.get(key);
-     * value = mappingFunction.apply(key);
-     * if (value != null)
-     *   map.put(key, value);
-     * return value;}
- * - * except that the action is performed atomically. If the - * function returns {@code null} no mapping is recorded. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and no mapping is recorded. Some - * attempted update operations on this map by other threads may be - * blocked while computation is in progress, so the computation - * should be short and simple, and must not attempt to update any - * other mappings of this Map. The most appropriate usage is to - * construct a new object serving as an initial mapped value, or - * memoized result, as in: - * - *
 {@code
-     * map.computeIfAbsent(key, new Fun() {
-     *   public V map(K k) { return new Value(f(k)); }});}
- * - * @param key key with which the specified value is to be associated - * @param mappingFunction the function to compute a value - * @return the current (existing or computed) value associated with - * the specified key, or null if the computed value is null - * @throws NullPointerException if the specified key or mappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the mappingFunction does so, - * in which case the mapping is left unestablished - */ - @SuppressWarnings("unchecked") public V computeIfAbsent - (K key, Fun mappingFunction) { - if (key == null || mappingFunction == null) - throw new NullPointerException(); - return (V)internalComputeIfAbsent(key, mappingFunction); - } - - /** - * If the given key is present, computes a new mapping value given a key and - * its current mapped value. This is equivalent to - *
 {@code
-     *   if (map.containsKey(key)) {
-     *     value = remappingFunction.apply(key, map.get(key));
-     *     if (value != null)
-     *       map.put(key, value);
-     *     else
-     *       map.remove(key);
-     *   }
-     * }
- * - * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. For example, - * to either create or append new messages to a value mapping: - * - * @param key key with which the specified value is to be associated - * @param remappingFunction the function to compute a value - * @return the new value associated with the specified key, or null if none - * @throws NullPointerException if the specified key or remappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the remappingFunction does so, - * in which case the mapping is unchanged - */ - @SuppressWarnings("unchecked") public V computeIfPresent - (K key, BiFun remappingFunction) { - if (key == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalCompute(key, true, remappingFunction); - } - - /** - * Computes a new mapping value given a key and - * its current mapped value (or {@code null} if there is no current - * mapping). This is equivalent to - *
 {@code
-     *   value = remappingFunction.apply(key, map.get(key));
-     *   if (value != null)
-     *     map.put(key, value);
-     *   else
-     *     map.remove(key);
-     * }
- * - * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. For example, - * to either create or append new messages to a value mapping: - * - *
 {@code
-     * Map map = ...;
-     * final String msg = ...;
-     * map.compute(key, new BiFun() {
-     *   public String apply(Key k, String v) {
-     *    return (v == null) ? msg : v + msg;});}}
- * - * @param key key with which the specified value is to be associated - * @param remappingFunction the function to compute a value - * @return the new value associated with the specified key, or null if none - * @throws NullPointerException if the specified key or remappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the remappingFunction does so, - * in which case the mapping is unchanged - */ - @SuppressWarnings("unchecked") public V compute - (K key, BiFun remappingFunction) { - if (key == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalCompute(key, false, remappingFunction); - } - - /** - * If the specified key is not already associated - * with a value, associate it with the given value. - * Otherwise, replace the value with the results of - * the given remapping function. This is equivalent to: - *
 {@code
-     *   if (!map.containsKey(key))
-     *     map.put(value);
-     *   else {
-     *     newValue = remappingFunction.apply(map.get(key), value);
-     *     if (value != null)
-     *       map.put(key, value);
-     *     else
-     *       map.remove(key);
-     *   }
-     * }
- * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. - */ - @SuppressWarnings("unchecked") public V merge - (K key, V value, BiFun remappingFunction) { - if (key == null || value == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalMerge(key, value, remappingFunction); - } - - /** - * Removes the key (and its corresponding value) from this map. - * This method does nothing if the key is not in the map. - * - * @param key the key that needs to be removed - * @return the previous value associated with {@code key}, or - * {@code null} if there was no mapping for {@code key} - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V remove(Object key) { - if (key == null) - throw new NullPointerException(); - return (V)internalReplace(key, null, null); - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if the specified key is null - */ - public boolean remove(Object key, Object value) { - if (key == null) - throw new NullPointerException(); - if (value == null) - return false; - return internalReplace(key, null, value) != null; - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if any of the arguments are null - */ - public boolean replace(K key, V oldValue, V newValue) { - if (key == null || oldValue == null || newValue == null) - throw new NullPointerException(); - return internalReplace(key, newValue, oldValue) != null; - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or {@code null} if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V replace(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalReplace(key, value, null); - } - - /** - * Removes all of the mappings from this map. - */ - public void clear() { - internalClear(); - } - - /** - * Returns a {@link Set} view of the keys contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. - * - * @return the set view - */ - public KeySetView keySet() { - KeySetView ks = keySet; - return (ks != null) ? ks : (keySet = new KeySetView(this, null)); - } - - /** - * Returns a {@link Set} view of the keys in this map, using the - * given common mapped value for any additions (i.e., {@link - * Collection#add} and {@link Collection#addAll}). This is of - * course only appropriate if it is acceptable to use the same - * value for all additions from this view. - * - * @param mappedValue the mapped value to use for any - * additions. - * @return the set view - * @throws NullPointerException if the mappedValue is null - */ - public KeySetView keySet(V mappedValue) { - if (mappedValue == null) - throw new NullPointerException(); - return new KeySetView(this, mappedValue); - } - - /** - * Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are - * reflected in the collection, and vice-versa. - */ - public ValuesView values() { - ValuesView vs = values; - return (vs != null) ? vs : (values = new ValuesView(this)); - } - - /** - * Returns a {@link Set} view of the mappings contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or - * {@code addAll} operations. - * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - */ - public Set> entrySet() { - EntrySetView es = entrySet; - return (es != null) ? es : (entrySet = new EntrySetView(this)); - } - - /** - * Returns an enumeration of the keys in this table. - * - * @return an enumeration of the keys in this table - * @see #keySet() - */ - public Enumeration keys() { - return new KeyIterator(this); - } - - /** - * Returns an enumeration of the values in this table. - * - * @return an enumeration of the values in this table - * @see #values() - */ - public Enumeration elements() { - return new ValueIterator(this); - } - - /** - * Returns a partitionable iterator of the keys in this map. - * - * @return a partitionable iterator of the keys in this map - */ - public Spliterator keySpliterator() { - return new KeyIterator(this); - } - - /** - * Returns a partitionable iterator of the values in this map. - * - * @return a partitionable iterator of the values in this map - */ - public Spliterator valueSpliterator() { - return new ValueIterator(this); - } - - /** - * Returns a partitionable iterator of the entries in this map. - * - * @return a partitionable iterator of the entries in this map - */ - public Spliterator> entrySpliterator() { - return new EntryIterator(this); - } - - /** - * Returns the hash code value for this {@link Map}, i.e., - * the sum of, for each key-value pair in the map, - * {@code key.hashCode() ^ value.hashCode()}. - * - * @return the hash code value for this map - */ - public int hashCode() { - int h = 0; - Traverser it = new Traverser(this); - Object v; - while ((v = it.advance()) != null) { - h += it.nextKey.hashCode() ^ v.hashCode(); - } - return h; - } - - /** - * Returns a string representation of this map. The string - * representation consists of a list of key-value mappings (in no - * particular order) enclosed in braces ("{@code {}}"). Adjacent - * mappings are separated by the characters {@code ", "} (comma - * and space). Each key-value mapping is rendered as the key - * followed by an equals sign ("{@code =}") followed by the - * associated value. - * - * @return a string representation of this map - */ - public String toString() { - Traverser it = new Traverser(this); - StringBuilder sb = new StringBuilder(); - sb.append('{'); - Object v; - if ((v = it.advance()) != null) { - for (;;) { - Object k = it.nextKey; - sb.append(k == this ? "(this Map)" : k); - sb.append('='); - sb.append(v == this ? "(this Map)" : v); - if ((v = it.advance()) == null) - break; - sb.append(',').append(' '); - } - } - return sb.append('}').toString(); - } - - /** - * Compares the specified object with this map for equality. - * Returns {@code true} if the given object is a map with the same - * mappings as this map. This operation may return misleading - * results if either map is concurrently modified during execution - * of this method. - * - * @param o object to be compared for equality with this map - * @return {@code true} if the specified object is equal to this map - */ - public boolean equals(Object o) { - if (o != this) { - if (!(o instanceof Map)) - return false; - Map m = (Map) o; - Traverser it = new Traverser(this); - Object val; - while ((val = it.advance()) != null) { - Object v = m.get(it.nextKey); - if (v == null || (v != val && !v.equals(val))) - return false; - } - for (Map.Entry e : m.entrySet()) { - Object mk, mv, v; - if ((mk = e.getKey()) == null || - (mv = e.getValue()) == null || - (v = internalGet(mk)) == null || - (mv != v && !mv.equals(v))) - return false; - } - } - return true; - } - - /* ----------------Iterators -------------- */ - - @SuppressWarnings("serial") static final class KeyIterator extends Traverser - implements Spliterator, Enumeration { - KeyIterator(ConcurrentHashMapV8 map) { super(map); } - KeyIterator(Traverser it) { - super(it); - } - public KeyIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new KeyIterator(this); - } - @SuppressWarnings("unchecked") public final K next() { - if (nextVal == null && advance() == null) - throw new NoSuchElementException(); - Object k = nextKey; - nextVal = null; - return (K) k; - } - - public final K nextElement() { return next(); } - } - - @SuppressWarnings("serial") static final class ValueIterator extends Traverser - implements Spliterator, Enumeration { - ValueIterator(ConcurrentHashMapV8 map) { super(map); } - ValueIterator(Traverser it) { - super(it); - } - public ValueIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new ValueIterator(this); - } - - @SuppressWarnings("unchecked") public final V next() { - Object v; - if ((v = nextVal) == null && (v = advance()) == null) - throw new NoSuchElementException(); - nextVal = null; - return (V) v; - } - - public final V nextElement() { return next(); } - } - - @SuppressWarnings("serial") static final class EntryIterator extends Traverser - implements Spliterator> { - EntryIterator(ConcurrentHashMapV8 map) { super(map); } - EntryIterator(Traverser it) { - super(it); - } - public EntryIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new EntryIterator(this); - } - - @SuppressWarnings("unchecked") public final Map.Entry next() { - Object v; - if ((v = nextVal) == null && (v = advance()) == null) - throw new NoSuchElementException(); - Object k = nextKey; - nextVal = null; - return new MapEntry((K)k, (V)v, map); - } - } - - /** - * Exported Entry for iterators - */ - static final class MapEntry implements Map.Entry { - final K key; // non-null - V val; // non-null - final ConcurrentHashMapV8 map; - MapEntry(K key, V val, ConcurrentHashMapV8 map) { - this.key = key; - this.val = val; - this.map = map; - } - public final K getKey() { return key; } - public final V getValue() { return val; } - public final int hashCode() { return key.hashCode() ^ val.hashCode(); } - public final String toString(){ return key + "=" + val; } - - public final boolean equals(Object o) { - Object k, v; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (v = e.getValue()) != null && - (k == key || k.equals(key)) && - (v == val || v.equals(val))); - } - - /** - * Sets our entry's value and writes through to the map. The - * value to return is somewhat arbitrary here. Since we do not - * necessarily track asynchronous changes, the most recent - * "previous" value could be different from what we return (or - * could even have been removed in which case the put will - * re-establish). We do not and cannot guarantee more. - */ - public final V setValue(V value) { - if (value == null) throw new NullPointerException(); - V v = val; - val = value; - map.put(key, value); - return v; - } - } - - /* ---------------- Serialization Support -------------- */ - - /** - * Stripped-down version of helper class used in previous version, - * declared for the sake of serialization compatibility - */ - static class Segment implements Serializable { - private static final long serialVersionUID = 2249069246763182397L; - final float loadFactor; - Segment(float lf) { this.loadFactor = lf; } - } - - /** - * Saves the state of the {@code ConcurrentHashMapV8} instance to a - * stream (i.e., serializes it). - * @param s the stream - * @serialData - * the key (Object) and value (Object) - * for each key-value mapping, followed by a null pair. - * The key-value mappings are emitted in no particular order. - */ - @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - if (segments == null) { // for serialization compatibility - segments = (Segment[]) - new Segment[DEFAULT_CONCURRENCY_LEVEL]; - for (int i = 0; i < segments.length; ++i) - segments[i] = new Segment(LOAD_FACTOR); - } - s.defaultWriteObject(); - Traverser it = new Traverser(this); - Object v; - while ((v = it.advance()) != null) { - s.writeObject(it.nextKey); - s.writeObject(v); - } - s.writeObject(null); - s.writeObject(null); - segments = null; // throw away - } - - /** - * Reconstitutes the instance from a stream (that is, deserializes it). - * @param s the stream - */ - @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - this.segments = null; // unneeded - // initialize transient final field - UNSAFE.putObjectVolatile(this, counterOffset, new LongAdder()); - - // Create all nodes, then place in table once size is known - long size = 0L; - Node p = null; - for (;;) { - K k = (K) s.readObject(); - V v = (V) s.readObject(); - if (k != null && v != null) { - int h = spread(k.hashCode()); - p = new Node(h, k, v, p); - ++size; - } - else - break; - } - if (p != null) { - boolean init = false; - int n; - if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) - n = MAXIMUM_CAPACITY; - else { - int sz = (int)size; - n = tableSizeFor(sz + (sz >>> 1) + 1); - } - int sc = sizeCtl; - boolean collide = false; - if (n > sc && - UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { - try { - if (table == null) { - init = true; - Node[] tab = new Node[n]; - int mask = n - 1; - while (p != null) { - int j = p.hash & mask; - Node next = p.next; - Node q = p.next = tabAt(tab, j); - setTabAt(tab, j, p); - if (!collide && q != null && q.hash == p.hash) - collide = true; - p = next; - } - table = tab; - counter.add(size); - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - if (collide) { // rescan and convert to TreeBins - Node[] tab = table; - for (int i = 0; i < tab.length; ++i) { - int c = 0; - for (Node e = tabAt(tab, i); e != null; e = e.next) { - if (++c > TREE_THRESHOLD && - (e.key instanceof Comparable)) { - replaceWithTreeBin(tab, i, e.key); - break; - } - } - } - } - } - if (!init) { // Can only happen if unsafely published. - while (p != null) { - internalPut(p.key, p.val); - p = p.next; - } - } - } - } - - - // ------------------------------------------------------- - - // Sams - /** Interface describing a void action of one argument */ - public interface Action { void apply(A a); } - /** Interface describing a void action of two arguments */ - public interface BiAction { void apply(A a, B b); } - /** Interface describing a function of one argument */ - public interface Generator { T apply(); } - /** Interface describing a function mapping its argument to a double */ - public interface ObjectToDouble { double apply(A a); } - /** Interface describing a function mapping its argument to a long */ - public interface ObjectToLong { long apply(A a); } - /** Interface describing a function mapping its argument to an int */ - public interface ObjectToInt {int apply(A a); } - /** Interface describing a function mapping two arguments to a double */ - public interface ObjectByObjectToDouble { double apply(A a, B b); } - /** Interface describing a function mapping two arguments to a long */ - public interface ObjectByObjectToLong { long apply(A a, B b); } - /** Interface describing a function mapping two arguments to an int */ - public interface ObjectByObjectToInt {int apply(A a, B b); } - /** Interface describing a function mapping a double to a double */ - public interface DoubleToDouble { double apply(double a); } - /** Interface describing a function mapping a long to a long */ - public interface LongToLong { long apply(long a); } - /** Interface describing a function mapping an int to an int */ - public interface IntToInt { int apply(int a); } - /** Interface describing a function mapping two doubles to a double */ - public interface DoubleByDoubleToDouble { double apply(double a, double b); } - /** Interface describing a function mapping two longs to a long */ - public interface LongByLongToLong { long apply(long a, long b); } - /** Interface describing a function mapping two ints to an int */ - public interface IntByIntToInt { int apply(int a, int b); } - - - /* ----------------Views -------------- */ - - /** - * Base class for views. - */ - static abstract class CHMView { - final ConcurrentHashMapV8 map; - CHMView(ConcurrentHashMapV8 map) { this.map = map; } - - /** - * Returns the map backing this view. - * - * @return the map backing this view - */ - public ConcurrentHashMapV8 getMap() { return map; } - - public final int size() { return map.size(); } - public final boolean isEmpty() { return map.isEmpty(); } - public final void clear() { map.clear(); } - - // implementations below rely on concrete classes supplying these - abstract public Iterator iterator(); - abstract public boolean contains(Object o); - abstract public boolean remove(Object o); - - private static final String oomeMsg = "Required array size too large"; - - public final Object[] toArray() { - long sz = map.mappingCount(); - if (sz > (long)(MAX_ARRAY_SIZE)) - throw new OutOfMemoryError(oomeMsg); - int n = (int)sz; - Object[] r = new Object[n]; - int i = 0; - Iterator it = iterator(); - while (it.hasNext()) { - if (i == n) { - if (n >= MAX_ARRAY_SIZE) - throw new OutOfMemoryError(oomeMsg); - if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) - n = MAX_ARRAY_SIZE; - else - n += (n >>> 1) + 1; - r = Arrays.copyOf(r, n); - } - r[i++] = it.next(); - } - return (i == n) ? r : Arrays.copyOf(r, i); - } - - @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { - long sz = map.mappingCount(); - if (sz > (long)(MAX_ARRAY_SIZE)) - throw new OutOfMemoryError(oomeMsg); - int m = (int)sz; - T[] r = (a.length >= m) ? a : - (T[])java.lang.reflect.Array - .newInstance(a.getClass().getComponentType(), m); - int n = r.length; - int i = 0; - Iterator it = iterator(); - while (it.hasNext()) { - if (i == n) { - if (n >= MAX_ARRAY_SIZE) - throw new OutOfMemoryError(oomeMsg); - if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) - n = MAX_ARRAY_SIZE; - else - n += (n >>> 1) + 1; - r = Arrays.copyOf(r, n); - } - r[i++] = (T)it.next(); - } - if (a == r && i < n) { - r[i] = null; // null-terminate - return r; - } - return (i == n) ? r : Arrays.copyOf(r, i); - } - - public final int hashCode() { - int h = 0; - for (Iterator it = iterator(); it.hasNext();) - h += it.next().hashCode(); - return h; - } - - public final String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('['); - Iterator it = iterator(); - if (it.hasNext()) { - for (;;) { - Object e = it.next(); - sb.append(e == this ? "(this Collection)" : e); - if (!it.hasNext()) - break; - sb.append(',').append(' '); - } - } - return sb.append(']').toString(); - } - - public final boolean containsAll(Collection c) { - if (c != this) { - for (Iterator it = c.iterator(); it.hasNext();) { - Object e = it.next(); - if (e == null || !contains(e)) - return false; - } - } - return true; - } - - public final boolean removeAll(Collection c) { - boolean modified = false; - for (Iterator it = iterator(); it.hasNext();) { - if (c.contains(it.next())) { - it.remove(); - modified = true; - } - } - return modified; - } - - public final boolean retainAll(Collection c) { - boolean modified = false; - for (Iterator it = iterator(); it.hasNext();) { - if (!c.contains(it.next())) { - it.remove(); - modified = true; - } - } - return modified; - } - - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in - * which additions may optionally be enabled by mapping to a - * common value. This class cannot be directly instantiated. See - * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, - * {@link #newKeySet(int)}. - */ - public static class KeySetView extends CHMView implements Set, java.io.Serializable { - private static final long serialVersionUID = 7249069246763182397L; - private final V value; - KeySetView(ConcurrentHashMapV8 map, V value) { // non-public - super(map); - this.value = value; - } - - /** - * Returns the default mapped value for additions, - * or {@code null} if additions are not supported. - * - * @return the default mapped value for additions, or {@code null} - * if not supported. - */ - public V getMappedValue() { return value; } - - // implement Set API - - public boolean contains(Object o) { return map.containsKey(o); } - public boolean remove(Object o) { return map.remove(o) != null; } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the keys of this map - */ - public Iterator iterator() { return new KeyIterator(map); } - public boolean add(K e) { - V v; - if ((v = value) == null) - throw new UnsupportedOperationException(); - if (e == null) - throw new NullPointerException(); - return map.internalPutIfAbsent(e, v) == null; - } - public boolean addAll(Collection c) { - boolean added = false; - V v; - if ((v = value) == null) - throw new UnsupportedOperationException(); - for (K e : c) { - if (e == null) - throw new NullPointerException(); - if (map.internalPutIfAbsent(e, v) == null) - added = true; - } - return added; - } - public boolean equals(Object o) { - Set c; - return ((o instanceof Set) && - ((c = (Set)o) == this || - (containsAll(c) && c.containsAll(this)))); - } - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Collection} of - * values, in which additions are disabled. This class cannot be - * directly instantiated. See {@link #values}, - * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - */ - public static final class ValuesView extends CHMView - implements Collection { - ValuesView(ConcurrentHashMapV8 map) { super(map); } - public final boolean contains(Object o) { return map.containsValue(o); } - public final boolean remove(Object o) { - if (o != null) { - Iterator it = new ValueIterator(map); - while (it.hasNext()) { - if (o.equals(it.next())) { - it.remove(); - return true; - } - } - } - return false; - } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the values of this map - */ - public final Iterator iterator() { - return new ValueIterator(map); - } - public final boolean add(V e) { - throw new UnsupportedOperationException(); - } - public final boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) - * entries. This class cannot be directly instantiated. See - * {@link #entrySet}. - */ - public static final class EntrySetView extends CHMView - implements Set> { - EntrySetView(ConcurrentHashMapV8 map) { super(map); } - public final boolean contains(Object o) { - Object k, v, r; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (r = map.get(k)) != null && - (v = e.getValue()) != null && - (v == r || v.equals(r))); - } - public final boolean remove(Object o) { - Object k, v; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (v = e.getValue()) != null && - map.remove(k, v)); - } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the entries of this map - */ - public final Iterator> iterator() { - return new EntryIterator(map); - } - - public final boolean add(Entry e) { - K key = e.getKey(); - V value = e.getValue(); - if (key == null || value == null) - throw new NullPointerException(); - return map.internalPut(key, value) == null; - } - public final boolean addAll(Collection> c) { - boolean added = false; - for (Entry e : c) { - if (add(e)) - added = true; - } - return added; - } - public boolean equals(Object o) { - Set c; - return ((o instanceof Set) && - ((c = (Set)o) == this || - (containsAll(c) && c.containsAll(this)))); - } - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long counterOffset; - private static final long sizeCtlOffset; - private static final long ABASE; - private static final int ASHIFT; - - static { - int ss; - try { - UNSAFE = getUnsafe(); - Class k = ConcurrentHashMapV8.class; - counterOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("counter")); - sizeCtlOffset = UNSAFE.objectFieldOffset - (k.getDeclaredField("sizeCtl")); - Class sc = Node[].class; - ABASE = UNSAFE.arrayBaseOffset(sc); - ss = UNSAFE.arrayIndexScale(sc); - } catch (Exception e) { - throw new Error(e); - } - if ((ss & (ss-1)) != 0) - throw new Error("data type scale not a power of two"); - ASHIFT = 31 - Integer.numberOfLeadingZeros(ss); - } - - /** - * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. - * Replace with a simple call to Unsafe.getUnsafe when integrating - * into a jdk. - * - * @return a sun.misc.Unsafe - */ - private static sun.misc.Unsafe getUnsafe() { - try { - return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - return java.security.AccessController.doPrivileged - (new java.security - .PrivilegedExceptionAction() { - public sun.misc.Unsafe run() throws Exception { - java.lang.reflect.Field f = sun.misc - .Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (sun.misc.Unsafe) f.get(null); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java deleted file mode 100644 index 47a923c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on 1.9 version. - -package com.concurrent_ruby.ext.jsr166e; -import java.util.concurrent.atomic.AtomicLong; -import java.io.IOException; -import java.io.Serializable; -import java.io.ObjectInputStream; - -/** - * One or more variables that together maintain an initially zero - * {@code long} sum. When updates (method {@link #add}) are contended - * across threads, the set of variables may grow dynamically to reduce - * contention. Method {@link #sum} (or, equivalently, {@link - * #longValue}) returns the current total combined across the - * variables maintaining the sum. - * - *

This class is usually preferable to {@link AtomicLong} when - * multiple threads update a common sum that is used for purposes such - * as collecting statistics, not for fine-grained synchronization - * control. Under low update contention, the two classes have similar - * characteristics. But under high contention, expected throughput of - * this class is significantly higher, at the expense of higher space - * consumption. - * - *

This class extends {@link Number}, but does not define - * methods such as {@code hashCode} and {@code compareTo} because - * instances are expected to be mutated, and so are not useful as - * collection keys. - * - *

jsr166e note: This class is targeted to be placed in - * java.util.concurrent.atomic. - * - * @since 1.8 - * @author Doug Lea - */ -public class LongAdder extends Striped64 implements Serializable { - private static final long serialVersionUID = 7249069246863182397L; - - /** - * Version of plus for use in retryUpdate - */ - final long fn(long v, long x) { return v + x; } - - /** - * Creates a new adder with initial sum of zero. - */ - public LongAdder() { - } - - /** - * Adds the given value. - * - * @param x the value to add - */ - public void add(long x) { - Cell[] as; long b, v; HashCode hc; Cell a; int n; - if ((as = cells) != null || !casBase(b = base, b + x)) { - boolean uncontended = true; - int h = (hc = threadHashCode.get()).code; - if (as == null || (n = as.length) < 1 || - (a = as[(n - 1) & h]) == null || - !(uncontended = a.cas(v = a.value, v + x))) - retryUpdate(x, hc, uncontended); - } - } - - /** - * Equivalent to {@code add(1)}. - */ - public void increment() { - add(1L); - } - - /** - * Equivalent to {@code add(-1)}. - */ - public void decrement() { - add(-1L); - } - - /** - * Returns the current sum. The returned value is NOT an - * atomic snapshot: Invocation in the absence of concurrent - * updates returns an accurate result, but concurrent updates that - * occur while the sum is being calculated might not be - * incorporated. - * - * @return the sum - */ - public long sum() { - long sum = base; - Cell[] as = cells; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - sum += a.value; - } - } - return sum; - } - - /** - * Resets variables maintaining the sum to zero. This method may - * be a useful alternative to creating a new adder, but is only - * effective if there are no concurrent updates. Because this - * method is intrinsically racy, it should only be used when it is - * known that no threads are concurrently updating. - */ - public void reset() { - internalReset(0L); - } - - /** - * Equivalent in effect to {@link #sum} followed by {@link - * #reset}. This method may apply for example during quiescent - * points between multithreaded computations. If there are - * updates concurrent with this method, the returned value is - * not guaranteed to be the final value occurring before - * the reset. - * - * @return the sum - */ - public long sumThenReset() { - long sum = base; - Cell[] as = cells; - base = 0L; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) { - sum += a.value; - a.value = 0L; - } - } - } - return sum; - } - - /** - * Returns the String representation of the {@link #sum}. - * @return the String representation of the {@link #sum} - */ - public String toString() { - return Long.toString(sum()); - } - - /** - * Equivalent to {@link #sum}. - * - * @return the sum - */ - public long longValue() { - return sum(); - } - - /** - * Returns the {@link #sum} as an {@code int} after a narrowing - * primitive conversion. - */ - public int intValue() { - return (int)sum(); - } - - /** - * Returns the {@link #sum} as a {@code float} - * after a widening primitive conversion. - */ - public float floatValue() { - return (float)sum(); - } - - /** - * Returns the {@link #sum} as a {@code double} after a widening - * primitive conversion. - */ - public double doubleValue() { - return (double)sum(); - } - - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - s.defaultWriteObject(); - s.writeLong(sum()); - } - - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - busy = 0; - cells = null; - base = s.readLong(); - } - -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java deleted file mode 100644 index 93a277f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on 1.5 version. - -package com.concurrent_ruby.ext.jsr166e; -import java.util.Random; - -/** - * A package-local class holding common representation and mechanics - * for classes supporting dynamic striping on 64bit values. The class - * extends Number so that concrete subclasses must publicly do so. - */ -abstract class Striped64 extends Number { - /* - * This class maintains a lazily-initialized table of atomically - * updated variables, plus an extra "base" field. The table size - * is a power of two. Indexing uses masked per-thread hash codes. - * Nearly all declarations in this class are package-private, - * accessed directly by subclasses. - * - * Table entries are of class Cell; a variant of AtomicLong padded - * to reduce cache contention on most processors. Padding is - * overkill for most Atomics because they are usually irregularly - * scattered in memory and thus don't interfere much with each - * other. But Atomic objects residing in arrays will tend to be - * placed adjacent to each other, and so will most often share - * cache lines (with a huge negative performance impact) without - * this precaution. - * - * In part because Cells are relatively large, we avoid creating - * them until they are needed. When there is no contention, all - * updates are made to the base field. Upon first contention (a - * failed CAS on base update), the table is initialized to size 2. - * The table size is doubled upon further contention until - * reaching the nearest power of two greater than or equal to the - * number of CPUS. Table slots remain empty (null) until they are - * needed. - * - * A single spinlock ("busy") is used for initializing and - * resizing the table, as well as populating slots with new Cells. - * There is no need for a blocking lock: When the lock is not - * available, threads try other slots (or the base). During these - * retries, there is increased contention and reduced locality, - * which is still better than alternatives. - * - * Per-thread hash codes are initialized to random values. - * Contention and/or table collisions are indicated by failed - * CASes when performing an update operation (see method - * retryUpdate). Upon a collision, if the table size is less than - * the capacity, it is doubled in size unless some other thread - * holds the lock. If a hashed slot is empty, and lock is - * available, a new Cell is created. Otherwise, if the slot - * exists, a CAS is tried. Retries proceed by "double hashing", - * using a secondary hash (Marsaglia XorShift) to try to find a - * free slot. - * - * The table size is capped because, when there are more threads - * than CPUs, supposing that each thread were bound to a CPU, - * there would exist a perfect hash function mapping threads to - * slots that eliminates collisions. When we reach capacity, we - * search for this mapping by randomly varying the hash codes of - * colliding threads. Because search is random, and collisions - * only become known via CAS failures, convergence can be slow, - * and because threads are typically not bound to CPUS forever, - * may not occur at all. However, despite these limitations, - * observed contention rates are typically low in these cases. - * - * It is possible for a Cell to become unused when threads that - * once hashed to it terminate, as well as in the case where - * doubling the table causes no thread to hash to it under - * expanded mask. We do not try to detect or remove such cells, - * under the assumption that for long-running instances, observed - * contention levels will recur, so the cells will eventually be - * needed again; and for short-lived ones, it does not matter. - */ - - /** - * Padded variant of AtomicLong supporting only raw accesses plus CAS. - * The value field is placed between pads, hoping that the JVM doesn't - * reorder them. - * - * JVM intrinsics note: It would be possible to use a release-only - * form of CAS here, if it were provided. - */ - static final class Cell { - volatile long p0, p1, p2, p3, p4, p5, p6; - volatile long value; - volatile long q0, q1, q2, q3, q4, q5, q6; - Cell(long x) { value = x; } - - final boolean cas(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long valueOffset; - static { - try { - UNSAFE = getUnsafe(); - Class ak = Cell.class; - valueOffset = UNSAFE.objectFieldOffset - (ak.getDeclaredField("value")); - } catch (Exception e) { - throw new Error(e); - } - } - - } - - /** - * Holder for the thread-local hash code. The code is initially - * random, but may be set to a different value upon collisions. - */ - static final class HashCode { - static final Random rng = new Random(); - int code; - HashCode() { - int h = rng.nextInt(); // Avoid zero to allow xorShift rehash - code = (h == 0) ? 1 : h; - } - } - - /** - * The corresponding ThreadLocal class - */ - static final class ThreadHashCode extends ThreadLocal { - public HashCode initialValue() { return new HashCode(); } - } - - /** - * Static per-thread hash codes. Shared across all instances to - * reduce ThreadLocal pollution and because adjustments due to - * collisions in one table are likely to be appropriate for - * others. - */ - static final ThreadHashCode threadHashCode = new ThreadHashCode(); - - /** Number of CPUS, to place bound on table size */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * Table of cells. When non-null, size is a power of 2. - */ - transient volatile Cell[] cells; - - /** - * Base value, used mainly when there is no contention, but also as - * a fallback during table initialization races. Updated via CAS. - */ - transient volatile long base; - - /** - * Spinlock (locked via CAS) used when resizing and/or creating Cells. - */ - transient volatile int busy; - - /** - * Package-private default constructor - */ - Striped64() { - } - - /** - * CASes the base field. - */ - final boolean casBase(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); - } - - /** - * CASes the busy field from 0 to 1 to acquire lock. - */ - final boolean casBusy() { - return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); - } - - /** - * Computes the function of current and new value. Subclasses - * should open-code this update function for most uses, but the - * virtualized form is needed within retryUpdate. - * - * @param currentValue the current value (of either base or a cell) - * @param newValue the argument from a user update call - * @return result of the update function - */ - abstract long fn(long currentValue, long newValue); - - /** - * Handles cases of updates involving initialization, resizing, - * creating new Cells, and/or contention. See above for - * explanation. This method suffers the usual non-modularity - * problems of optimistic retry code, relying on rechecked sets of - * reads. - * - * @param x the value - * @param hc the hash code holder - * @param wasUncontended false if CAS failed before call - */ - final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { - int h = hc.code; - boolean collide = false; // True if last slot nonempty - for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { - if (busy == 0) { // Try to attach new Cell - Cell r = new Cell(x); // Optimistically create - if (busy == 0 && casBusy()) { - boolean created = false; - try { // Recheck under lock - Cell[] rs; int m, j; - if ((rs = cells) != null && - (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { - rs[j] = r; - created = true; - } - } finally { - busy = 0; - } - if (created) - break; - continue; // Slot is now non-empty - } - } - collide = false; - } - else if (!wasUncontended) // CAS already known to fail - wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, fn(v, x))) - break; - else if (n >= NCPU || cells != as) - collide = false; // At max size or stale - else if (!collide) - collide = true; - else if (busy == 0 && casBusy()) { - try { - if (cells == as) { // Expand table unless stale - Cell[] rs = new Cell[n << 1]; - for (int i = 0; i < n; ++i) - rs[i] = as[i]; - cells = rs; - } - } finally { - busy = 0; - } - collide = false; - continue; // Retry with expanded table - } - h ^= h << 13; // Rehash - h ^= h >>> 17; - h ^= h << 5; - } - else if (busy == 0 && cells == as && casBusy()) { - boolean init = false; - try { // Initialize table - if (cells == as) { - Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); - cells = rs; - init = true; - } - } finally { - busy = 0; - } - if (init) - break; - } - else if (casBase(v = base, fn(v, x))) - break; // Fall back on using base - } - hc.code = h; // Record index for next time - } - - - /** - * Sets base and all cells to the given value. - */ - final void internalReset(long initialValue) { - Cell[] as = cells; - base = initialValue; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - a.value = initialValue; - } - } - } - - // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE; - private static final long baseOffset; - private static final long busyOffset; - static { - try { - UNSAFE = getUnsafe(); - Class sk = Striped64.class; - baseOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("base")); - busyOffset = UNSAFE.objectFieldOffset - (sk.getDeclaredField("busy")); - } catch (Exception e) { - throw new Error(e); - } - } - - /** - * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. - * Replace with a simple call to Unsafe.getUnsafe when integrating - * into a jdk. - * - * @return a sun.misc.Unsafe - */ - private static sun.misc.Unsafe getUnsafe() { - try { - return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - return java.security.AccessController.doPrivileged - (new java.security - .PrivilegedExceptionAction() { - public sun.misc.Unsafe run() throws Exception { - java.lang.reflect.Field f = sun.misc - .Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (sun.misc.Unsafe) f.get(null); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } - } - } - -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java deleted file mode 100644 index b7fc5a9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +++ /dev/null @@ -1,3800 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on the 1.79 version. - -package com.concurrent_ruby.ext.jsr166e.nounsafe; - -import org.jruby.RubyClass; -import org.jruby.RubyNumeric; -import org.jruby.RubyObject; -import org.jruby.exceptions.RaiseException; -import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; -import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; -import org.jruby.runtime.ThreadContext; -import org.jruby.runtime.builtin.IRubyObject; - -import java.util.Arrays; -import java.util.Map; -import java.util.Set; -import java.util.Collection; -import java.util.Hashtable; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Enumeration; -import java.util.ConcurrentModificationException; -import java.util.NoSuchElementException; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.concurrent.locks.AbstractQueuedSynchronizer; - -import java.io.Serializable; - -/** - * A hash table supporting full concurrency of retrievals and - * high expected concurrency for updates. This class obeys the - * same functional specification as {@link java.util.Hashtable}, and - * includes versions of methods corresponding to each method of - * {@code Hashtable}. However, even though all operations are - * thread-safe, retrieval operations do not entail locking, - * and there is not any support for locking the entire table - * in a way that prevents all access. This class is fully - * interoperable with {@code Hashtable} in programs that rely on its - * thread safety but not on its synchronization details. - * - *

Retrieval operations (including {@code get}) generally do not - * block, so may overlap with update operations (including {@code put} - * and {@code remove}). Retrievals reflect the results of the most - * recently completed update operations holding upon their - * onset. (More formally, an update operation for a given key bears a - * happens-before relation with any (non-null) retrieval for - * that key reporting the updated value.) For aggregate operations - * such as {@code putAll} and {@code clear}, concurrent retrievals may - * reflect insertion or removal of only some entries. Similarly, - * Iterators and Enumerations return elements reflecting the state of - * the hash table at some point at or since the creation of the - * iterator/enumeration. They do not throw {@link - * ConcurrentModificationException}. However, iterators are designed - * to be used by only one thread at a time. Bear in mind that the - * results of aggregate status methods including {@code size}, {@code - * isEmpty}, and {@code containsValue} are typically useful only when - * a map is not undergoing concurrent updates in other threads. - * Otherwise the results of these methods reflect transient states - * that may be adequate for monitoring or estimation purposes, but not - * for program control. - * - *

The table is dynamically expanded when there are too many - * collisions (i.e., keys that have distinct hash codes but fall into - * the same slot modulo the table size), with the expected average - * effect of maintaining roughly two bins per mapping (corresponding - * to a 0.75 load factor threshold for resizing). There may be much - * variance around this average as mappings are added and removed, but - * overall, this maintains a commonly accepted time/space tradeoff for - * hash tables. However, resizing this or any other kind of hash - * table may be a relatively slow operation. When possible, it is a - * good idea to provide a size estimate as an optional {@code - * initialCapacity} constructor argument. An additional optional - * {@code loadFactor} constructor argument provides a further means of - * customizing initial table capacity by specifying the table density - * to be used in calculating the amount of space to allocate for the - * given number of elements. Also, for compatibility with previous - * versions of this class, constructors may optionally specify an - * expected {@code concurrencyLevel} as an additional hint for - * internal sizing. Note that using many keys with exactly the same - * {@code hashCode()} is a sure way to slow down performance of any - * hash table. - * - *

A {@link Set} projection of a ConcurrentHashMapV8 may be created - * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed - * (using {@link #keySet(Object)} when only keys are of interest, and the - * mapped values are (perhaps transiently) not used or all take the - * same mapping value. - * - *

A ConcurrentHashMapV8 can be used as scalable frequency map (a - * form of histogram or multiset) by using {@link LongAdder} values - * and initializing via {@link #computeIfAbsent}. For example, to add - * a count to a {@code ConcurrentHashMapV8 freqs}, you - * can use {@code freqs.computeIfAbsent(k -> new - * LongAdder()).increment();} - * - *

This class and its views and iterators implement all of the - * optional methods of the {@link Map} and {@link Iterator} - * interfaces. - * - *

Like {@link Hashtable} but unlike {@link HashMap}, this class - * does not allow {@code null} to be used as a key or value. - * - *

ConcurrentHashMapV8s support parallel operations using the {@link - * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts - * are available in class {@link ForkJoinTasks}). These operations are - * designed to be safely, and often sensibly, applied even with maps - * that are being concurrently updated by other threads; for example, - * when computing a snapshot summary of the values in a shared - * registry. There are three kinds of operation, each with four - * forms, accepting functions with Keys, Values, Entries, and (Key, - * Value) arguments and/or return values. (The first three forms are - * also available via the {@link #keySet()}, {@link #values()} and - * {@link #entrySet()} views). Because the elements of a - * ConcurrentHashMapV8 are not ordered in any particular way, and may be - * processed in different orders in different parallel executions, the - * correctness of supplied functions should not depend on any - * ordering, or on any other objects or values that may transiently - * change while computation is in progress; and except for forEach - * actions, should ideally be side-effect-free. - * - *

- * - *

The concurrency properties of bulk operations follow - * from those of ConcurrentHashMapV8: Any non-null result returned - * from {@code get(key)} and related access methods bears a - * happens-before relation with the associated insertion or - * update. The result of any bulk operation reflects the - * composition of these per-element relations (but is not - * necessarily atomic with respect to the map as a whole unless it - * is somehow known to be quiescent). Conversely, because keys - * and values in the map are never null, null serves as a reliable - * atomic indicator of the current lack of any result. To - * maintain this property, null serves as an implicit basis for - * all non-scalar reduction operations. For the double, long, and - * int versions, the basis should be one that, when combined with - * any other value, returns that other value (more formally, it - * should be the identity element for the reduction). Most common - * reductions have these properties; for example, computing a sum - * with basis 0 or a minimum with basis MAX_VALUE. - * - *

Search and transformation functions provided as arguments - * should similarly return null to indicate the lack of any result - * (in which case it is not used). In the case of mapped - * reductions, this also enables transformations to serve as - * filters, returning null (or, in the case of primitive - * specializations, the identity basis) if the element should not - * be combined. You can create compound transformations and - * filterings by composing them yourself under this "null means - * there is nothing there now" rule before using them in search or - * reduce operations. - * - *

Methods accepting and/or returning Entry arguments maintain - * key-value associations. They may be useful for example when - * finding the key for the greatest value. Note that "plain" Entry - * arguments can be supplied using {@code new - * AbstractMap.SimpleEntry(k,v)}. - * - *

Bulk operations may complete abruptly, throwing an - * exception encountered in the application of a supplied - * function. Bear in mind when handling such exceptions that other - * concurrently executing functions could also have thrown - * exceptions, or would have done so if the first exception had - * not occurred. - * - *

Parallel speedups for bulk operations compared to sequential - * processing are common but not guaranteed. Operations involving - * brief functions on small maps may execute more slowly than - * sequential loops if the underlying work to parallelize the - * computation is more expensive than the computation itself. - * Similarly, parallelization may not lead to much actual parallelism - * if all processors are busy performing unrelated tasks. - * - *

All arguments to all task methods must be non-null. - * - *

jsr166e note: During transition, this class - * uses nested functional interfaces with different names but the - * same forms as those expected for JDK8. - * - *

This class is a member of the - * - * Java Collections Framework. - * - * @since 1.5 - * @author Doug Lea - * @param the type of keys maintained by this map - * @param the type of mapped values - */ -public class ConcurrentHashMapV8 - implements ConcurrentMap, Serializable, ConcurrentHashMap { - private static final long serialVersionUID = 7249069246763182397L; - - /** - * A partitionable iterator. A Spliterator can be traversed - * directly, but can also be partitioned (before traversal) by - * creating another Spliterator that covers a non-overlapping - * portion of the elements, and so may be amenable to parallel - * execution. - * - *

This interface exports a subset of expected JDK8 - * functionality. - * - *

Sample usage: Here is one (of the several) ways to compute - * the sum of the values held in a map using the ForkJoin - * framework. As illustrated here, Spliterators are well suited to - * designs in which a task repeatedly splits off half its work - * into forked subtasks until small enough to process directly, - * and then joins these subtasks. Variants of this style can also - * be used in completion-based designs. - * - *

-     * {@code ConcurrentHashMapV8 m = ...
-     * // split as if have 8 * parallelism, for load balance
-     * int n = m.size();
-     * int p = aForkJoinPool.getParallelism() * 8;
-     * int split = (n < p)? n : p;
-     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
-     * // ...
-     * static class SumValues extends RecursiveTask {
-     *   final Spliterator s;
-     *   final int split;             // split while > 1
-     *   final SumValues nextJoin;    // records forked subtasks to join
-     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
-     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
-     *   }
-     *   public Long compute() {
-     *     long sum = 0;
-     *     SumValues subtasks = null; // fork subtasks
-     *     for (int s = split >>> 1; s > 0; s >>>= 1)
-     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
-     *     while (s.hasNext())        // directly process remaining elements
-     *       sum += s.next();
-     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
-     *       sum += t.join();         // collect subtask results
-     *     return sum;
-     *   }
-     * }
-     * }
- */ - public static interface Spliterator extends Iterator { - /** - * Returns a Spliterator covering approximately half of the - * elements, guaranteed not to overlap with those subsequently - * returned by this Spliterator. After invoking this method, - * the current Spliterator will not produce any of - * the elements of the returned Spliterator, but the two - * Spliterators together will produce all of the elements that - * would have been produced by this Spliterator had this - * method not been called. The exact number of elements - * produced by the returned Spliterator is not guaranteed, and - * may be zero (i.e., with {@code hasNext()} reporting {@code - * false}) if this Spliterator cannot be further split. - * - * @return a Spliterator covering approximately half of the - * elements - * @throws IllegalStateException if this Spliterator has - * already commenced traversing elements - */ - Spliterator split(); - } - - - /* - * Overview: - * - * The primary design goal of this hash table is to maintain - * concurrent readability (typically method get(), but also - * iterators and related methods) while minimizing update - * contention. Secondary goals are to keep space consumption about - * the same or better than java.util.HashMap, and to support high - * initial insertion rates on an empty table by many threads. - * - * Each key-value mapping is held in a Node. Because Node fields - * can contain special values, they are defined using plain Object - * types. Similarly in turn, all internal methods that use them - * work off Object types. And similarly, so do the internal - * methods of auxiliary iterator and view classes. All public - * generic typed methods relay in/out of these internal methods, - * supplying null-checks and casts as needed. This also allows - * many of the public methods to be factored into a smaller number - * of internal methods (although sadly not so for the five - * variants of put-related operations). The validation-based - * approach explained below leads to a lot of code sprawl because - * retry-control precludes factoring into smaller methods. - * - * The table is lazily initialized to a power-of-two size upon the - * first insertion. Each bin in the table normally contains a - * list of Nodes (most often, the list has only zero or one Node). - * Table accesses require volatile/atomic reads, writes, and - * CASes. Because there is no other way to arrange this without - * adding further indirections, we use intrinsics - * (sun.misc.Unsafe) operations. The lists of nodes within bins - * are always accurately traversable under volatile reads, so long - * as lookups check hash code and non-nullness of value before - * checking key equality. - * - * We use the top two bits of Node hash fields for control - * purposes -- they are available anyway because of addressing - * constraints. As explained further below, these top bits are - * used as follows: - * 00 - Normal - * 01 - Locked - * 11 - Locked and may have a thread waiting for lock - * 10 - Node is a forwarding node - * - * The lower 30 bits of each Node's hash field contain a - * transformation of the key's hash code, except for forwarding - * nodes, for which the lower bits are zero (and so always have - * hash field == MOVED). - * - * Insertion (via put or its variants) of the first node in an - * empty bin is performed by just CASing it to the bin. This is - * by far the most common case for put operations under most - * key/hash distributions. Other update operations (insert, - * delete, and replace) require locks. We do not want to waste - * the space required to associate a distinct lock object with - * each bin, so instead use the first node of a bin list itself as - * a lock. Blocking support for these locks relies on the builtin - * "synchronized" monitors. However, we also need a tryLock - * construction, so we overlay these by using bits of the Node - * hash field for lock control (see above), and so normally use - * builtin monitors only for blocking and signalling using - * wait/notifyAll constructions. See Node.tryAwaitLock. - * - * Using the first node of a list as a lock does not by itself - * suffice though: When a node is locked, any update must first - * validate that it is still the first node after locking it, and - * retry if not. Because new nodes are always appended to lists, - * once a node is first in a bin, it remains first until deleted - * or the bin becomes invalidated (upon resizing). However, - * operations that only conditionally update may inspect nodes - * until the point of update. This is a converse of sorts to the - * lazy locking technique described by Herlihy & Shavit. - * - * The main disadvantage of per-bin locks is that other update - * operations on other nodes in a bin list protected by the same - * lock can stall, for example when user equals() or mapping - * functions take a long time. However, statistically, under - * random hash codes, this is not a common problem. Ideally, the - * frequency of nodes in bins follows a Poisson distribution - * (http://en.wikipedia.org/wiki/Poisson_distribution) with a - * parameter of about 0.5 on average, given the resizing threshold - * of 0.75, although with a large variance because of resizing - * granularity. Ignoring variance, the expected occurrences of - * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The - * first values are: - * - * 0: 0.60653066 - * 1: 0.30326533 - * 2: 0.07581633 - * 3: 0.01263606 - * 4: 0.00157952 - * 5: 0.00015795 - * 6: 0.00001316 - * 7: 0.00000094 - * 8: 0.00000006 - * more: less than 1 in ten million - * - * Lock contention probability for two threads accessing distinct - * elements is roughly 1 / (8 * #elements) under random hashes. - * - * Actual hash code distributions encountered in practice - * sometimes deviate significantly from uniform randomness. This - * includes the case when N > (1<<30), so some keys MUST collide. - * Similarly for dumb or hostile usages in which multiple keys are - * designed to have identical hash codes. Also, although we guard - * against the worst effects of this (see method spread), sets of - * hashes may differ only in bits that do not impact their bin - * index for a given power-of-two mask. So we use a secondary - * strategy that applies when the number of nodes in a bin exceeds - * a threshold, and at least one of the keys implements - * Comparable. These TreeBins use a balanced tree to hold nodes - * (a specialized form of red-black trees), bounding search time - * to O(log N). Each search step in a TreeBin is around twice as - * slow as in a regular list, but given that N cannot exceed - * (1<<64) (before running out of addresses) this bounds search - * steps, lock hold times, etc, to reasonable constants (roughly - * 100 nodes inspected per operation worst case) so long as keys - * are Comparable (which is very common -- String, Long, etc). - * TreeBin nodes (TreeNodes) also maintain the same "next" - * traversal pointers as regular nodes, so can be traversed in - * iterators in the same way. - * - * The table is resized when occupancy exceeds a percentage - * threshold (nominally, 0.75, but see below). Only a single - * thread performs the resize (using field "sizeCtl", to arrange - * exclusion), but the table otherwise remains usable for reads - * and updates. Resizing proceeds by transferring bins, one by - * one, from the table to the next table. Because we are using - * power-of-two expansion, the elements from each bin must either - * stay at same index, or move with a power of two offset. We - * eliminate unnecessary node creation by catching cases where old - * nodes can be reused because their next fields won't change. On - * average, only about one-sixth of them need cloning when a table - * doubles. The nodes they replace will be garbage collectable as - * soon as they are no longer referenced by any reader thread that - * may be in the midst of concurrently traversing table. Upon - * transfer, the old table bin contains only a special forwarding - * node (with hash field "MOVED") that contains the next table as - * its key. On encountering a forwarding node, access and update - * operations restart, using the new table. - * - * Each bin transfer requires its bin lock. However, unlike other - * cases, a transfer can skip a bin if it fails to acquire its - * lock, and revisit it later (unless it is a TreeBin). Method - * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that - * have been skipped because of failure to acquire a lock, and - * blocks only if none are available (i.e., only very rarely). - * The transfer operation must also ensure that all accessible - * bins in both the old and new table are usable by any traversal. - * When there are no lock acquisition failures, this is arranged - * simply by proceeding from the last bin (table.length - 1) up - * towards the first. Upon seeing a forwarding node, traversals - * (see class Iter) arrange to move to the new table - * without revisiting nodes. However, when any node is skipped - * during a transfer, all earlier table bins may have become - * visible, so are initialized with a reverse-forwarding node back - * to the old table until the new ones are established. (This - * sometimes requires transiently locking a forwarding node, which - * is possible under the above encoding.) These more expensive - * mechanics trigger only when necessary. - * - * The traversal scheme also applies to partial traversals of - * ranges of bins (via an alternate Traverser constructor) - * to support partitioned aggregate operations. Also, read-only - * operations give up if ever forwarded to a null table, which - * provides support for shutdown-style clearing, which is also not - * currently implemented. - * - * Lazy table initialization minimizes footprint until first use, - * and also avoids resizings when the first operation is from a - * putAll, constructor with map argument, or deserialization. - * These cases attempt to override the initial capacity settings, - * but harmlessly fail to take effect in cases of races. - * - * The element count is maintained using a LongAdder, which avoids - * contention on updates but can encounter cache thrashing if read - * too frequently during concurrent access. To avoid reading so - * often, resizing is attempted either when a bin lock is - * contended, or upon adding to a bin already holding two or more - * nodes (checked before adding in the xIfAbsent methods, after - * adding in others). Under uniform hash distributions, the - * probability of this occurring at threshold is around 13%, - * meaning that only about 1 in 8 puts check threshold (and after - * resizing, many fewer do so). But this approximation has high - * variance for small table sizes, so we check on any collision - * for sizes <= 64. The bulk putAll operation further reduces - * contention by only committing count updates upon these size - * checks. - * - * Maintaining API and serialization compatibility with previous - * versions of this class introduces several oddities. Mainly: We - * leave untouched but unused constructor arguments refering to - * concurrencyLevel. We accept a loadFactor constructor argument, - * but apply it only to initial table capacity (which is the only - * time that we can guarantee to honor it.) We also declare an - * unused "Segment" class that is instantiated in minimal form - * only when serializing. - */ - - /* ---------------- Constants -------------- */ - - /** - * The largest possible table capacity. This value must be - * exactly 1<<30 to stay within Java array allocation and indexing - * bounds for power of two table sizes, and is further required - * because the top two bits of 32bit hash fields are used for - * control purposes. - */ - private static final int MAXIMUM_CAPACITY = 1 << 30; - - /** - * The default initial table capacity. Must be a power of 2 - * (i.e., at least 1) and at most MAXIMUM_CAPACITY. - */ - private static final int DEFAULT_CAPACITY = 16; - - /** - * The largest possible (non-power of two) array size. - * Needed by toArray and related methods. - */ - static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - /** - * The default concurrency level for this table. Unused but - * defined for compatibility with previous versions of this class. - */ - private static final int DEFAULT_CONCURRENCY_LEVEL = 16; - - /** - * The load factor for this table. Overrides of this value in - * constructors affect only the initial table capacity. The - * actual floating point value isn't normally used -- it is - * simpler to use expressions such as {@code n - (n >>> 2)} for - * the associated resizing threshold. - */ - private static final float LOAD_FACTOR = 0.75f; - - /** - * The buffer size for skipped bins during transfers. The - * value is arbitrary but should be large enough to avoid - * most locking stalls during resizes. - */ - private static final int TRANSFER_BUFFER_SIZE = 32; - - /** - * The bin count threshold for using a tree rather than list for a - * bin. The value reflects the approximate break-even point for - * using tree-based operations. - * Note that Doug's version defaults to 8, but when dealing with - * Ruby objects it is actually beneficial to avoid TreeNodes - * as long as possible as it usually means going into Ruby land. - */ - private static final int TREE_THRESHOLD = 16; - - /* - * Encodings for special uses of Node hash fields. See above for - * explanation. - */ - static final int MOVED = 0x80000000; // hash field for forwarding nodes - static final int LOCKED = 0x40000000; // set/tested only as a bit - static final int WAITING = 0xc0000000; // both bits set/tested together - static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash - - /* ---------------- Fields -------------- */ - - /** - * The array of bins. Lazily initialized upon first insertion. - * Size is always a power of two. Accessed directly by iterators. - */ - transient volatile AtomicReferenceArray table; - - /** - * The counter maintaining number of elements. - */ - private transient LongAdder counter; - - /** - * Table initialization and resizing control. When negative, the - * table is being initialized or resized. Otherwise, when table is - * null, holds the initial table size to use upon creation, or 0 - * for default. After initialization, holds the next element count - * value upon which to resize the table. - */ - private transient volatile int sizeCtl; - - // views - private transient KeySetView keySet; - private transient ValuesView values; - private transient EntrySetView entrySet; - - /** For serialization compatibility. Null unless serialized; see below */ - private Segment[] segments; - - static AtomicIntegerFieldUpdater SIZE_CTRL_UPDATER = AtomicIntegerFieldUpdater.newUpdater(ConcurrentHashMapV8.class, "sizeCtl"); - - /* ---------------- Table element access -------------- */ - - /* - * Volatile access methods are used for table elements as well as - * elements of in-progress next table while resizing. Uses are - * null checked by callers, and implicitly bounds-checked, relying - * on the invariants that tab arrays have non-zero size, and all - * indices are masked with (tab.length - 1) which is never - * negative and always less than length. Note that, to be correct - * wrt arbitrary concurrency errors by users, bounds checks must - * operate on local variables, which accounts for some odd-looking - * inline assignments below. - */ - - static final Node tabAt(AtomicReferenceArray tab, int i) { // used by Iter - return tab.get(i); - } - - private static final boolean casTabAt(AtomicReferenceArray tab, int i, Node c, Node v) { - return tab.compareAndSet(i, c, v); - } - - private static final void setTabAt(AtomicReferenceArray tab, int i, Node v) { - tab.set(i, v); - } - - /* ---------------- Nodes -------------- */ - - /** - * Key-value entry. Note that this is never exported out as a - * user-visible Map.Entry (see MapEntry below). Nodes with a hash - * field of MOVED are special, and do not contain user keys or - * values. Otherwise, keys are never null, and null val fields - * indicate that a node is in the process of being deleted or - * created. For purposes of read-only access, a key may be read - * before a val, but can only be used after checking val to be - * non-null. - */ - static class Node { - volatile int hash; - final Object key; - volatile Object val; - volatile Node next; - - static AtomicIntegerFieldUpdater HASH_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Node.class, "hash"); - - Node(int hash, Object key, Object val, Node next) { - this.hash = hash; - this.key = key; - this.val = val; - this.next = next; - } - - /** CompareAndSet the hash field */ - final boolean casHash(int cmp, int val) { - return HASH_UPDATER.compareAndSet(this, cmp, val); - } - - /** The number of spins before blocking for a lock */ - static final int MAX_SPINS = - Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1; - - /** - * Spins a while if LOCKED bit set and this node is the first - * of its bin, and then sets WAITING bits on hash field and - * blocks (once) if they are still set. It is OK for this - * method to return even if lock is not available upon exit, - * which enables these simple single-wait mechanics. - * - * The corresponding signalling operation is performed within - * callers: Upon detecting that WAITING has been set when - * unlocking lock (via a failed CAS from non-waiting LOCKED - * state), unlockers acquire the sync lock and perform a - * notifyAll. - * - * The initial sanity check on tab and bounds is not currently - * necessary in the only usages of this method, but enables - * use in other future contexts. - */ - final void tryAwaitLock(AtomicReferenceArray tab, int i) { - if (tab != null && i >= 0 && i < tab.length()) { // sanity check - int r = ThreadLocalRandom.current().nextInt(); // randomize spins - int spins = MAX_SPINS, h; - while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { - if (spins >= 0) { - r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift - if (r >= 0 && --spins == 0) - Thread.yield(); // yield before block - } - else if (casHash(h, h | WAITING)) { - synchronized (this) { - if (tabAt(tab, i) == this && - (hash & WAITING) == WAITING) { - try { - wait(); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - } - } - else - notifyAll(); // possibly won race vs signaller - } - break; - } - } - } - } - } - - /* ---------------- TreeBins -------------- */ - - /** - * Nodes for use in TreeBins - */ - static final class TreeNode extends Node { - TreeNode parent; // red-black tree links - TreeNode left; - TreeNode right; - TreeNode prev; // needed to unlink next upon deletion - boolean red; - - TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { - super(hash, key, val, next); - this.parent = parent; - } - } - - /** - * A specialized form of red-black tree for use in bins - * whose size exceeds a threshold. - * - * TreeBins use a special form of comparison for search and - * related operations (which is the main reason we cannot use - * existing collections such as TreeMaps). TreeBins contain - * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by getClass().getName() order, and then by Comparator order - * among elements of the same class. On lookup at a node, if - * elements are not comparable or compare as 0, both left and - * right children may need to be searched in the case of tied hash - * values. (This corresponds to the full list search that would be - * necessary if all elements were non-Comparable and had tied - * hashes.) The red-black balancing code is updated from - * pre-jdk-collections - * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) - * based in turn on Cormen, Leiserson, and Rivest "Introduction to - * Algorithms" (CLR). - * - * TreeBins also maintain a separate locking discipline than - * regular bins. Because they are forwarded via special MOVED - * nodes at bin heads (which can never change once established), - * we cannot use those nodes as locks. Instead, TreeBin - * extends AbstractQueuedSynchronizer to support a simple form of - * read-write lock. For update operations and table validation, - * the exclusive form of lock behaves in the same way as bin-head - * locks. However, lookups use shared read-lock mechanics to allow - * multiple readers in the absence of writers. Additionally, - * these lookups do not ever block: While the lock is not - * available, they proceed along the slow traversal path (via - * next-pointers) until the lock becomes available or the list is - * exhausted, whichever comes first. (These cases are not fast, - * but maximize aggregate expected throughput.) The AQS mechanics - * for doing this are straightforward. The lock state is held as - * AQS getState(). Read counts are negative; the write count (1) - * is positive. There are no signalling preferences among readers - * and writers. Since we don't need to export full Lock API, we - * just override the minimal AQS methods and use them directly. - */ - static final class TreeBin extends AbstractQueuedSynchronizer { - private static final long serialVersionUID = 2249069246763182397L; - transient TreeNode root; // root of tree - transient TreeNode first; // head of next-pointer list - - /* AQS overrides */ - public final boolean isHeldExclusively() { return getState() > 0; } - public final boolean tryAcquire(int ignore) { - if (compareAndSetState(0, 1)) { - setExclusiveOwnerThread(Thread.currentThread()); - return true; - } - return false; - } - public final boolean tryRelease(int ignore) { - setExclusiveOwnerThread(null); - setState(0); - return true; - } - public final int tryAcquireShared(int ignore) { - for (int c;;) { - if ((c = getState()) > 0) - return -1; - if (compareAndSetState(c, c -1)) - return 1; - } - } - public final boolean tryReleaseShared(int ignore) { - int c; - do {} while (!compareAndSetState(c = getState(), c + 1)); - return c == -1; - } - - /** From CLR */ - private void rotateLeft(TreeNode p) { - if (p != null) { - TreeNode r = p.right, pp, rl; - if ((rl = p.right = r.left) != null) - rl.parent = p; - if ((pp = r.parent = p.parent) == null) - root = r; - else if (pp.left == p) - pp.left = r; - else - pp.right = r; - r.left = p; - p.parent = r; - } - } - - /** From CLR */ - private void rotateRight(TreeNode p) { - if (p != null) { - TreeNode l = p.left, pp, lr; - if ((lr = p.left = l.right) != null) - lr.parent = p; - if ((pp = l.parent = p.parent) == null) - root = l; - else if (pp.right == p) - pp.right = l; - else - pp.left = l; - l.right = p; - p.parent = l; - } - } - - @SuppressWarnings("unchecked") final TreeNode getTreeNode - (int h, Object k, TreeNode p) { - return getTreeNode(h, (RubyObject)k, p); - } - - /** - * Returns the TreeNode (or null if not found) for the given key - * starting at given root. - */ - @SuppressWarnings("unchecked") final TreeNode getTreeNode - (int h, RubyObject k, TreeNode p) { - RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); - while (p != null) { - int dir, ph; RubyObject pk; RubyClass pc; - if ((ph = p.hash) == h) { - if ((pk = (RubyObject)p.key) == k || k.equals(pk)) - return p; - if (c != (pc = (RubyClass)pk.getMetaClass()) || - kNotComparable || - (dir = rubyCompare(k, pk)) == 0) { - dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); - if (dir == 0) { // if still stuck, need to check both sides - TreeNode r = null, pl, pr; - // try to recurse on the right - if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) - return r; - // try to continue iterating on the left side - else if ((pl = p.left) != null && h <= pl.hash) - dir = -1; - else // no matching node found - return null; - } - } - } - else - dir = (h < ph) ? -1 : 1; - p = (dir > 0) ? p.right : p.left; - } - return null; - } - - int rubyCompare(RubyObject l, RubyObject r) { - ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); - IRubyObject result; - try { - result = l.callMethod(context, "<=>", r); - } catch (RaiseException e) { - // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys - if (context.runtime.getNoMethodError().isInstance(e.getException())) { - return 0; - } - throw e; - } - - return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); - } - - /** - * Wrapper for getTreeNode used by CHM.get. Tries to obtain - * read-lock to call getTreeNode, but during failure to get - * lock, searches along next links. - */ - final Object getValue(int h, Object k) { - Node r = null; - int c = getState(); // Must read lock state first - for (Node e = first; e != null; e = e.next) { - if (c <= 0 && compareAndSetState(c, c - 1)) { - try { - r = getTreeNode(h, k, root); - } finally { - releaseShared(0); - } - break; - } - else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { - r = e; - break; - } - else - c = getState(); - } - return r == null ? null : r.val; - } - - @SuppressWarnings("unchecked") final TreeNode putTreeNode - (int h, Object k, Object v) { - return putTreeNode(h, (RubyObject)k, v); - } - - /** - * Finds or adds a node. - * @return null if added - */ - @SuppressWarnings("unchecked") final TreeNode putTreeNode - (int h, RubyObject k, Object v) { - RubyClass c = k.getMetaClass(); - boolean kNotComparable = !k.respondsTo("<=>"); - TreeNode pp = root, p = null; - int dir = 0; - while (pp != null) { // find existing node or leaf to insert at - int ph; RubyObject pk; RubyClass pc; - p = pp; - if ((ph = p.hash) == h) { - if ((pk = (RubyObject)p.key) == k || k.equals(pk)) - return p; - if (c != (pc = pk.getMetaClass()) || - kNotComparable || - (dir = rubyCompare(k, pk)) == 0) { - dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); - if (dir == 0) { // if still stuck, need to check both sides - TreeNode r = null, pr; - // try to recurse on the right - if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) - return r; - else // continue descending down the left subtree - dir = -1; - } - } - } - else - dir = (h < ph) ? -1 : 1; - pp = (dir > 0) ? p.right : p.left; - } - - TreeNode f = first; - TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); - if (p == null) - root = x; - else { // attach and rebalance; adapted from CLR - TreeNode xp, xpp; - if (f != null) - f.prev = x; - if (dir <= 0) - p.left = x; - else - p.right = x; - x.red = true; - while (x != null && (xp = x.parent) != null && xp.red && - (xpp = xp.parent) != null) { - TreeNode xppl = xpp.left; - if (xp == xppl) { - TreeNode y = xpp.right; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } - else { - if (x == xp.right) { - rotateLeft(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateRight(xpp); - } - } - } - } - else { - TreeNode y = xppl; - if (y != null && y.red) { - y.red = false; - xp.red = false; - xpp.red = true; - x = xpp; - } - else { - if (x == xp.left) { - rotateRight(x = xp); - xpp = (xp = x.parent) == null ? null : xp.parent; - } - if (xp != null) { - xp.red = false; - if (xpp != null) { - xpp.red = true; - rotateLeft(xpp); - } - } - } - } - } - TreeNode r = root; - if (r != null && r.red) - r.red = false; - } - return null; - } - - /** - * Removes the given node, that must be present before this - * call. This is messier than typical red-black deletion code - * because we cannot swap the contents of an interior node - * with a leaf successor that is pinned by "next" pointers - * that are accessible independently of lock. So instead we - * swap the tree linkages. - */ - final void deleteTreeNode(TreeNode p) { - TreeNode next = (TreeNode)p.next; // unlink traversal pointers - TreeNode pred = p.prev; - if (pred == null) - first = next; - else - pred.next = next; - if (next != null) - next.prev = pred; - TreeNode replacement; - TreeNode pl = p.left; - TreeNode pr = p.right; - if (pl != null && pr != null) { - TreeNode s = pr, sl; - while ((sl = s.left) != null) // find successor - s = sl; - boolean c = s.red; s.red = p.red; p.red = c; // swap colors - TreeNode sr = s.right; - TreeNode pp = p.parent; - if (s == pr) { // p was s's direct parent - p.parent = s; - s.right = p; - } - else { - TreeNode sp = s.parent; - if ((p.parent = sp) != null) { - if (s == sp.left) - sp.left = p; - else - sp.right = p; - } - if ((s.right = pr) != null) - pr.parent = s; - } - p.left = null; - if ((p.right = sr) != null) - sr.parent = p; - if ((s.left = pl) != null) - pl.parent = s; - if ((s.parent = pp) == null) - root = s; - else if (p == pp.left) - pp.left = s; - else - pp.right = s; - replacement = sr; - } - else - replacement = (pl != null) ? pl : pr; - TreeNode pp = p.parent; - if (replacement == null) { - if (pp == null) { - root = null; - return; - } - replacement = p; - } - else { - replacement.parent = pp; - if (pp == null) - root = replacement; - else if (p == pp.left) - pp.left = replacement; - else - pp.right = replacement; - p.left = p.right = p.parent = null; - } - if (!p.red) { // rebalance, from CLR - TreeNode x = replacement; - while (x != null) { - TreeNode xp, xpl; - if (x.red || (xp = x.parent) == null) { - x.red = false; - break; - } - if (x == (xpl = xp.left)) { - TreeNode sib = xp.right; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateLeft(xp); - sib = (xp = x.parent) == null ? null : xp.right; - } - if (sib == null) - x = xp; - else { - TreeNode sl = sib.left, sr = sib.right; - if ((sr == null || !sr.red) && - (sl == null || !sl.red)) { - sib.red = true; - x = xp; - } - else { - if (sr == null || !sr.red) { - if (sl != null) - sl.red = false; - sib.red = true; - rotateRight(sib); - sib = (xp = x.parent) == null ? null : xp.right; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sr = sib.right) != null) - sr.red = false; - } - if (xp != null) { - xp.red = false; - rotateLeft(xp); - } - x = root; - } - } - } - else { // symmetric - TreeNode sib = xpl; - if (sib != null && sib.red) { - sib.red = false; - xp.red = true; - rotateRight(xp); - sib = (xp = x.parent) == null ? null : xp.left; - } - if (sib == null) - x = xp; - else { - TreeNode sl = sib.left, sr = sib.right; - if ((sl == null || !sl.red) && - (sr == null || !sr.red)) { - sib.red = true; - x = xp; - } - else { - if (sl == null || !sl.red) { - if (sr != null) - sr.red = false; - sib.red = true; - rotateLeft(sib); - sib = (xp = x.parent) == null ? null : xp.left; - } - if (sib != null) { - sib.red = (xp == null) ? false : xp.red; - if ((sl = sib.left) != null) - sl.red = false; - } - if (xp != null) { - xp.red = false; - rotateRight(xp); - } - x = root; - } - } - } - } - } - if (p == replacement && (pp = p.parent) != null) { - if (p == pp.left) // detach pointers - pp.left = null; - else if (p == pp.right) - pp.right = null; - p.parent = null; - } - } - } - - /* ---------------- Collision reduction methods -------------- */ - - /** - * Spreads higher bits to lower, and also forces top 2 bits to 0. - * Because the table uses power-of-two masking, sets of hashes - * that vary only in bits above the current mask will always - * collide. (Among known examples are sets of Float keys holding - * consecutive whole numbers in small tables.) To counter this, - * we apply a transform that spreads the impact of higher bits - * downward. There is a tradeoff between speed, utility, and - * quality of bit-spreading. Because many common sets of hashes - * are already reasonably distributed across bits (so don't benefit - * from spreading), and because we use trees to handle large sets - * of collisions in bins, we don't need excessively high quality. - */ - private static final int spread(int h) { - h ^= (h >>> 18) ^ (h >>> 12); - return (h ^ (h >>> 10)) & HASH_BITS; - } - - /** - * Replaces a list bin with a tree bin. Call only when locked. - * Fails to replace if the given key is non-comparable or table - * is, or needs, resizing. - */ - private final void replaceWithTreeBin(AtomicReferenceArray tab, int index, Object key) { - if ((key instanceof Comparable) && - (tab.length() >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { - TreeBin t = new TreeBin(); - for (Node e = tabAt(tab, index); e != null; e = e.next) - t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); - setTabAt(tab, index, new Node(MOVED, t, null, null)); - } - } - - /* ---------------- Internal access and update methods -------------- */ - - /** Implementation for get and containsKey */ - private final Object internalGet(Object k) { - int h = spread(k.hashCode()); - retry: for (AtomicReferenceArray tab = table; tab != null;) { - Node e, p; Object ek, ev; int eh; // locals to read fields once - for (e = tabAt(tab, (tab.length() - 1) & h); e != null; e = e.next) { - if ((eh = e.hash) == MOVED) { - if ((ek = e.key) instanceof TreeBin) // search TreeBin - return ((TreeBin)ek).getValue(h, k); - else { // restart with new table - tab = (AtomicReferenceArray)ek; - continue retry; - } - } - else if ((eh & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - } - break; - } - return null; - } - - /** - * Implementation for the four public remove/replace methods: - * Replaces node value with v, conditional upon match of cv if - * non-null. If resulting value is null, delete. - */ - private final Object internalReplace(Object k, Object v, Object cv) { - int h = spread(k.hashCode()); - Object oldVal = null; - for (AtomicReferenceArray tab = table;;) { - Node f; int i, fh; Object fk; - if (tab == null || - (f = tabAt(tab, i = (tab.length() - 1) & h)) == null) - break; - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - boolean deleted = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) { - Object pv = p.val; - if (cv == null || cv == pv || cv.equals(pv)) { - oldVal = pv; - if ((p.val = v) == null) { - deleted = true; - t.deleteTreeNode(p); - } - } - } - } - } finally { - t.release(0); - } - if (validated) { - if (deleted) - counter.add(-1L); - break; - } - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & HASH_BITS) != h && f.next == null) // precheck - break; // rules out possible existence - else if ((fh & LOCKED) != 0) { - checkForResize(); // try resizing if can't get lock - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - boolean validated = false; - boolean deleted = false; - try { - if (tabAt(tab, i) == f) { - validated = true; - for (Node e = f, pred = null;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - ((ev = e.val) != null) && - ((ek = e.key) == k || k.equals(ek))) { - if (cv == null || cv == ev || cv.equals(ev)) { - oldVal = ev; - if ((e.val = v) == null) { - deleted = true; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - } - break; - } - pred = e; - if ((e = e.next) == null) - break; - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (validated) { - if (deleted) - counter.add(-1L); - break; - } - } - } - return oldVal; - } - - /* - * Internal versions of the six insertion methods, each a - * little more complicated than the last. All have - * the same basic structure as the first (internalPut): - * 1. If table uninitialized, create - * 2. If bin empty, try to CAS new node - * 3. If bin stale, use new table - * 4. if bin converted to TreeBin, validate and relay to TreeBin methods - * 5. Lock and validate; if valid, scan and add or update - * - * The others interweave other checks and/or alternative actions: - * * Plain put checks for and performs resize after insertion. - * * putIfAbsent prescans for mapping without lock (and fails to add - * if present), which also makes pre-emptive resize checks worthwhile. - * * computeIfAbsent extends form used in putIfAbsent with additional - * mechanics to deal with, calls, potential exceptions and null - * returns from function call. - * * compute uses the same function-call mechanics, but without - * the prescans - * * merge acts as putIfAbsent in the absent case, but invokes the - * update function if present - * * putAll attempts to pre-allocate enough table space - * and more lazily performs count updates and checks. - * - * Someday when details settle down a bit more, it might be worth - * some factoring to reduce sprawl. - */ - - /** Implementation for put */ - private final Object internalPut(Object k, Object v) { - int h = spread(k.hashCode()); - int count = 0; - for (AtomicReferenceArray tab = table;;) { - int i; Node f; int fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) - break; // no lock when adding to empty bin - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - Object oldVal = null; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 2; - TreeNode p = t.putTreeNode(h, k, v); - if (p != null) { - oldVal = p.val; - p.val = v; - } - } - } finally { - t.release(0); - } - if (count != 0) { - if (oldVal != null) - return oldVal; - break; - } - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - Object oldVal = null; - try { // needed in case equals() throws - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - oldVal = ev; - e.val = v; - break; - } - Node last = e; - if ((e = e.next) == null) { - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { // unlock and signal if needed - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (oldVal != null) - return oldVal; - if (tab.length() <= 64) - count = 2; - break; - } - } - } - counter.add(1L); - if (count > 1) - checkForResize(); - return null; - } - - /** Implementation for putIfAbsent */ - private final Object internalPutIfAbsent(Object k, Object v) { - int h = spread(k.hashCode()); - int count = 0; - for (AtomicReferenceArray tab = table;;) { - int i; Node f; int fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - Object oldVal = null; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 2; - TreeNode p = t.putTreeNode(h, k, v); - if (p != null) - oldVal = p.val; - } - } finally { - t.release(0); - } - if (count != 0) { - if (oldVal != null) - return oldVal; - break; - } - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & HASH_BITS) == h && (fv = f.val) != null && - ((fk = f.key) == k || k.equals(fk))) - return fv; - else { - Node g = f.next; - if (g != null) { // at least 2 nodes -- search and maybe resize - for (Node e = g;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - if ((e = e.next) == null) { - checkForResize(); - break; - } - } - } - if (((fh = f.hash) & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { - Object oldVal = null; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - oldVal = ev; - break; - } - Node last = e; - if ((e = e.next) == null) { - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (oldVal != null) - return oldVal; - if (tab.length() <= 64) - count = 2; - break; - } - } - } - } - counter.add(1L); - if (count > 1) - checkForResize(); - return null; - } - - /** Implementation for computeIfAbsent */ - private final Object internalComputeIfAbsent(K k, - Fun mf) { - int h = spread(k.hashCode()); - Object val = null; - int count = 0; - for (AtomicReferenceArray tab = table;;) { - Node f; int i, fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { - Node node = new Node(fh = h | LOCKED, k, null, null); - if (casTabAt(tab, i, null, node)) { - count = 1; - try { - if ((val = mf.apply(k)) != null) - node.val = val; - } finally { - if (val == null) - setTabAt(tab, i, null); - if (!node.casHash(fh, h)) { - node.hash = h; - synchronized (node) { node.notifyAll(); }; - } - } - } - if (count != 0) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean added = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) - val = p.val; - else if ((val = mf.apply(k)) != null) { - added = true; - count = 2; - t.putTreeNode(h, k, val); - } - } - } finally { - t.release(0); - } - if (count != 0) { - if (!added) - return val; - break; - } - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & HASH_BITS) == h && (fv = f.val) != null && - ((fk = f.key) == k || k.equals(fk))) - return fv; - else { - Node g = f.next; - if (g != null) { - for (Node e = g;;) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) - return ev; - if ((e = e.next) == null) { - checkForResize(); - break; - } - } - } - if (((fh = f.hash) & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { - boolean added = false; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = ev; - break; - } - Node last = e; - if ((e = e.next) == null) { - if ((val = mf.apply(k)) != null) { - added = true; - last.next = new Node(h, k, val, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - } - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (!added) - return val; - if (tab.length() <= 64) - count = 2; - break; - } - } - } - } - if (val != null) { - counter.add(1L); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for compute */ - @SuppressWarnings("unchecked") private final Object internalCompute - (K k, boolean onlyIfPresent, BiFun mf) { - int h = spread(k.hashCode()); - Object val = null; - int delta = 0; - int count = 0; - for (AtomicReferenceArray tab = table;;) { - Node f; int i, fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { - if (onlyIfPresent) - break; - Node node = new Node(fh = h | LOCKED, k, null, null); - if (casTabAt(tab, i, null, node)) { - try { - count = 1; - if ((val = mf.apply(k, null)) != null) { - node.val = val; - delta = 1; - } - } finally { - if (delta == 0) - setTabAt(tab, i, null); - if (!node.casHash(fh, h)) { - node.hash = h; - synchronized (node) { node.notifyAll(); }; - } - } - } - if (count != 0) - break; - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - Object pv; - if (p == null) { - if (onlyIfPresent) - break; - pv = null; - } else - pv = p.val; - if ((val = mf.apply(k, (V)pv)) != null) { - if (p != null) - p.val = val; - else { - count = 2; - delta = 1; - t.putTreeNode(h, k, val); - } - } - else if (p != null) { - delta = -1; - t.deleteTreeNode(p); - } - } - } finally { - t.release(0); - } - if (count != 0) - break; - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f, pred = null;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = mf.apply(k, (V)ev); - if (val != null) - e.val = val; - else { - delta = -1; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - break; - } - pred = e; - if ((e = e.next) == null) { - if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { - pred.next = new Node(h, k, val, null); - delta = 1; - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - } - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (tab.length() <= 64) - count = 2; - break; - } - } - } - if (delta != 0) { - counter.add((long)delta); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for merge */ - @SuppressWarnings("unchecked") private final Object internalMerge - (K k, V v, BiFun mf) { - int h = spread(k.hashCode()); - Object val = null; - int delta = 0; - int count = 0; - for (AtomicReferenceArray tab = table;;) { - int i; Node f; int fh; Object fk, fv; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { - if (casTabAt(tab, i, null, new Node(h, k, v, null))) { - delta = 1; - val = v; - break; - } - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - count = 1; - TreeNode p = t.getTreeNode(h, k, t.root); - val = (p == null) ? v : mf.apply((V)p.val, v); - if (val != null) { - if (p != null) - p.val = val; - else { - count = 2; - delta = 1; - t.putTreeNode(h, k, val); - } - } - else if (p != null) { - delta = -1; - t.deleteTreeNode(p); - } - } - } finally { - t.release(0); - } - if (count != 0) - break; - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & LOCKED) != 0) { - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f, pred = null;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - val = mf.apply((V)ev, v); - if (val != null) - e.val = val; - else { - delta = -1; - Node en = e.next; - if (pred != null) - pred.next = en; - else - setTabAt(tab, i, en); - } - break; - } - pred = e; - if ((e = e.next) == null) { - val = v; - pred.next = new Node(h, k, val, null); - delta = 1; - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (tab.length() <= 64) - count = 2; - break; - } - } - } - if (delta != 0) { - counter.add((long)delta); - if (count > 1) - checkForResize(); - } - return val; - } - - /** Implementation for putAll */ - private final void internalPutAll(Map m) { - tryPresize(m.size()); - long delta = 0L; // number of uncommitted additions - boolean npe = false; // to throw exception on exit for nulls - try { // to clean up counts on other exceptions - for (Map.Entry entry : m.entrySet()) { - Object k, v; - if (entry == null || (k = entry.getKey()) == null || - (v = entry.getValue()) == null) { - npe = true; - break; - } - int h = spread(k.hashCode()); - for (AtomicReferenceArray tab = table;;) { - int i; Node f; int fh; Object fk; - if (tab == null) - tab = initTable(); - else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null){ - if (casTabAt(tab, i, null, new Node(h, k, v, null))) { - ++delta; - break; - } - } - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - TreeNode p = t.getTreeNode(h, k, t.root); - if (p != null) - p.val = v; - else { - t.putTreeNode(h, k, v); - ++delta; - } - } - } finally { - t.release(0); - } - if (validated) - break; - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & LOCKED) != 0) { - counter.add(delta); - delta = 0L; - checkForResize(); - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - int count = 0; - try { - if (tabAt(tab, i) == f) { - count = 1; - for (Node e = f;; ++count) { - Object ek, ev; - if ((e.hash & HASH_BITS) == h && - (ev = e.val) != null && - ((ek = e.key) == k || k.equals(ek))) { - e.val = v; - break; - } - Node last = e; - if ((e = e.next) == null) { - ++delta; - last.next = new Node(h, k, v, null); - if (count >= TREE_THRESHOLD) - replaceWithTreeBin(tab, i, k); - break; - } - } - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (count != 0) { - if (count > 1) { - counter.add(delta); - delta = 0L; - checkForResize(); - } - break; - } - } - } - } - } finally { - if (delta != 0) - counter.add(delta); - } - if (npe) - throw new NullPointerException(); - } - - /* ---------------- Table Initialization and Resizing -------------- */ - - /** - * Returns a power of two table size for the given desired capacity. - * See Hackers Delight, sec 3.2 - */ - private static final int tableSizeFor(int c) { - int n = c - 1; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; - } - - /** - * Initializes table, using the size recorded in sizeCtl. - */ - private final AtomicReferenceArray initTable() { - AtomicReferenceArray tab; int sc; - while ((tab = table) == null) { - if ((sc = sizeCtl) < 0) - Thread.yield(); // lost initialization race; just spin - else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { - try { - if ((tab = table) == null) { - int n = (sc > 0) ? sc : DEFAULT_CAPACITY; - tab = table = new AtomicReferenceArray(n); - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - break; - } - } - return tab; - } - - /** - * If table is too small and not already resizing, creates next - * table and transfers bins. Rechecks occupancy after a transfer - * to see if another resize is already needed because resizings - * are lagging additions. - */ - private final void checkForResize() { - AtomicReferenceArray tab; int n, sc; - while ((tab = table) != null && - (n = tab.length()) < MAXIMUM_CAPACITY && - (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && - SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { - try { - if (tab == table) { - table = rebuild(tab); - sc = (n << 1) - (n >>> 1); - } - } finally { - sizeCtl = sc; - } - } - } - - /** - * Tries to presize table to accommodate the given number of elements. - * - * @param size number of elements (doesn't need to be perfectly accurate) - */ - private final void tryPresize(int size) { - int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : - tableSizeFor(size + (size >>> 1) + 1); - int sc; - while ((sc = sizeCtl) >= 0) { - AtomicReferenceArray tab = table; int n; - if (tab == null || (n = tab.length()) == 0) { - n = (sc > c) ? sc : c; - if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { - try { - if (table == tab) { - table = new AtomicReferenceArray(n); - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - } - } - else if (c <= sc || n >= MAXIMUM_CAPACITY) - break; - else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { - try { - if (table == tab) { - table = rebuild(tab); - sc = (n << 1) - (n >>> 1); - } - } finally { - sizeCtl = sc; - } - } - } - } - - /* - * Moves and/or copies the nodes in each bin to new table. See - * above for explanation. - * - * @return the new table - */ - private static final AtomicReferenceArray rebuild(AtomicReferenceArray tab) { - int n = tab.length(); - AtomicReferenceArray nextTab = new AtomicReferenceArray(n << 1); - Node fwd = new Node(MOVED, nextTab, null, null); - int[] buffer = null; // holds bins to revisit; null until needed - Node rev = null; // reverse forwarder; null until needed - int nbuffered = 0; // the number of bins in buffer list - int bufferIndex = 0; // buffer index of current buffered bin - int bin = n - 1; // current non-buffered bin or -1 if none - - for (int i = bin;;) { // start upwards sweep - int fh; Node f; - if ((f = tabAt(tab, i)) == null) { - if (bin >= 0) { // Unbuffered; no lock needed (or available) - if (!casTabAt(tab, i, f, fwd)) - continue; - } - else { // transiently use a locked forwarding node - Node g = new Node(MOVED|LOCKED, nextTab, null, null); - if (!casTabAt(tab, i, f, g)) - continue; - setTabAt(nextTab, i, null); - setTabAt(nextTab, i + n, null); - setTabAt(tab, i, fwd); - if (!g.casHash(MOVED|LOCKED, MOVED)) { - g.hash = MOVED; - synchronized (g) { g.notifyAll(); } - } - } - } - else if ((fh = f.hash) == MOVED) { - Object fk = f.key; - if (fk instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - boolean validated = false; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - validated = true; - splitTreeBin(nextTab, i, t); - setTabAt(tab, i, fwd); - } - } finally { - t.release(0); - } - if (!validated) - continue; - } - } - else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { - boolean validated = false; - try { // split to lo and hi lists; copying as needed - if (tabAt(tab, i) == f) { - validated = true; - splitBin(nextTab, i, f); - setTabAt(tab, i, fwd); - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - if (!validated) - continue; - } - else { - if (buffer == null) // initialize buffer for revisits - buffer = new int[TRANSFER_BUFFER_SIZE]; - if (bin < 0 && bufferIndex > 0) { - int j = buffer[--bufferIndex]; - buffer[bufferIndex] = i; - i = j; // swap with another bin - continue; - } - if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { - f.tryAwaitLock(tab, i); - continue; // no other options -- block - } - if (rev == null) // initialize reverse-forwarder - rev = new Node(MOVED, tab, null, null); - if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) - continue; // recheck before adding to list - buffer[nbuffered++] = i; - setTabAt(nextTab, i, rev); // install place-holders - setTabAt(nextTab, i + n, rev); - } - - if (bin > 0) - i = --bin; - else if (buffer != null && nbuffered > 0) { - bin = -1; - i = buffer[bufferIndex = --nbuffered]; - } - else - return nextTab; - } - } - - /** - * Splits a normal bin with list headed by e into lo and hi parts; - * installs in given table. - */ - private static void splitBin(AtomicReferenceArray nextTab, int i, Node e) { - int bit = nextTab.length() >>> 1; // bit to split on - int runBit = e.hash & bit; - Node lastRun = e, lo = null, hi = null; - for (Node p = e.next; p != null; p = p.next) { - int b = p.hash & bit; - if (b != runBit) { - runBit = b; - lastRun = p; - } - } - if (runBit == 0) - lo = lastRun; - else - hi = lastRun; - for (Node p = e; p != lastRun; p = p.next) { - int ph = p.hash & HASH_BITS; - Object pk = p.key, pv = p.val; - if ((ph & bit) == 0) - lo = new Node(ph, pk, pv, lo); - else - hi = new Node(ph, pk, pv, hi); - } - setTabAt(nextTab, i, lo); - setTabAt(nextTab, i + bit, hi); - } - - /** - * Splits a tree bin into lo and hi parts; installs in given table. - */ - private static void splitTreeBin(AtomicReferenceArray nextTab, int i, TreeBin t) { - int bit = nextTab.length() >>> 1; - TreeBin lt = new TreeBin(); - TreeBin ht = new TreeBin(); - int lc = 0, hc = 0; - for (Node e = t.first; e != null; e = e.next) { - int h = e.hash & HASH_BITS; - Object k = e.key, v = e.val; - if ((h & bit) == 0) { - ++lc; - lt.putTreeNode(h, k, v); - } - else { - ++hc; - ht.putTreeNode(h, k, v); - } - } - Node ln, hn; // throw away trees if too small - if (lc <= (TREE_THRESHOLD >>> 1)) { - ln = null; - for (Node p = lt.first; p != null; p = p.next) - ln = new Node(p.hash, p.key, p.val, ln); - } - else - ln = new Node(MOVED, lt, null, null); - setTabAt(nextTab, i, ln); - if (hc <= (TREE_THRESHOLD >>> 1)) { - hn = null; - for (Node p = ht.first; p != null; p = p.next) - hn = new Node(p.hash, p.key, p.val, hn); - } - else - hn = new Node(MOVED, ht, null, null); - setTabAt(nextTab, i + bit, hn); - } - - /** - * Implementation for clear. Steps through each bin, removing all - * nodes. - */ - private final void internalClear() { - long delta = 0L; // negative number of deletions - int i = 0; - AtomicReferenceArray tab = table; - while (tab != null && i < tab.length()) { - int fh; Object fk; - Node f = tabAt(tab, i); - if (f == null) - ++i; - else if ((fh = f.hash) == MOVED) { - if ((fk = f.key) instanceof TreeBin) { - TreeBin t = (TreeBin)fk; - t.acquire(0); - try { - if (tabAt(tab, i) == f) { - for (Node p = t.first; p != null; p = p.next) { - if (p.val != null) { // (currently always true) - p.val = null; - --delta; - } - } - t.first = null; - t.root = null; - ++i; - } - } finally { - t.release(0); - } - } - else - tab = (AtomicReferenceArray)fk; - } - else if ((fh & LOCKED) != 0) { - counter.add(delta); // opportunistically update count - delta = 0L; - f.tryAwaitLock(tab, i); - } - else if (f.casHash(fh, fh | LOCKED)) { - try { - if (tabAt(tab, i) == f) { - for (Node e = f; e != null; e = e.next) { - if (e.val != null) { // (currently always true) - e.val = null; - --delta; - } - } - setTabAt(tab, i, null); - ++i; - } - } finally { - if (!f.casHash(fh | LOCKED, fh)) { - f.hash = fh; - synchronized (f) { f.notifyAll(); }; - } - } - } - } - if (delta != 0) - counter.add(delta); - } - - /* ----------------Table Traversal -------------- */ - - /** - * Encapsulates traversal for methods such as containsValue; also - * serves as a base class for other iterators and bulk tasks. - * - * At each step, the iterator snapshots the key ("nextKey") and - * value ("nextVal") of a valid node (i.e., one that, at point of - * snapshot, has a non-null user value). Because val fields can - * change (including to null, indicating deletion), field nextVal - * might not be accurate at point of use, but still maintains the - * weak consistency property of holding a value that was once - * valid. To support iterator.remove, the nextKey field is not - * updated (nulled out) when the iterator cannot advance. - * - * Internal traversals directly access these fields, as in: - * {@code while (it.advance() != null) { process(it.nextKey); }} - * - * Exported iterators must track whether the iterator has advanced - * (in hasNext vs next) (by setting/checking/nulling field - * nextVal), and then extract key, value, or key-value pairs as - * return values of next(). - * - * The iterator visits once each still-valid node that was - * reachable upon iterator construction. It might miss some that - * were added to a bin after the bin was visited, which is OK wrt - * consistency guarantees. Maintaining this property in the face - * of possible ongoing resizes requires a fair amount of - * bookkeeping state that is difficult to optimize away amidst - * volatile accesses. Even so, traversal maintains reasonable - * throughput. - * - * Normally, iteration proceeds bin-by-bin traversing lists. - * However, if the table has been resized, then all future steps - * must traverse both the bin at the current index as well as at - * (index + baseSize); and so on for further resizings. To - * paranoically cope with potential sharing by users of iterators - * across threads, iteration terminates if a bounds checks fails - * for a table read. - * - * This class extends ForkJoinTask to streamline parallel - * iteration in bulk operations (see BulkTask). This adds only an - * int of space overhead, which is close enough to negligible in - * cases where it is not needed to not worry about it. Because - * ForkJoinTask is Serializable, but iterators need not be, we - * need to add warning suppressions. - */ - @SuppressWarnings("serial") static class Traverser { - final ConcurrentHashMapV8 map; - Node next; // the next entry to use - K nextKey; // cached key field of next - V nextVal; // cached val field of next - AtomicReferenceArray tab; // current table; updated if resized - int index; // index of bin to use next - int baseIndex; // current index of initial table - int baseLimit; // index bound for initial table - int baseSize; // initial table size - - /** Creates iterator for all entries in the table. */ - Traverser(ConcurrentHashMapV8 map) { - this.map = map; - } - - /** Creates iterator for split() methods */ - Traverser(Traverser it) { - ConcurrentHashMapV8 m; AtomicReferenceArray t; - if ((m = this.map = it.map) == null) - t = null; - else if ((t = it.tab) == null && // force parent tab initialization - (t = it.tab = m.table) != null) - it.baseLimit = it.baseSize = t.length(); - this.tab = t; - this.baseSize = it.baseSize; - it.baseLimit = this.index = this.baseIndex = - ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; - } - - /** - * Advances next; returns nextVal or null if terminated. - * See above for explanation. - */ - final V advance() { - Node e = next; - V ev = null; - outer: do { - if (e != null) // advance past used/skipped node - e = e.next; - while (e == null) { // get to next non-null bin - ConcurrentHashMapV8 m; - AtomicReferenceArray t; int b, i, n; Object ek; // checks must use locals - if ((t = tab) != null) - n = t.length(); - else if ((m = map) != null && (t = tab = m.table) != null) - n = baseLimit = baseSize = t.length(); - else - break outer; - if ((b = baseIndex) >= baseLimit || - (i = index) < 0 || i >= n) - break outer; - if ((e = tabAt(t, i)) != null && e.hash == MOVED) { - if ((ek = e.key) instanceof TreeBin) - e = ((TreeBin)ek).first; - else { - tab = (AtomicReferenceArray)ek; - continue; // restarts due to null val - } - } // visit upper slots if present - index = (i += baseSize) < n ? i : (baseIndex = b + 1); - } - nextKey = (K) e.key; - } while ((ev = (V) e.val) == null); // skip deleted or special nodes - next = e; - return nextVal = ev; - } - - public final void remove() { - Object k = nextKey; - if (k == null && (advance() == null || (k = nextKey) == null)) - throw new IllegalStateException(); - map.internalReplace(k, null, null); - } - - public final boolean hasNext() { - return nextVal != null || advance() != null; - } - - public final boolean hasMoreElements() { return hasNext(); } - public final void setRawResult(Object x) { } - public R getRawResult() { return null; } - public boolean exec() { return true; } - } - - /* ---------------- Public operations -------------- */ - - /** - * Creates a new, empty map with the default initial table size (16). - */ - public ConcurrentHashMapV8() { - this.counter = new LongAdder(); - } - - /** - * Creates a new, empty map with an initial table size - * accommodating the specified number of elements without the need - * to dynamically resize. - * - * @param initialCapacity The implementation performs internal - * sizing to accommodate this many elements. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative - */ - public ConcurrentHashMapV8(int initialCapacity) { - if (initialCapacity < 0) - throw new IllegalArgumentException(); - int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? - MAXIMUM_CAPACITY : - tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); - this.counter = new LongAdder(); - this.sizeCtl = cap; - } - - /** - * Creates a new map with the same mappings as the given map. - * - * @param m the map - */ - public ConcurrentHashMapV8(Map m) { - this.counter = new LongAdder(); - this.sizeCtl = DEFAULT_CAPACITY; - internalPutAll(m); - } - - /** - * Creates a new, empty map with an initial table size based on - * the given number of elements ({@code initialCapacity}) and - * initial table density ({@code loadFactor}). - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements, - * given the specified load factor. - * @param loadFactor the load factor (table density) for - * establishing the initial table size - * @throws IllegalArgumentException if the initial capacity of - * elements is negative or the load factor is nonpositive - * - * @since 1.6 - */ - public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { - this(initialCapacity, loadFactor, 1); - } - - /** - * Creates a new, empty map with an initial table size based on - * the given number of elements ({@code initialCapacity}), table - * density ({@code loadFactor}), and number of concurrently - * updating threads ({@code concurrencyLevel}). - * - * @param initialCapacity the initial capacity. The implementation - * performs internal sizing to accommodate this many elements, - * given the specified load factor. - * @param loadFactor the load factor (table density) for - * establishing the initial table size - * @param concurrencyLevel the estimated number of concurrently - * updating threads. The implementation may use this value as - * a sizing hint. - * @throws IllegalArgumentException if the initial capacity is - * negative or the load factor or concurrencyLevel are - * nonpositive - */ - public ConcurrentHashMapV8(int initialCapacity, - float loadFactor, int concurrencyLevel) { - if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) - throw new IllegalArgumentException(); - if (initialCapacity < concurrencyLevel) // Use at least as many bins - initialCapacity = concurrencyLevel; // as estimated threads - long size = (long)(1.0 + (long)initialCapacity / loadFactor); - int cap = (size >= (long)MAXIMUM_CAPACITY) ? - MAXIMUM_CAPACITY : tableSizeFor((int)size); - this.counter = new LongAdder(); - this.sizeCtl = cap; - } - - /** - * Creates a new {@link Set} backed by a ConcurrentHashMapV8 - * from the given type to {@code Boolean.TRUE}. - * - * @return the new set - */ - public static KeySetView newKeySet() { - return new KeySetView(new ConcurrentHashMapV8(), - Boolean.TRUE); - } - - /** - * Creates a new {@link Set} backed by a ConcurrentHashMapV8 - * from the given type to {@code Boolean.TRUE}. - * - * @param initialCapacity The implementation performs internal - * sizing to accommodate this many elements. - * @throws IllegalArgumentException if the initial capacity of - * elements is negative - * @return the new set - */ - public static KeySetView newKeySet(int initialCapacity) { - return new KeySetView(new ConcurrentHashMapV8(initialCapacity), - Boolean.TRUE); - } - - /** - * {@inheritDoc} - */ - public boolean isEmpty() { - return counter.sum() <= 0L; // ignore transient negative values - } - - /** - * {@inheritDoc} - */ - public int size() { - long n = counter.sum(); - return ((n < 0L) ? 0 : - (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : - (int)n); - } - - /** - * Returns the number of mappings. This method should be used - * instead of {@link #size} because a ConcurrentHashMapV8 may - * contain more mappings than can be represented as an int. The - * value returned is a snapshot; the actual count may differ if - * there are ongoing concurrent insertions or removals. - * - * @return the number of mappings - */ - public long mappingCount() { - long n = counter.sum(); - return (n < 0L) ? 0L : n; // ignore transient negative values - } - - /** - * Returns the value to which the specified key is mapped, - * or {@code null} if this map contains no mapping for the key. - * - *

More formally, if this map contains a mapping from a key - * {@code k} to a value {@code v} such that {@code key.equals(k)}, - * then this method returns {@code v}; otherwise it returns - * {@code null}. (There can be at most one such mapping.) - * - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V get(Object key) { - if (key == null) - throw new NullPointerException(); - return (V)internalGet(key); - } - - /** - * Returns the value to which the specified key is mapped, - * or the given defaultValue if this map contains no mapping for the key. - * - * @param key the key - * @param defaultValue the value to return if this map contains - * no mapping for the given key - * @return the mapping for the key, if present; else the defaultValue - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { - if (key == null) - throw new NullPointerException(); - V v = (V) internalGet(key); - return v == null ? defaultValue : v; - } - - /** - * Tests if the specified object is a key in this table. - * - * @param key possible key - * @return {@code true} if and only if the specified object - * is a key in this table, as determined by the - * {@code equals} method; {@code false} otherwise - * @throws NullPointerException if the specified key is null - */ - public boolean containsKey(Object key) { - if (key == null) - throw new NullPointerException(); - return internalGet(key) != null; - } - - /** - * Returns {@code true} if this map maps one or more keys to the - * specified value. Note: This method may require a full traversal - * of the map, and is much slower than method {@code containsKey}. - * - * @param value value whose presence in this map is to be tested - * @return {@code true} if this map maps one or more keys to the - * specified value - * @throws NullPointerException if the specified value is null - */ - public boolean containsValue(Object value) { - if (value == null) - throw new NullPointerException(); - Object v; - Traverser it = new Traverser(this); - while ((v = it.advance()) != null) { - if (v == value || value.equals(v)) - return true; - } - return false; - } - - public K findKey(Object value) { - if (value == null) - throw new NullPointerException(); - Object v; - Traverser it = new Traverser(this); - while ((v = it.advance()) != null) { - if (v == value || value.equals(v)) - return it.nextKey; - } - return null; - } - - /** - * Legacy method testing if some key maps into the specified value - * in this table. This method is identical in functionality to - * {@link #containsValue}, and exists solely to ensure - * full compatibility with class {@link java.util.Hashtable}, - * which supported this method prior to introduction of the - * Java Collections framework. - * - * @param value a value to search for - * @return {@code true} if and only if some key maps to the - * {@code value} argument in this table as - * determined by the {@code equals} method; - * {@code false} otherwise - * @throws NullPointerException if the specified value is null - */ - public boolean contains(Object value) { - return containsValue(value); - } - - /** - * Maps the specified key to the specified value in this table. - * Neither the key nor the value can be null. - * - *

The value can be retrieved by calling the {@code get} method - * with a key that is equal to the original key. - * - * @param key key with which the specified value is to be associated - * @param value value to be associated with the specified key - * @return the previous value associated with {@code key}, or - * {@code null} if there was no mapping for {@code key} - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V put(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalPut(key, value); - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or {@code null} if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalPutIfAbsent(key, value); - } - - /** - * Copies all of the mappings from the specified map to this one. - * These mappings replace any mappings that this map had for any of the - * keys currently in the specified map. - * - * @param m mappings to be stored in this map - */ - public void putAll(Map m) { - internalPutAll(m); - } - - /** - * If the specified key is not already associated with a value, - * computes its value using the given mappingFunction and enters - * it into the map unless null. This is equivalent to - *

 {@code
-     * if (map.containsKey(key))
-     *   return map.get(key);
-     * value = mappingFunction.apply(key);
-     * if (value != null)
-     *   map.put(key, value);
-     * return value;}
- * - * except that the action is performed atomically. If the - * function returns {@code null} no mapping is recorded. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and no mapping is recorded. Some - * attempted update operations on this map by other threads may be - * blocked while computation is in progress, so the computation - * should be short and simple, and must not attempt to update any - * other mappings of this Map. The most appropriate usage is to - * construct a new object serving as an initial mapped value, or - * memoized result, as in: - * - *
 {@code
-     * map.computeIfAbsent(key, new Fun() {
-     *   public V map(K k) { return new Value(f(k)); }});}
- * - * @param key key with which the specified value is to be associated - * @param mappingFunction the function to compute a value - * @return the current (existing or computed) value associated with - * the specified key, or null if the computed value is null - * @throws NullPointerException if the specified key or mappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the mappingFunction does so, - * in which case the mapping is left unestablished - */ - @SuppressWarnings("unchecked") public V computeIfAbsent - (K key, Fun mappingFunction) { - if (key == null || mappingFunction == null) - throw new NullPointerException(); - return (V)internalComputeIfAbsent(key, mappingFunction); - } - - /** - * If the given key is present, computes a new mapping value given a key and - * its current mapped value. This is equivalent to - *
 {@code
-     *   if (map.containsKey(key)) {
-     *     value = remappingFunction.apply(key, map.get(key));
-     *     if (value != null)
-     *       map.put(key, value);
-     *     else
-     *       map.remove(key);
-     *   }
-     * }
- * - * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. For example, - * to either create or append new messages to a value mapping: - * - * @param key key with which the specified value is to be associated - * @param remappingFunction the function to compute a value - * @return the new value associated with the specified key, or null if none - * @throws NullPointerException if the specified key or remappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the remappingFunction does so, - * in which case the mapping is unchanged - */ - @SuppressWarnings("unchecked") public V computeIfPresent - (K key, BiFun remappingFunction) { - if (key == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalCompute(key, true, remappingFunction); - } - - /** - * Computes a new mapping value given a key and - * its current mapped value (or {@code null} if there is no current - * mapping). This is equivalent to - *
 {@code
-     *   value = remappingFunction.apply(key, map.get(key));
-     *   if (value != null)
-     *     map.put(key, value);
-     *   else
-     *     map.remove(key);
-     * }
- * - * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. For example, - * to either create or append new messages to a value mapping: - * - *
 {@code
-     * Map map = ...;
-     * final String msg = ...;
-     * map.compute(key, new BiFun() {
-     *   public String apply(Key k, String v) {
-     *    return (v == null) ? msg : v + msg;});}}
- * - * @param key key with which the specified value is to be associated - * @param remappingFunction the function to compute a value - * @return the new value associated with the specified key, or null if none - * @throws NullPointerException if the specified key or remappingFunction - * is null - * @throws IllegalStateException if the computation detectably - * attempts a recursive update to this map that would - * otherwise never complete - * @throws RuntimeException or Error if the remappingFunction does so, - * in which case the mapping is unchanged - */ - @SuppressWarnings("unchecked") public V compute - (K key, BiFun remappingFunction) { - if (key == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalCompute(key, false, remappingFunction); - } - - /** - * If the specified key is not already associated - * with a value, associate it with the given value. - * Otherwise, replace the value with the results of - * the given remapping function. This is equivalent to: - *
 {@code
-     *   if (!map.containsKey(key))
-     *     map.put(value);
-     *   else {
-     *     newValue = remappingFunction.apply(map.get(key), value);
-     *     if (value != null)
-     *       map.put(key, value);
-     *     else
-     *       map.remove(key);
-     *   }
-     * }
- * except that the action is performed atomically. If the - * function returns {@code null}, the mapping is removed. If the - * function itself throws an (unchecked) exception, the exception - * is rethrown to its caller, and the current mapping is left - * unchanged. Some attempted update operations on this map by - * other threads may be blocked while computation is in progress, - * so the computation should be short and simple, and must not - * attempt to update any other mappings of this Map. - */ - @SuppressWarnings("unchecked") public V merge - (K key, V value, BiFun remappingFunction) { - if (key == null || value == null || remappingFunction == null) - throw new NullPointerException(); - return (V)internalMerge(key, value, remappingFunction); - } - - /** - * Removes the key (and its corresponding value) from this map. - * This method does nothing if the key is not in the map. - * - * @param key the key that needs to be removed - * @return the previous value associated with {@code key}, or - * {@code null} if there was no mapping for {@code key} - * @throws NullPointerException if the specified key is null - */ - @SuppressWarnings("unchecked") public V remove(Object key) { - if (key == null) - throw new NullPointerException(); - return (V)internalReplace(key, null, null); - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if the specified key is null - */ - public boolean remove(Object key, Object value) { - if (key == null) - throw new NullPointerException(); - if (value == null) - return false; - return internalReplace(key, null, value) != null; - } - - /** - * {@inheritDoc} - * - * @throws NullPointerException if any of the arguments are null - */ - public boolean replace(K key, V oldValue, V newValue) { - if (key == null || oldValue == null || newValue == null) - throw new NullPointerException(); - return internalReplace(key, newValue, oldValue) != null; - } - - /** - * {@inheritDoc} - * - * @return the previous value associated with the specified key, - * or {@code null} if there was no mapping for the key - * @throws NullPointerException if the specified key or value is null - */ - @SuppressWarnings("unchecked") public V replace(K key, V value) { - if (key == null || value == null) - throw new NullPointerException(); - return (V)internalReplace(key, value, null); - } - - /** - * Removes all of the mappings from this map. - */ - public void clear() { - internalClear(); - } - - /** - * Returns a {@link Set} view of the keys contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. - * - * @return the set view - */ - public KeySetView keySet() { - KeySetView ks = keySet; - return (ks != null) ? ks : (keySet = new KeySetView(this, null)); - } - - /** - * Returns a {@link Set} view of the keys in this map, using the - * given common mapped value for any additions (i.e., {@link - * Collection#add} and {@link Collection#addAll}). This is of - * course only appropriate if it is acceptable to use the same - * value for all additions from this view. - * - * @param mappedValue the mapped value to use for any - * additions. - * @return the set view - * @throws NullPointerException if the mappedValue is null - */ - public KeySetView keySet(V mappedValue) { - if (mappedValue == null) - throw new NullPointerException(); - return new KeySetView(this, mappedValue); - } - - /** - * Returns a {@link Collection} view of the values contained in this map. - * The collection is backed by the map, so changes to the map are - * reflected in the collection, and vice-versa. - */ - public ValuesView values() { - ValuesView vs = values; - return (vs != null) ? vs : (values = new ValuesView(this)); - } - - /** - * Returns a {@link Set} view of the mappings contained in this map. - * The set is backed by the map, so changes to the map are - * reflected in the set, and vice-versa. The set supports element - * removal, which removes the corresponding mapping from the map, - * via the {@code Iterator.remove}, {@code Set.remove}, - * {@code removeAll}, {@code retainAll}, and {@code clear} - * operations. It does not support the {@code add} or - * {@code addAll} operations. - * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - */ - public Set> entrySet() { - EntrySetView es = entrySet; - return (es != null) ? es : (entrySet = new EntrySetView(this)); - } - - /** - * Returns an enumeration of the keys in this table. - * - * @return an enumeration of the keys in this table - * @see #keySet() - */ - public Enumeration keys() { - return new KeyIterator(this); - } - - /** - * Returns an enumeration of the values in this table. - * - * @return an enumeration of the values in this table - * @see #values() - */ - public Enumeration elements() { - return new ValueIterator(this); - } - - /** - * Returns a partitionable iterator of the keys in this map. - * - * @return a partitionable iterator of the keys in this map - */ - public Spliterator keySpliterator() { - return new KeyIterator(this); - } - - /** - * Returns a partitionable iterator of the values in this map. - * - * @return a partitionable iterator of the values in this map - */ - public Spliterator valueSpliterator() { - return new ValueIterator(this); - } - - /** - * Returns a partitionable iterator of the entries in this map. - * - * @return a partitionable iterator of the entries in this map - */ - public Spliterator> entrySpliterator() { - return new EntryIterator(this); - } - - /** - * Returns the hash code value for this {@link Map}, i.e., - * the sum of, for each key-value pair in the map, - * {@code key.hashCode() ^ value.hashCode()}. - * - * @return the hash code value for this map - */ - public int hashCode() { - int h = 0; - Traverser it = new Traverser(this); - Object v; - while ((v = it.advance()) != null) { - h += it.nextKey.hashCode() ^ v.hashCode(); - } - return h; - } - - /** - * Returns a string representation of this map. The string - * representation consists of a list of key-value mappings (in no - * particular order) enclosed in braces ("{@code {}}"). Adjacent - * mappings are separated by the characters {@code ", "} (comma - * and space). Each key-value mapping is rendered as the key - * followed by an equals sign ("{@code =}") followed by the - * associated value. - * - * @return a string representation of this map - */ - public String toString() { - Traverser it = new Traverser(this); - StringBuilder sb = new StringBuilder(); - sb.append('{'); - Object v; - if ((v = it.advance()) != null) { - for (;;) { - Object k = it.nextKey; - sb.append(k == this ? "(this Map)" : k); - sb.append('='); - sb.append(v == this ? "(this Map)" : v); - if ((v = it.advance()) == null) - break; - sb.append(',').append(' '); - } - } - return sb.append('}').toString(); - } - - /** - * Compares the specified object with this map for equality. - * Returns {@code true} if the given object is a map with the same - * mappings as this map. This operation may return misleading - * results if either map is concurrently modified during execution - * of this method. - * - * @param o object to be compared for equality with this map - * @return {@code true} if the specified object is equal to this map - */ - public boolean equals(Object o) { - if (o != this) { - if (!(o instanceof Map)) - return false; - Map m = (Map) o; - Traverser it = new Traverser(this); - Object val; - while ((val = it.advance()) != null) { - Object v = m.get(it.nextKey); - if (v == null || (v != val && !v.equals(val))) - return false; - } - for (Map.Entry e : m.entrySet()) { - Object mk, mv, v; - if ((mk = e.getKey()) == null || - (mv = e.getValue()) == null || - (v = internalGet(mk)) == null || - (mv != v && !mv.equals(v))) - return false; - } - } - return true; - } - - /* ----------------Iterators -------------- */ - - @SuppressWarnings("serial") static final class KeyIterator extends Traverser - implements Spliterator, Enumeration { - KeyIterator(ConcurrentHashMapV8 map) { super(map); } - KeyIterator(Traverser it) { - super(it); - } - public KeyIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new KeyIterator(this); - } - @SuppressWarnings("unchecked") public final K next() { - if (nextVal == null && advance() == null) - throw new NoSuchElementException(); - Object k = nextKey; - nextVal = null; - return (K) k; - } - - public final K nextElement() { return next(); } - } - - @SuppressWarnings("serial") static final class ValueIterator extends Traverser - implements Spliterator, Enumeration { - ValueIterator(ConcurrentHashMapV8 map) { super(map); } - ValueIterator(Traverser it) { - super(it); - } - public ValueIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new ValueIterator(this); - } - - @SuppressWarnings("unchecked") public final V next() { - Object v; - if ((v = nextVal) == null && (v = advance()) == null) - throw new NoSuchElementException(); - nextVal = null; - return (V) v; - } - - public final V nextElement() { return next(); } - } - - @SuppressWarnings("serial") static final class EntryIterator extends Traverser - implements Spliterator> { - EntryIterator(ConcurrentHashMapV8 map) { super(map); } - EntryIterator(Traverser it) { - super(it); - } - public EntryIterator split() { - if (nextKey != null) - throw new IllegalStateException(); - return new EntryIterator(this); - } - - @SuppressWarnings("unchecked") public final Map.Entry next() { - Object v; - if ((v = nextVal) == null && (v = advance()) == null) - throw new NoSuchElementException(); - Object k = nextKey; - nextVal = null; - return new MapEntry((K)k, (V)v, map); - } - } - - /** - * Exported Entry for iterators - */ - static final class MapEntry implements Map.Entry { - final K key; // non-null - V val; // non-null - final ConcurrentHashMapV8 map; - MapEntry(K key, V val, ConcurrentHashMapV8 map) { - this.key = key; - this.val = val; - this.map = map; - } - public final K getKey() { return key; } - public final V getValue() { return val; } - public final int hashCode() { return key.hashCode() ^ val.hashCode(); } - public final String toString(){ return key + "=" + val; } - - public final boolean equals(Object o) { - Object k, v; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (v = e.getValue()) != null && - (k == key || k.equals(key)) && - (v == val || v.equals(val))); - } - - /** - * Sets our entry's value and writes through to the map. The - * value to return is somewhat arbitrary here. Since we do not - * necessarily track asynchronous changes, the most recent - * "previous" value could be different from what we return (or - * could even have been removed in which case the put will - * re-establish). We do not and cannot guarantee more. - */ - public final V setValue(V value) { - if (value == null) throw new NullPointerException(); - V v = val; - val = value; - map.put(key, value); - return v; - } - } - - /* ---------------- Serialization Support -------------- */ - - /** - * Stripped-down version of helper class used in previous version, - * declared for the sake of serialization compatibility - */ - static class Segment implements Serializable { - private static final long serialVersionUID = 2249069246763182397L; - final float loadFactor; - Segment(float lf) { this.loadFactor = lf; } - } - - /** - * Saves the state of the {@code ConcurrentHashMapV8} instance to a - * stream (i.e., serializes it). - * @param s the stream - * @serialData - * the key (Object) and value (Object) - * for each key-value mapping, followed by a null pair. - * The key-value mappings are emitted in no particular order. - */ - @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - if (segments == null) { // for serialization compatibility - segments = (Segment[]) - new Segment[DEFAULT_CONCURRENCY_LEVEL]; - for (int i = 0; i < segments.length; ++i) - segments[i] = new Segment(LOAD_FACTOR); - } - s.defaultWriteObject(); - Traverser it = new Traverser(this); - Object v; - while ((v = it.advance()) != null) { - s.writeObject(it.nextKey); - s.writeObject(v); - } - s.writeObject(null); - s.writeObject(null); - segments = null; // throw away - } - - /** - * Reconstitutes the instance from a stream (that is, deserializes it). - * @param s the stream - */ - @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException { - s.defaultReadObject(); - this.segments = null; // unneeded - // initialize transient final field - this.counter = new LongAdder(); - - // Create all nodes, then place in table once size is known - long size = 0L; - Node p = null; - for (;;) { - K k = (K) s.readObject(); - V v = (V) s.readObject(); - if (k != null && v != null) { - int h = spread(k.hashCode()); - p = new Node(h, k, v, p); - ++size; - } - else - break; - } - if (p != null) { - boolean init = false; - int n; - if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) - n = MAXIMUM_CAPACITY; - else { - int sz = (int)size; - n = tableSizeFor(sz + (sz >>> 1) + 1); - } - int sc = sizeCtl; - boolean collide = false; - if (n > sc && - SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { - try { - if (table == null) { - init = true; - AtomicReferenceArray tab = new AtomicReferenceArray(n); - int mask = n - 1; - while (p != null) { - int j = p.hash & mask; - Node next = p.next; - Node q = p.next = tabAt(tab, j); - setTabAt(tab, j, p); - if (!collide && q != null && q.hash == p.hash) - collide = true; - p = next; - } - table = tab; - counter.add(size); - sc = n - (n >>> 2); - } - } finally { - sizeCtl = sc; - } - if (collide) { // rescan and convert to TreeBins - AtomicReferenceArray tab = table; - for (int i = 0; i < tab.length(); ++i) { - int c = 0; - for (Node e = tabAt(tab, i); e != null; e = e.next) { - if (++c > TREE_THRESHOLD && - (e.key instanceof Comparable)) { - replaceWithTreeBin(tab, i, e.key); - break; - } - } - } - } - } - if (!init) { // Can only happen if unsafely published. - while (p != null) { - internalPut(p.key, p.val); - p = p.next; - } - } - } - } - - - // ------------------------------------------------------- - - // Sams - /** Interface describing a void action of one argument */ - public interface Action { void apply(A a); } - /** Interface describing a void action of two arguments */ - public interface BiAction { void apply(A a, B b); } - /** Interface describing a function of one argument */ - public interface Generator { T apply(); } - /** Interface describing a function mapping its argument to a double */ - public interface ObjectToDouble { double apply(A a); } - /** Interface describing a function mapping its argument to a long */ - public interface ObjectToLong { long apply(A a); } - /** Interface describing a function mapping its argument to an int */ - public interface ObjectToInt {int apply(A a); } - /** Interface describing a function mapping two arguments to a double */ - public interface ObjectByObjectToDouble { double apply(A a, B b); } - /** Interface describing a function mapping two arguments to a long */ - public interface ObjectByObjectToLong { long apply(A a, B b); } - /** Interface describing a function mapping two arguments to an int */ - public interface ObjectByObjectToInt {int apply(A a, B b); } - /** Interface describing a function mapping a double to a double */ - public interface DoubleToDouble { double apply(double a); } - /** Interface describing a function mapping a long to a long */ - public interface LongToLong { long apply(long a); } - /** Interface describing a function mapping an int to an int */ - public interface IntToInt { int apply(int a); } - /** Interface describing a function mapping two doubles to a double */ - public interface DoubleByDoubleToDouble { double apply(double a, double b); } - /** Interface describing a function mapping two longs to a long */ - public interface LongByLongToLong { long apply(long a, long b); } - /** Interface describing a function mapping two ints to an int */ - public interface IntByIntToInt { int apply(int a, int b); } - - - /* ----------------Views -------------- */ - - /** - * Base class for views. - */ - static abstract class CHMView { - final ConcurrentHashMapV8 map; - CHMView(ConcurrentHashMapV8 map) { this.map = map; } - - /** - * Returns the map backing this view. - * - * @return the map backing this view - */ - public ConcurrentHashMapV8 getMap() { return map; } - - public final int size() { return map.size(); } - public final boolean isEmpty() { return map.isEmpty(); } - public final void clear() { map.clear(); } - - // implementations below rely on concrete classes supplying these - abstract public Iterator iterator(); - abstract public boolean contains(Object o); - abstract public boolean remove(Object o); - - private static final String oomeMsg = "Required array size too large"; - - public final Object[] toArray() { - long sz = map.mappingCount(); - if (sz > (long)(MAX_ARRAY_SIZE)) - throw new OutOfMemoryError(oomeMsg); - int n = (int)sz; - Object[] r = new Object[n]; - int i = 0; - Iterator it = iterator(); - while (it.hasNext()) { - if (i == n) { - if (n >= MAX_ARRAY_SIZE) - throw new OutOfMemoryError(oomeMsg); - if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) - n = MAX_ARRAY_SIZE; - else - n += (n >>> 1) + 1; - r = Arrays.copyOf(r, n); - } - r[i++] = it.next(); - } - return (i == n) ? r : Arrays.copyOf(r, i); - } - - @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { - long sz = map.mappingCount(); - if (sz > (long)(MAX_ARRAY_SIZE)) - throw new OutOfMemoryError(oomeMsg); - int m = (int)sz; - T[] r = (a.length >= m) ? a : - (T[])java.lang.reflect.Array - .newInstance(a.getClass().getComponentType(), m); - int n = r.length; - int i = 0; - Iterator it = iterator(); - while (it.hasNext()) { - if (i == n) { - if (n >= MAX_ARRAY_SIZE) - throw new OutOfMemoryError(oomeMsg); - if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) - n = MAX_ARRAY_SIZE; - else - n += (n >>> 1) + 1; - r = Arrays.copyOf(r, n); - } - r[i++] = (T)it.next(); - } - if (a == r && i < n) { - r[i] = null; // null-terminate - return r; - } - return (i == n) ? r : Arrays.copyOf(r, i); - } - - public final int hashCode() { - int h = 0; - for (Iterator it = iterator(); it.hasNext();) - h += it.next().hashCode(); - return h; - } - - public final String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('['); - Iterator it = iterator(); - if (it.hasNext()) { - for (;;) { - Object e = it.next(); - sb.append(e == this ? "(this Collection)" : e); - if (!it.hasNext()) - break; - sb.append(',').append(' '); - } - } - return sb.append(']').toString(); - } - - public final boolean containsAll(Collection c) { - if (c != this) { - for (Iterator it = c.iterator(); it.hasNext();) { - Object e = it.next(); - if (e == null || !contains(e)) - return false; - } - } - return true; - } - - public final boolean removeAll(Collection c) { - boolean modified = false; - for (Iterator it = iterator(); it.hasNext();) { - if (c.contains(it.next())) { - it.remove(); - modified = true; - } - } - return modified; - } - - public final boolean retainAll(Collection c) { - boolean modified = false; - for (Iterator it = iterator(); it.hasNext();) { - if (!c.contains(it.next())) { - it.remove(); - modified = true; - } - } - return modified; - } - - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in - * which additions may optionally be enabled by mapping to a - * common value. This class cannot be directly instantiated. See - * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, - * {@link #newKeySet(int)}. - */ - public static class KeySetView extends CHMView implements Set, java.io.Serializable { - private static final long serialVersionUID = 7249069246763182397L; - private final V value; - KeySetView(ConcurrentHashMapV8 map, V value) { // non-public - super(map); - this.value = value; - } - - /** - * Returns the default mapped value for additions, - * or {@code null} if additions are not supported. - * - * @return the default mapped value for additions, or {@code null} - * if not supported. - */ - public V getMappedValue() { return value; } - - // implement Set API - - public boolean contains(Object o) { return map.containsKey(o); } - public boolean remove(Object o) { return map.remove(o) != null; } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the keys of this map - */ - public Iterator iterator() { return new KeyIterator(map); } - public boolean add(K e) { - V v; - if ((v = value) == null) - throw new UnsupportedOperationException(); - if (e == null) - throw new NullPointerException(); - return map.internalPutIfAbsent(e, v) == null; - } - public boolean addAll(Collection c) { - boolean added = false; - V v; - if ((v = value) == null) - throw new UnsupportedOperationException(); - for (K e : c) { - if (e == null) - throw new NullPointerException(); - if (map.internalPutIfAbsent(e, v) == null) - added = true; - } - return added; - } - public boolean equals(Object o) { - Set c; - return ((o instanceof Set) && - ((c = (Set)o) == this || - (containsAll(c) && c.containsAll(this)))); - } - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Collection} of - * values, in which additions are disabled. This class cannot be - * directly instantiated. See {@link #values}, - * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. - */ - public static final class ValuesView extends CHMView - implements Collection { - ValuesView(ConcurrentHashMapV8 map) { super(map); } - public final boolean contains(Object o) { return map.containsValue(o); } - public final boolean remove(Object o) { - if (o != null) { - Iterator it = new ValueIterator(map); - while (it.hasNext()) { - if (o.equals(it.next())) { - it.remove(); - return true; - } - } - } - return false; - } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the values of this map - */ - public final Iterator iterator() { - return new ValueIterator(map); - } - public final boolean add(V e) { - throw new UnsupportedOperationException(); - } - public final boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - } - - /** - * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) - * entries. This class cannot be directly instantiated. See - * {@link #entrySet}. - */ - public static final class EntrySetView extends CHMView - implements Set> { - EntrySetView(ConcurrentHashMapV8 map) { super(map); } - public final boolean contains(Object o) { - Object k, v, r; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (r = map.get(k)) != null && - (v = e.getValue()) != null && - (v == r || v.equals(r))); - } - public final boolean remove(Object o) { - Object k, v; Map.Entry e; - return ((o instanceof Map.Entry) && - (k = (e = (Map.Entry)o).getKey()) != null && - (v = e.getValue()) != null && - map.remove(k, v)); - } - - /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. - * - * @return an iterator over the entries of this map - */ - public final Iterator> iterator() { - return new EntryIterator(map); - } - - public final boolean add(Entry e) { - K key = e.getKey(); - V value = e.getValue(); - if (key == null || value == null) - throw new NullPointerException(); - return map.internalPut(key, value) == null; - } - public final boolean addAll(Collection> c) { - boolean added = false; - for (Entry e : c) { - if (add(e)) - added = true; - } - return added; - } - public boolean equals(Object o) { - Set c; - return ((o instanceof Set) && - ((c = (Set)o) == this || - (containsAll(c) && c.containsAll(this)))); - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java deleted file mode 100644 index ecf552a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on 1.9 version. - -package com.concurrent_ruby.ext.jsr166e.nounsafe; - -import java.util.concurrent.atomic.AtomicLong; -import java.io.IOException; -import java.io.Serializable; -import java.io.ObjectInputStream; - -/** - * One or more variables that together maintain an initially zero - * {@code long} sum. When updates (method {@link #add}) are contended - * across threads, the set of variables may grow dynamically to reduce - * contention. Method {@link #sum} (or, equivalently, {@link - * #longValue}) returns the current total combined across the - * variables maintaining the sum. - * - *

This class is usually preferable to {@link AtomicLong} when - * multiple threads update a common sum that is used for purposes such - * as collecting statistics, not for fine-grained synchronization - * control. Under low update contention, the two classes have similar - * characteristics. But under high contention, expected throughput of - * this class is significantly higher, at the expense of higher space - * consumption. - * - *

This class extends {@link Number}, but does not define - * methods such as {@code hashCode} and {@code compareTo} because - * instances are expected to be mutated, and so are not useful as - * collection keys. - * - *

jsr166e note: This class is targeted to be placed in - * java.util.concurrent.atomic. - * - * @since 1.8 - * @author Doug Lea - */ -public class LongAdder extends Striped64 implements Serializable { - private static final long serialVersionUID = 7249069246863182397L; - - /** - * Version of plus for use in retryUpdate - */ - final long fn(long v, long x) { return v + x; } - - /** - * Creates a new adder with initial sum of zero. - */ - public LongAdder() { - } - - /** - * Adds the given value. - * - * @param x the value to add - */ - public void add(long x) { - Cell[] as; long b, v; HashCode hc; Cell a; int n; - if ((as = cells) != null || !casBase(b = base, b + x)) { - boolean uncontended = true; - int h = (hc = threadHashCode.get()).code; - if (as == null || (n = as.length) < 1 || - (a = as[(n - 1) & h]) == null || - !(uncontended = a.cas(v = a.value, v + x))) - retryUpdate(x, hc, uncontended); - } - } - - /** - * Equivalent to {@code add(1)}. - */ - public void increment() { - add(1L); - } - - /** - * Equivalent to {@code add(-1)}. - */ - public void decrement() { - add(-1L); - } - - /** - * Returns the current sum. The returned value is NOT an - * atomic snapshot: Invocation in the absence of concurrent - * updates returns an accurate result, but concurrent updates that - * occur while the sum is being calculated might not be - * incorporated. - * - * @return the sum - */ - public long sum() { - long sum = base; - Cell[] as = cells; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - sum += a.value; - } - } - return sum; - } - - /** - * Resets variables maintaining the sum to zero. This method may - * be a useful alternative to creating a new adder, but is only - * effective if there are no concurrent updates. Because this - * method is intrinsically racy, it should only be used when it is - * known that no threads are concurrently updating. - */ - public void reset() { - internalReset(0L); - } - - /** - * Equivalent in effect to {@link #sum} followed by {@link - * #reset}. This method may apply for example during quiescent - * points between multithreaded computations. If there are - * updates concurrent with this method, the returned value is - * not guaranteed to be the final value occurring before - * the reset. - * - * @return the sum - */ - public long sumThenReset() { - long sum = base; - Cell[] as = cells; - base = 0L; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) { - sum += a.value; - a.value = 0L; - } - } - } - return sum; - } - - /** - * Returns the String representation of the {@link #sum}. - * @return the String representation of the {@link #sum} - */ - public String toString() { - return Long.toString(sum()); - } - - /** - * Equivalent to {@link #sum}. - * - * @return the sum - */ - public long longValue() { - return sum(); - } - - /** - * Returns the {@link #sum} as an {@code int} after a narrowing - * primitive conversion. - */ - public int intValue() { - return (int)sum(); - } - - /** - * Returns the {@link #sum} as a {@code float} - * after a widening primitive conversion. - */ - public float floatValue() { - return (float)sum(); - } - - /** - * Returns the {@link #sum} as a {@code double} after a widening - * primitive conversion. - */ - public double doubleValue() { - return (double)sum(); - } - - private void writeObject(java.io.ObjectOutputStream s) - throws java.io.IOException { - s.defaultWriteObject(); - s.writeLong(sum()); - } - - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - busy = 0; - cells = null; - base = s.readLong(); - } - -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java deleted file mode 100644 index f521642..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on 1.5 version. - -package com.concurrent_ruby.ext.jsr166e.nounsafe; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; - -/** - * A package-local class holding common representation and mechanics - * for classes supporting dynamic striping on 64bit values. The class - * extends Number so that concrete subclasses must publicly do so. - */ -abstract class Striped64 extends Number { - /* - * This class maintains a lazily-initialized table of atomically - * updated variables, plus an extra "base" field. The table size - * is a power of two. Indexing uses masked per-thread hash codes. - * Nearly all declarations in this class are package-private, - * accessed directly by subclasses. - * - * Table entries are of class Cell; a variant of AtomicLong padded - * to reduce cache contention on most processors. Padding is - * overkill for most Atomics because they are usually irregularly - * scattered in memory and thus don't interfere much with each - * other. But Atomic objects residing in arrays will tend to be - * placed adjacent to each other, and so will most often share - * cache lines (with a huge negative performance impact) without - * this precaution. - * - * In part because Cells are relatively large, we avoid creating - * them until they are needed. When there is no contention, all - * updates are made to the base field. Upon first contention (a - * failed CAS on base update), the table is initialized to size 2. - * The table size is doubled upon further contention until - * reaching the nearest power of two greater than or equal to the - * number of CPUS. Table slots remain empty (null) until they are - * needed. - * - * A single spinlock ("busy") is used for initializing and - * resizing the table, as well as populating slots with new Cells. - * There is no need for a blocking lock: When the lock is not - * available, threads try other slots (or the base). During these - * retries, there is increased contention and reduced locality, - * which is still better than alternatives. - * - * Per-thread hash codes are initialized to random values. - * Contention and/or table collisions are indicated by failed - * CASes when performing an update operation (see method - * retryUpdate). Upon a collision, if the table size is less than - * the capacity, it is doubled in size unless some other thread - * holds the lock. If a hashed slot is empty, and lock is - * available, a new Cell is created. Otherwise, if the slot - * exists, a CAS is tried. Retries proceed by "double hashing", - * using a secondary hash (Marsaglia XorShift) to try to find a - * free slot. - * - * The table size is capped because, when there are more threads - * than CPUs, supposing that each thread were bound to a CPU, - * there would exist a perfect hash function mapping threads to - * slots that eliminates collisions. When we reach capacity, we - * search for this mapping by randomly varying the hash codes of - * colliding threads. Because search is random, and collisions - * only become known via CAS failures, convergence can be slow, - * and because threads are typically not bound to CPUS forever, - * may not occur at all. However, despite these limitations, - * observed contention rates are typically low in these cases. - * - * It is possible for a Cell to become unused when threads that - * once hashed to it terminate, as well as in the case where - * doubling the table causes no thread to hash to it under - * expanded mask. We do not try to detect or remove such cells, - * under the assumption that for long-running instances, observed - * contention levels will recur, so the cells will eventually be - * needed again; and for short-lived ones, it does not matter. - */ - - /** - * Padded variant of AtomicLong supporting only raw accesses plus CAS. - * The value field is placed between pads, hoping that the JVM doesn't - * reorder them. - * - * JVM intrinsics note: It would be possible to use a release-only - * form of CAS here, if it were provided. - */ - static final class Cell { - volatile long p0, p1, p2, p3, p4, p5, p6; - volatile long value; - volatile long q0, q1, q2, q3, q4, q5, q6; - - static AtomicLongFieldUpdater VALUE_UPDATER = AtomicLongFieldUpdater.newUpdater(Cell.class, "value"); - - Cell(long x) { value = x; } - - final boolean cas(long cmp, long val) { - return VALUE_UPDATER.compareAndSet(this, cmp, val); - } - - } - - /** - * Holder for the thread-local hash code. The code is initially - * random, but may be set to a different value upon collisions. - */ - static final class HashCode { - static final Random rng = new Random(); - int code; - HashCode() { - int h = rng.nextInt(); // Avoid zero to allow xorShift rehash - code = (h == 0) ? 1 : h; - } - } - - /** - * The corresponding ThreadLocal class - */ - static final class ThreadHashCode extends ThreadLocal { - public HashCode initialValue() { return new HashCode(); } - } - - /** - * Static per-thread hash codes. Shared across all instances to - * reduce ThreadLocal pollution and because adjustments due to - * collisions in one table are likely to be appropriate for - * others. - */ - static final ThreadHashCode threadHashCode = new ThreadHashCode(); - - /** Number of CPUS, to place bound on table size */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * Table of cells. When non-null, size is a power of 2. - */ - transient volatile Cell[] cells; - - /** - * Base value, used mainly when there is no contention, but also as - * a fallback during table initialization races. Updated via CAS. - */ - transient volatile long base; - - /** - * Spinlock (locked via CAS) used when resizing and/or creating Cells. - */ - transient volatile int busy; - - AtomicLongFieldUpdater BASE_UPDATER = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base"); - AtomicIntegerFieldUpdater BUSY_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy"); - - /** - * Package-private default constructor - */ - Striped64() { - } - - /** - * CASes the base field. - */ - final boolean casBase(long cmp, long val) { - return BASE_UPDATER.compareAndSet(this, cmp, val); - } - - /** - * CASes the busy field from 0 to 1 to acquire lock. - */ - final boolean casBusy() { - return BUSY_UPDATER.compareAndSet(this, 0, 1); - } - - /** - * Computes the function of current and new value. Subclasses - * should open-code this update function for most uses, but the - * virtualized form is needed within retryUpdate. - * - * @param currentValue the current value (of either base or a cell) - * @param newValue the argument from a user update call - * @return result of the update function - */ - abstract long fn(long currentValue, long newValue); - - /** - * Handles cases of updates involving initialization, resizing, - * creating new Cells, and/or contention. See above for - * explanation. This method suffers the usual non-modularity - * problems of optimistic retry code, relying on rechecked sets of - * reads. - * - * @param x the value - * @param hc the hash code holder - * @param wasUncontended false if CAS failed before call - */ - final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { - int h = hc.code; - boolean collide = false; // True if last slot nonempty - for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { - if (busy == 0) { // Try to attach new Cell - Cell r = new Cell(x); // Optimistically create - if (busy == 0 && casBusy()) { - boolean created = false; - try { // Recheck under lock - Cell[] rs; int m, j; - if ((rs = cells) != null && - (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { - rs[j] = r; - created = true; - } - } finally { - busy = 0; - } - if (created) - break; - continue; // Slot is now non-empty - } - } - collide = false; - } - else if (!wasUncontended) // CAS already known to fail - wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, fn(v, x))) - break; - else if (n >= NCPU || cells != as) - collide = false; // At max size or stale - else if (!collide) - collide = true; - else if (busy == 0 && casBusy()) { - try { - if (cells == as) { // Expand table unless stale - Cell[] rs = new Cell[n << 1]; - for (int i = 0; i < n; ++i) - rs[i] = as[i]; - cells = rs; - } - } finally { - busy = 0; - } - collide = false; - continue; // Retry with expanded table - } - h ^= h << 13; // Rehash - h ^= h >>> 17; - h ^= h << 5; - } - else if (busy == 0 && cells == as && casBusy()) { - boolean init = false; - try { // Initialize table - if (cells == as) { - Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); - cells = rs; - init = true; - } - } finally { - busy = 0; - } - if (init) - break; - } - else if (casBase(v = base, fn(v, x))) - break; // Fall back on using base - } - hc.code = h; // Record index for next time - } - - - /** - * Sets base and all cells to the given value. - */ - final void internalReset(long initialValue) { - Cell[] as = cells; - base = initialValue; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - a.value = initialValue; - } - } - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java deleted file mode 100644 index 3ea409f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// This is based on 1.16 version - -package com.concurrent_ruby.ext.jsr166y; - -import java.util.Random; - -/** - * A random number generator isolated to the current thread. Like the - * global {@link java.util.Random} generator used by the {@link - * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized - * with an internally generated seed that may not otherwise be - * modified. When applicable, use of {@code ThreadLocalRandom} rather - * than shared {@code Random} objects in concurrent programs will - * typically encounter much less overhead and contention. Use of - * {@code ThreadLocalRandom} is particularly appropriate when multiple - * tasks (for example, each a {@link ForkJoinTask}) use random numbers - * in parallel in thread pools. - * - *

Usages of this class should typically be of the form: - * {@code ThreadLocalRandom.current().nextX(...)} (where - * {@code X} is {@code Int}, {@code Long}, etc). - * When all usages are of this form, it is never possible to - * accidently share a {@code ThreadLocalRandom} across multiple threads. - * - *

This class also provides additional commonly used bounded random - * generation methods. - * - * @since 1.7 - * @author Doug Lea - */ -public class ThreadLocalRandom extends Random { - // same constants as Random, but must be redeclared because private - private static final long multiplier = 0x5DEECE66DL; - private static final long addend = 0xBL; - private static final long mask = (1L << 48) - 1; - - /** - * The random seed. We can't use super.seed. - */ - private long rnd; - - /** - * Initialization flag to permit calls to setSeed to succeed only - * while executing the Random constructor. We can't allow others - * since it would cause setting seed in one part of a program to - * unintentionally impact other usages by the thread. - */ - boolean initialized; - - // Padding to help avoid memory contention among seed updates in - // different TLRs in the common case that they are located near - // each other. - private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; - - /** - * The actual ThreadLocal - */ - private static final ThreadLocal localRandom = - new ThreadLocal() { - protected ThreadLocalRandom initialValue() { - return new ThreadLocalRandom(); - } - }; - - - /** - * Constructor called only by localRandom.initialValue. - */ - ThreadLocalRandom() { - super(); - initialized = true; - } - - /** - * Returns the current thread's {@code ThreadLocalRandom}. - * - * @return the current thread's {@code ThreadLocalRandom} - */ - public static ThreadLocalRandom current() { - return localRandom.get(); - } - - /** - * Throws {@code UnsupportedOperationException}. Setting seeds in - * this generator is not supported. - * - * @throws UnsupportedOperationException always - */ - public void setSeed(long seed) { - if (initialized) - throw new UnsupportedOperationException(); - rnd = (seed ^ multiplier) & mask; - } - - protected int next(int bits) { - rnd = (rnd * multiplier + addend) & mask; - return (int) (rnd >>> (48-bits)); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @throws IllegalArgumentException if least greater than or equal - * to bound - * @return the next value - */ - public int nextInt(int least, int bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextInt(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed value - * between 0 (inclusive) and the specified value (exclusive). - * - * @param n the bound on the random number to be returned. Must be - * positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public long nextLong(long n) { - if (n <= 0) - throw new IllegalArgumentException("n must be positive"); - // Divide n by two until small enough for nextInt. On each - // iteration (at most 31 of them but usually much less), - // randomly choose both whether to include high bit in result - // (offset) and whether to continue with the lower vs upper - // half (which makes a difference only if odd). - long offset = 0; - while (n >= Integer.MAX_VALUE) { - int bits = next(2); - long half = n >>> 1; - long nextn = ((bits & 2) == 0) ? half : n - half; - if ((bits & 1) == 0) - offset += n - nextn; - n = nextn; - } - return offset + nextInt((int) n); - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal - * to bound - */ - public long nextLong(long least, long bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextLong(bound - least) + least; - } - - /** - * Returns a pseudorandom, uniformly distributed {@code double} value - * between 0 (inclusive) and the specified value (exclusive). - * - * @param n the bound on the random number to be returned. Must be - * positive. - * @return the next value - * @throws IllegalArgumentException if n is not positive - */ - public double nextDouble(double n) { - if (n <= 0) - throw new IllegalArgumentException("n must be positive"); - return nextDouble() * n; - } - - /** - * Returns a pseudorandom, uniformly distributed value between the - * given least value (inclusive) and bound (exclusive). - * - * @param least the least value returned - * @param bound the upper bound (exclusive) - * @return the next value - * @throws IllegalArgumentException if least greater than or equal - * to bound - */ - public double nextDouble(double least, double bound) { - if (least >= bound) - throw new IllegalArgumentException(); - return nextDouble() * (bound - least) + least; - } - - private static final long serialVersionUID = -5851777807851030925L; -} diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent-ruby.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent-ruby.rb deleted file mode 100644 index e9a3dea..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent-ruby.rb +++ /dev/null @@ -1,5 +0,0 @@ -# This file is here so that there is a file with the same name as the gem that -# can be required by Bundler.require. Applications should normally -# require 'concurrent'. - -require_relative "concurrent" diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent.rb deleted file mode 100644 index 87de46f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent.rb +++ /dev/null @@ -1,134 +0,0 @@ -require 'concurrent/version' -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/configuration' - -require 'concurrent/atomics' -require 'concurrent/executors' -require 'concurrent/synchronization' - -require 'concurrent/atomic/atomic_markable_reference' -require 'concurrent/atomic/atomic_reference' -require 'concurrent/agent' -require 'concurrent/atom' -require 'concurrent/array' -require 'concurrent/hash' -require 'concurrent/set' -require 'concurrent/map' -require 'concurrent/tuple' -require 'concurrent/async' -require 'concurrent/dataflow' -require 'concurrent/delay' -require 'concurrent/exchanger' -require 'concurrent/future' -require 'concurrent/immutable_struct' -require 'concurrent/ivar' -require 'concurrent/maybe' -require 'concurrent/mutable_struct' -require 'concurrent/mvar' -require 'concurrent/promise' -require 'concurrent/scheduled_task' -require 'concurrent/settable_struct' -require 'concurrent/timer_task' -require 'concurrent/tvar' -require 'concurrent/promises' - -require 'concurrent/thread_safe/synchronized_delegator' -require 'concurrent/thread_safe/util' - -require 'concurrent/options' - -# @!macro internal_implementation_note -# -# @note **Private Implementation:** This abstraction is a private, internal -# implementation detail. It should never be used directly. - -# @!macro monotonic_clock_warning -# -# @note Time calculations on all platforms and languages are sensitive to -# changes to the system clock. To alleviate the potential problems -# associated with changing the system clock while an application is running, -# most modern operating systems provide a monotonic clock that operates -# independently of the system clock. A monotonic clock cannot be used to -# determine human-friendly clock times. A monotonic clock is used exclusively -# for calculating time intervals. Not all Ruby platforms provide access to an -# operating system monotonic clock. On these platforms a pure-Ruby monotonic -# clock will be used as a fallback. An operating system monotonic clock is both -# faster and more reliable than the pure-Ruby implementation. The pure-Ruby -# implementation should be fast and reliable enough for most non-realtime -# operations. At this time the common Ruby platforms that provide access to an -# operating system monotonic clock are MRI 2.1 and above and JRuby (all versions). -# -# @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3) - -# @!macro copy_options -# -# ## Copy Options -# -# Object references in Ruby are mutable. This can lead to serious -# problems when the {#value} of an object is a mutable reference. Which -# is always the case unless the value is a `Fixnum`, `Symbol`, or similar -# "primitive" data type. Each instance can be configured with a few -# options that can help protect the program from potentially dangerous -# operations. Each of these options can be optionally set when the object -# instance is created: -# -# * `:dup_on_deref` When true the object will call the `#dup` method on -# the `value` object every time the `#value` method is called -# (default: false) -# * `:freeze_on_deref` When true the object will call the `#freeze` -# method on the `value` object every time the `#value` method is called -# (default: false) -# * `:copy_on_deref` When given a `Proc` object the `Proc` will be run -# every time the `#value` method is called. The `Proc` will be given -# the current `value` as its only argument and the result returned by -# the block will be the return value of the `#value` call. When `nil` -# this option will be ignored (default: nil) -# -# When multiple deref options are set the order of operations is strictly defined. -# The order of deref operations is: -# * `:copy_on_deref` -# * `:dup_on_deref` -# * `:freeze_on_deref` -# -# Because of this ordering there is no need to `#freeze` an object created by a -# provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`. -# Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is -# as close to the behavior of a "pure" functional language (like Erlang, Clojure, -# or Haskell) as we are likely to get in Ruby. - -# @!macro deref_options -# -# @option opts [Boolean] :dup_on_deref (false) Call `#dup` before -# returning the data from {#value} -# @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before -# returning the data from {#value} -# @option opts [Proc] :copy_on_deref (nil) When calling the {#value} -# method, call the given proc passing the internal value as the sole -# argument then return the new value returned from the proc. - -# @!macro executor_and_deref_options -# -# @param [Hash] opts the options used to define the behavior at update and deref -# and to specify the executor on which to perform actions -# @option opts [Executor] :executor when set use the given `Executor` instance. -# Three special values are also supported: `:io` returns the global pool for -# long, blocking (IO) tasks, `:fast` returns the global pool for short, fast -# operations, and `:immediate` returns the global `ImmediateExecutor` object. -# @!macro deref_options - -# @!macro warn.edge -# @api Edge -# @note **Edge Features** are under active development and may change frequently. -# -# - Deprecations are not added before incompatible changes. -# - Edge version: _major_ is always 0, _minor_ bump means incompatible change, -# _patch_ bump means compatible change. -# - Edge features may also lack tests and documentation. -# - Features developed in `concurrent-ruby-edge` are expected to move -# to `concurrent-ruby` when finalised. - - -# {include:file:README.md} -module Concurrent -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/agent.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/agent.rb deleted file mode 100644 index 2d32926..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/agent.rb +++ /dev/null @@ -1,588 +0,0 @@ -require 'concurrent/configuration' -require 'concurrent/atomic/atomic_reference' -require 'concurrent/atomic/count_down_latch' -require 'concurrent/atomic/thread_local_var' -require 'concurrent/collection/copy_on_write_observer_set' -require 'concurrent/concern/observable' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # `Agent` is inspired by Clojure's [agent](http://clojure.org/agents) - # function. An agent is a shared, mutable variable providing independent, - # uncoordinated, *asynchronous* change of individual values. Best used when - # the value will undergo frequent, complex updates. Suitable when the result - # of an update does not need to be known immediately. `Agent` is (mostly) - # functionally equivalent to Clojure's agent, except where the runtime - # prevents parity. - # - # Agents are reactive, not autonomous - there is no imperative message loop - # and no blocking receive. The state of an Agent should be itself immutable - # and the `#value` of an Agent is always immediately available for reading by - # any thread without any messages, i.e. observation does not require - # cooperation or coordination. - # - # Agent action dispatches are made using the various `#send` methods. These - # methods always return immediately. At some point later, in another thread, - # the following will happen: - # - # 1. The given `action` will be applied to the state of the Agent and the - # `args`, if any were supplied. - # 2. The return value of `action` will be passed to the validator lambda, - # if one has been set on the Agent. - # 3. If the validator succeeds or if no validator was given, the return value - # of the given `action` will become the new `#value` of the Agent. See - # `#initialize` for details. - # 4. If any observers were added to the Agent, they will be notified. See - # `#add_observer` for details. - # 5. If during the `action` execution any other dispatches are made (directly - # or indirectly), they will be held until after the `#value` of the Agent - # has been changed. - # - # If any exceptions are thrown by an action function, no nested dispatches - # will occur, and the exception will be cached in the Agent itself. When an - # Agent has errors cached, any subsequent interactions will immediately throw - # an exception, until the agent's errors are cleared. Agent errors can be - # examined with `#error` and the agent restarted with `#restart`. - # - # The actions of all Agents get interleaved amongst threads in a thread pool. - # At any point in time, at most one action for each Agent is being executed. - # Actions dispatched to an agent from another single agent or thread will - # occur in the order they were sent, potentially interleaved with actions - # dispatched to the same agent from other sources. The `#send` method should - # be used for actions that are CPU limited, while the `#send_off` method is - # appropriate for actions that may block on IO. - # - # Unlike in Clojure, `Agent` cannot participate in `Concurrent::TVar` transactions. - # - # ## Example - # - # ``` - # def next_fibonacci(set = nil) - # return [0, 1] if set.nil? - # set + [set[-2..-1].reduce{|sum,x| sum + x }] - # end - # - # # create an agent with an initial value - # agent = Concurrent::Agent.new(next_fibonacci) - # - # # send a few update requests - # 5.times do - # agent.send{|set| next_fibonacci(set) } - # end - # - # # wait for them to complete - # agent.await - # - # # get the current value - # agent.value #=> [0, 1, 1, 2, 3, 5, 8] - # ``` - # - # ## Observation - # - # Agents support observers through the {Concurrent::Observable} mixin module. - # Notification of observers occurs every time an action dispatch returns and - # the new value is successfully validated. Observation will *not* occur if the - # action raises an exception, if validation fails, or when a {#restart} occurs. - # - # When notified the observer will receive three arguments: `time`, `old_value`, - # and `new_value`. The `time` argument is the time at which the value change - # occurred. The `old_value` is the value of the Agent when the action began - # processing. The `new_value` is the value to which the Agent was set when the - # action completed. Note that `old_value` and `new_value` may be the same. - # This is not an error. It simply means that the action returned the same - # value. - # - # ## Nested Actions - # - # It is possible for an Agent action to post further actions back to itself. - # The nested actions will be enqueued normally then processed *after* the - # outer action completes, in the order they were sent, possibly interleaved - # with action dispatches from other threads. Nested actions never deadlock - # with one another and a failure in a nested action will never affect the - # outer action. - # - # Nested actions can be called using the Agent reference from the enclosing - # scope or by passing the reference in as a "send" argument. Nested actions - # cannot be post using `self` from within the action block/proc/lambda; `self` - # in this context will not reference the Agent. The preferred method for - # dispatching nested actions is to pass the Agent as an argument. This allows - # Ruby to more effectively manage the closing scope. - # - # Prefer this: - # - # ``` - # agent = Concurrent::Agent.new(0) - # agent.send(agent) do |value, this| - # this.send {|v| v + 42 } - # 3.14 - # end - # agent.value #=> 45.14 - # ``` - # - # Over this: - # - # ``` - # agent = Concurrent::Agent.new(0) - # agent.send do |value| - # agent.send {|v| v + 42 } - # 3.14 - # end - # ``` - # - # @!macro agent_await_warning - # - # **NOTE** Never, *under any circumstances*, call any of the "await" methods - # ({#await}, {#await_for}, {#await_for!}, and {#wait}) from within an action - # block/proc/lambda. The call will block the Agent and will always fail. - # Calling either {#await} or {#wait} (with a timeout of `nil`) will - # hopelessly deadlock the Agent with no possibility of recovery. - # - # @!macro thread_safe_variable_comparison - # - # @see http://clojure.org/Agents Clojure Agents - # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State - class Agent < Synchronization::LockableObject - include Concern::Observable - - ERROR_MODES = [:continue, :fail].freeze - private_constant :ERROR_MODES - - AWAIT_FLAG = ::Object.new - private_constant :AWAIT_FLAG - - AWAIT_ACTION = ->(value, latch) { latch.count_down; AWAIT_FLAG } - private_constant :AWAIT_ACTION - - DEFAULT_ERROR_HANDLER = ->(agent, error) { nil } - private_constant :DEFAULT_ERROR_HANDLER - - DEFAULT_VALIDATOR = ->(value) { true } - private_constant :DEFAULT_VALIDATOR - - Job = Struct.new(:action, :args, :executor, :caller) - private_constant :Job - - # Raised during action processing or any other time in an Agent's lifecycle. - class Error < StandardError - def initialize(message = nil) - message ||= 'agent must be restarted before jobs can post' - super(message) - end - end - - # Raised when a new value obtained during action processing or at `#restart` - # fails validation. - class ValidationError < Error - def initialize(message = nil) - message ||= 'invalid value' - super(message) - end - end - - # The error mode this Agent is operating in. See {#initialize} for details. - attr_reader :error_mode - - # Create a new `Agent` with the given initial value and options. - # - # The `:validator` option must be `nil` or a side-effect free proc/lambda - # which takes one argument. On any intended value change the validator, if - # provided, will be called. If the new value is invalid the validator should - # return `false` or raise an error. - # - # The `:error_handler` option must be `nil` or a proc/lambda which takes two - # arguments. When an action raises an error or validation fails, either by - # returning false or raising an error, the error handler will be called. The - # arguments to the error handler will be a reference to the agent itself and - # the error object which was raised. - # - # The `:error_mode` may be either `:continue` (the default if an error - # handler is given) or `:fail` (the default if error handler nil or not - # given). - # - # If an action being run by the agent throws an error or doesn't pass - # validation the error handler, if present, will be called. After the - # handler executes if the error mode is `:continue` the Agent will continue - # as if neither the action that caused the error nor the error itself ever - # happened. - # - # If the mode is `:fail` the Agent will become {#failed?} and will stop - # accepting new action dispatches. Any previously queued actions will be - # held until {#restart} is called. The {#value} method will still work, - # returning the value of the Agent before the error. - # - # @param [Object] initial the initial value - # @param [Hash] opts the configuration options - # - # @option opts [Symbol] :error_mode either `:continue` or `:fail` - # @option opts [nil, Proc] :error_handler the (optional) error handler - # @option opts [nil, Proc] :validator the (optional) validation procedure - def initialize(initial, opts = {}) - super() - synchronize { ns_initialize(initial, opts) } - end - - # The current value (state) of the Agent, irrespective of any pending or - # in-progress actions. The value is always available and is non-blocking. - # - # @return [Object] the current value - def value - @current.value # TODO (pitr 12-Sep-2015): broken unsafe read? - end - - alias_method :deref, :value - - # When {#failed?} and {#error_mode} is `:fail`, returns the error object - # which caused the failure, else `nil`. When {#error_mode} is `:continue` - # will *always* return `nil`. - # - # @return [nil, Error] the error which caused the failure when {#failed?} - def error - @error.value - end - - alias_method :reason, :error - - # @!macro agent_send - # - # Dispatches an action to the Agent and returns immediately. Subsequently, - # in a thread from a thread pool, the {#value} will be set to the return - # value of the action. Action dispatches are only allowed when the Agent - # is not {#failed?}. - # - # The action must be a block/proc/lambda which takes 1 or more arguments. - # The first argument is the current {#value} of the Agent. Any arguments - # passed to the send method via the `args` parameter will be passed to the - # action as the remaining arguments. The action must return the new value - # of the Agent. - # - # * {#send} and {#send!} should be used for actions that are CPU limited - # * {#send_off}, {#send_off!}, and {#<<} are appropriate for actions that - # may block on IO - # * {#send_via} and {#send_via!} are used when a specific executor is to - # be used for the action - # - # @param [Array] args zero or more arguments to be passed to - # the action - # @param [Proc] action the action dispatch to be enqueued - # - # @yield [agent, value, *args] process the old value and return the new - # @yieldparam [Object] value the current {#value} of the Agent - # @yieldparam [Array] args zero or more arguments to pass to the - # action - # @yieldreturn [Object] the new value of the Agent - # - # @!macro send_return - # @return [Boolean] true if the action is successfully enqueued, false if - # the Agent is {#failed?} - def send(*args, &action) - enqueue_action_job(action, args, Concurrent.global_fast_executor) - end - - # @!macro agent_send - # - # @!macro send_bang_return_and_raise - # @return [Boolean] true if the action is successfully enqueued - # @raise [Concurrent::Agent::Error] if the Agent is {#failed?} - def send!(*args, &action) - raise Error.new unless send(*args, &action) - true - end - - # @!macro agent_send - # @!macro send_return - def send_off(*args, &action) - enqueue_action_job(action, args, Concurrent.global_io_executor) - end - - alias_method :post, :send_off - - # @!macro agent_send - # @!macro send_bang_return_and_raise - def send_off!(*args, &action) - raise Error.new unless send_off(*args, &action) - true - end - - # @!macro agent_send - # @!macro send_return - # @param [Concurrent::ExecutorService] executor the executor on which the - # action is to be dispatched - def send_via(executor, *args, &action) - enqueue_action_job(action, args, executor) - end - - # @!macro agent_send - # @!macro send_bang_return_and_raise - # @param [Concurrent::ExecutorService] executor the executor on which the - # action is to be dispatched - def send_via!(executor, *args, &action) - raise Error.new unless send_via(executor, *args, &action) - true - end - - # Dispatches an action to the Agent and returns immediately. Subsequently, - # in a thread from a thread pool, the {#value} will be set to the return - # value of the action. Appropriate for actions that may block on IO. - # - # @param [Proc] action the action dispatch to be enqueued - # @return [Concurrent::Agent] self - # @see #send_off - def <<(action) - send_off(&action) - self - end - - # Blocks the current thread (indefinitely!) until all actions dispatched - # thus far, from this thread or nested by the Agent, have occurred. Will - # block when {#failed?}. Will never return if a failed Agent is {#restart} - # with `:clear_actions` true. - # - # Returns a reference to `self` to support method chaining: - # - # ``` - # current_value = agent.await.value - # ``` - # - # @return [Boolean] self - # - # @!macro agent_await_warning - def await - wait(nil) - self - end - - # Blocks the current thread until all actions dispatched thus far, from this - # thread or nested by the Agent, have occurred, or the timeout (in seconds) - # has elapsed. - # - # @param [Float] timeout the maximum number of seconds to wait - # @return [Boolean] true if all actions complete before timeout else false - # - # @!macro agent_await_warning - def await_for(timeout) - wait(timeout.to_f) - end - - # Blocks the current thread until all actions dispatched thus far, from this - # thread or nested by the Agent, have occurred, or the timeout (in seconds) - # has elapsed. - # - # @param [Float] timeout the maximum number of seconds to wait - # @return [Boolean] true if all actions complete before timeout - # - # @raise [Concurrent::TimeoutError] when timout is reached - # - # @!macro agent_await_warning - def await_for!(timeout) - raise Concurrent::TimeoutError unless wait(timeout.to_f) - true - end - - # Blocks the current thread until all actions dispatched thus far, from this - # thread or nested by the Agent, have occurred, or the timeout (in seconds) - # has elapsed. Will block indefinitely when timeout is nil or not given. - # - # Provided mainly for consistency with other classes in this library. Prefer - # the various `await` methods instead. - # - # @param [Float] timeout the maximum number of seconds to wait - # @return [Boolean] true if all actions complete before timeout else false - # - # @!macro agent_await_warning - def wait(timeout = nil) - latch = Concurrent::CountDownLatch.new(1) - enqueue_await_job(latch) - latch.wait(timeout) - end - - # Is the Agent in a failed state? - # - # @see #restart - def failed? - !@error.value.nil? - end - - alias_method :stopped?, :failed? - - # When an Agent is {#failed?}, changes the Agent {#value} to `new_value` - # then un-fails the Agent so that action dispatches are allowed again. If - # the `:clear_actions` option is give and true, any actions queued on the - # Agent that were being held while it was failed will be discarded, - # otherwise those held actions will proceed. The `new_value` must pass the - # validator if any, or `restart` will raise an exception and the Agent will - # remain failed with its old {#value} and {#error}. Observers, if any, will - # not be notified of the new state. - # - # @param [Object] new_value the new value for the Agent once restarted - # @param [Hash] opts the configuration options - # @option opts [Symbol] :clear_actions true if all enqueued but unprocessed - # actions should be discarded on restart, else false (default: false) - # @return [Boolean] true - # - # @raise [Concurrent:AgentError] when not failed - def restart(new_value, opts = {}) - clear_actions = opts.fetch(:clear_actions, false) - synchronize do - raise Error.new('agent is not failed') unless failed? - raise ValidationError unless ns_validate(new_value) - @current.value = new_value - @error.value = nil - @queue.clear if clear_actions - ns_post_next_job unless @queue.empty? - end - true - end - - class << self - - # Blocks the current thread (indefinitely!) until all actions dispatched - # thus far to all the given Agents, from this thread or nested by the - # given Agents, have occurred. Will block when any of the agents are - # failed. Will never return if a failed Agent is restart with - # `:clear_actions` true. - # - # @param [Array] agents the Agents on which to wait - # @return [Boolean] true - # - # @!macro agent_await_warning - def await(*agents) - agents.each { |agent| agent.await } - true - end - - # Blocks the current thread until all actions dispatched thus far to all - # the given Agents, from this thread or nested by the given Agents, have - # occurred, or the timeout (in seconds) has elapsed. - # - # @param [Float] timeout the maximum number of seconds to wait - # @param [Array] agents the Agents on which to wait - # @return [Boolean] true if all actions complete before timeout else false - # - # @!macro agent_await_warning - def await_for(timeout, *agents) - end_at = Concurrent.monotonic_time + timeout.to_f - ok = agents.length.times do |i| - break false if (delay = end_at - Concurrent.monotonic_time) < 0 - break false unless agents[i].await_for(delay) - end - !!ok - end - - # Blocks the current thread until all actions dispatched thus far to all - # the given Agents, from this thread or nested by the given Agents, have - # occurred, or the timeout (in seconds) has elapsed. - # - # @param [Float] timeout the maximum number of seconds to wait - # @param [Array] agents the Agents on which to wait - # @return [Boolean] true if all actions complete before timeout - # - # @raise [Concurrent::TimeoutError] when timout is reached - # @!macro agent_await_warning - def await_for!(timeout, *agents) - raise Concurrent::TimeoutError unless await_for(timeout, *agents) - true - end - end - - private - - def ns_initialize(initial, opts) - @error_mode = opts[:error_mode] - @error_handler = opts[:error_handler] - - if @error_mode && !ERROR_MODES.include?(@error_mode) - raise ArgumentError.new('unrecognized error mode') - elsif @error_mode.nil? - @error_mode = @error_handler ? :continue : :fail - end - - @error_handler ||= DEFAULT_ERROR_HANDLER - @validator = opts.fetch(:validator, DEFAULT_VALIDATOR) - @current = Concurrent::AtomicReference.new(initial) - @error = Concurrent::AtomicReference.new(nil) - @caller = Concurrent::ThreadLocalVar.new(nil) - @queue = [] - - self.observers = Collection::CopyOnNotifyObserverSet.new - end - - def enqueue_action_job(action, args, executor) - raise ArgumentError.new('no action given') unless action - job = Job.new(action, args, executor, @caller.value || Thread.current.object_id) - synchronize { ns_enqueue_job(job) } - end - - def enqueue_await_job(latch) - synchronize do - if (index = ns_find_last_job_for_thread) - job = Job.new(AWAIT_ACTION, [latch], Concurrent.global_immediate_executor, - Thread.current.object_id) - ns_enqueue_job(job, index+1) - else - latch.count_down - true - end - end - end - - def ns_enqueue_job(job, index = nil) - # a non-nil index means this is an await job - return false if index.nil? && failed? - index ||= @queue.length - @queue.insert(index, job) - # if this is the only job, post to executor - ns_post_next_job if @queue.length == 1 - true - end - - def ns_post_next_job - @queue.first.executor.post { execute_next_job } - end - - def execute_next_job - job = synchronize { @queue.first } - old_value = @current.value - - @caller.value = job.caller # for nested actions - new_value = job.action.call(old_value, *job.args) - @caller.value = nil - - return if new_value == AWAIT_FLAG - - if ns_validate(new_value) - @current.value = new_value - observers.notify_observers(Time.now, old_value, new_value) - else - handle_error(ValidationError.new) - end - rescue => error - handle_error(error) - ensure - synchronize do - @queue.shift - unless failed? || @queue.empty? - ns_post_next_job - end - end - end - - def ns_validate(value) - @validator.call(value) - rescue - false - end - - def handle_error(error) - # stop new jobs from posting - @error.value = error if @error_mode == :fail - @error_handler.call(self, error) - rescue - # do nothing - end - - def ns_find_last_job_for_thread - @queue.rindex { |job| job.caller == Thread.current.object_id } - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/array.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/array.rb deleted file mode 100644 index c8761af..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/array.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/thread_safe/util' - -module Concurrent - - # @!macro concurrent_array - # - # A thread-safe subclass of Array. This version locks against the object - # itself for every method call, ensuring only one thread can be reading - # or writing at a time. This includes iteration methods like `#each`. - # - # @note `a += b` is **not** a **thread-safe** operation on - # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array` - # which is concatenation of `a` and `b`, then it writes the concatenation to `a`. - # The read and write are independent operations they do not form a single atomic - # operation therefore when two `+=` operations are executed concurrently updates - # may be lost. Use `#concat` instead. - # - # @see http://ruby-doc.org/core/Array.html Ruby standard library `Array` - - # @!macro internal_implementation_note - ArrayImplementation = case - when Concurrent.on_cruby? - # Array is not fully thread-safe on CRuby, see - # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 - # So we will need to add synchronization here - ::Array - - when Concurrent.on_jruby? - require 'jruby/synchronized' - - class JRubyArray < ::Array - include JRuby::Synchronized - end - JRubyArray - - when Concurrent.on_truffleruby? - require 'concurrent/thread_safe/util/data_structures' - - class TruffleRubyArray < ::Array - end - - ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyArray - TruffleRubyArray - - else - warn 'Possibly unsupported Ruby implementation' - ::Array - end - private_constant :ArrayImplementation - - # @!macro concurrent_array - class Array < ArrayImplementation - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/async.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/async.rb deleted file mode 100644 index f9f8adf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/async.rb +++ /dev/null @@ -1,449 +0,0 @@ -require 'concurrent/configuration' -require 'concurrent/ivar' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # A mixin module that provides simple asynchronous behavior to a class, - # turning it into a simple actor. Loosely based on Erlang's - # [gen_server](http://www.erlang.org/doc/man/gen_server.html), but without - # supervision or linking. - # - # A more feature-rich {Concurrent::Actor} is also available when the - # capabilities of `Async` are too limited. - # - # ```cucumber - # Feature: - # As a stateful, plain old Ruby class - # I want safe, asynchronous behavior - # So my long-running methods don't block the main thread - # ``` - # - # The `Async` module is a way to mix simple yet powerful asynchronous - # capabilities into any plain old Ruby object or class, turning each object - # into a simple Actor. Method calls are processed on a background thread. The - # caller is free to perform other actions while processing occurs in the - # background. - # - # Method calls to the asynchronous object are made via two proxy methods: - # `async` (alias `cast`) and `await` (alias `call`). These proxy methods post - # the method call to the object's background thread and return a "future" - # which will eventually contain the result of the method call. - # - # This behavior is loosely patterned after Erlang's `gen_server` behavior. - # When an Erlang module implements the `gen_server` behavior it becomes - # inherently asynchronous. The `start` or `start_link` function spawns a - # process (similar to a thread but much more lightweight and efficient) and - # returns the ID of the process. Using the process ID, other processes can - # send messages to the `gen_server` via the `cast` and `call` methods. Unlike - # Erlang's `gen_server`, however, `Async` classes do not support linking or - # supervision trees. - # - # ## Basic Usage - # - # When this module is mixed into a class, objects of the class become inherently - # asynchronous. Each object gets its own background thread on which to post - # asynchronous method calls. Asynchronous method calls are executed in the - # background one at a time in the order they are received. - # - # To create an asynchronous class, simply mix in the `Concurrent::Async` module: - # - # ``` - # class Hello - # include Concurrent::Async - # - # def hello(name) - # "Hello, #{name}!" - # end - # end - # ``` - # - # Mixing this module into a class provides each object two proxy methods: - # `async` and `await`. These methods are thread safe with respect to the - # enclosing object. The former proxy allows methods to be called - # asynchronously by posting to the object's internal thread. The latter proxy - # allows a method to be called synchronously but does so safely with respect - # to any pending asynchronous method calls and ensures proper ordering. Both - # methods return a {Concurrent::IVar} which can be inspected for the result - # of the proxied method call. Calling a method with `async` will return a - # `:pending` `IVar` whereas `await` will return a `:complete` `IVar`. - # - # ``` - # class Echo - # include Concurrent::Async - # - # def echo(msg) - # print "#{msg}\n" - # end - # end - # - # horn = Echo.new - # horn.echo('zero') # synchronous, not thread-safe - # # returns the actual return value of the method - # - # horn.async.echo('one') # asynchronous, non-blocking, thread-safe - # # returns an IVar in the :pending state - # - # horn.await.echo('two') # synchronous, blocking, thread-safe - # # returns an IVar in the :complete state - # ``` - # - # ## Let It Fail - # - # The `async` and `await` proxy methods have built-in error protection based - # on Erlang's famous "let it fail" philosophy. Instance methods should not be - # programmed defensively. When an exception is raised by a delegated method - # the proxy will rescue the exception, expose it to the caller as the `reason` - # attribute of the returned future, then process the next method call. - # - # ## Calling Methods Internally - # - # External method calls should *always* use the `async` and `await` proxy - # methods. When one method calls another method, the `async` proxy should - # rarely be used and the `await` proxy should *never* be used. - # - # When an object calls one of its own methods using the `await` proxy the - # second call will be enqueued *behind* the currently running method call. - # Any attempt to wait on the result will fail as the second call will never - # run until after the current call completes. - # - # Calling a method using the `await` proxy from within a method that was - # itself called using `async` or `await` will irreversibly deadlock the - # object. Do *not* do this, ever. - # - # ## Instance Variables and Attribute Accessors - # - # Instance variables do not need to be thread-safe so long as they are private. - # Asynchronous method calls are processed in the order they are received and - # are processed one at a time. Therefore private instance variables can only - # be accessed by one thread at a time. This is inherently thread-safe. - # - # When using private instance variables within asynchronous methods, the best - # practice is to read the instance variable into a local variable at the start - # of the method then update the instance variable at the *end* of the method. - # This way, should an exception be raised during method execution the internal - # state of the object will not have been changed. - # - # ### Reader Attributes - # - # The use of `attr_reader` is discouraged. Internal state exposed externally, - # when necessary, should be done through accessor methods. The instance - # variables exposed by these methods *must* be thread-safe, or they must be - # called using the `async` and `await` proxy methods. These two approaches are - # subtly different. - # - # When internal state is accessed via the `async` and `await` proxy methods, - # the returned value represents the object's state *at the time the call is - # processed*, which may *not* be the state of the object at the time the call - # is made. - # - # To get the state *at the current* time, irrespective of an enqueued method - # calls, a reader method must be called directly. This is inherently unsafe - # unless the instance variable is itself thread-safe, preferably using one - # of the thread-safe classes within this library. Because the thread-safe - # classes within this library are internally-locking or non-locking, they can - # be safely used from within asynchronous methods without causing deadlocks. - # - # Generally speaking, the best practice is to *not* expose internal state via - # reader methods. The best practice is to simply use the method's return value. - # - # ### Writer Attributes - # - # Writer attributes should never be used with asynchronous classes. Changing - # the state externally, even when done in the thread-safe way, is not logically - # consistent. Changes to state need to be timed with respect to all asynchronous - # method calls which my be in-process or enqueued. The only safe practice is to - # pass all necessary data to each method as arguments and let the method update - # the internal state as necessary. - # - # ## Class Constants, Variables, and Methods - # - # ### Class Constants - # - # Class constants do not need to be thread-safe. Since they are read-only and - # immutable they may be safely read both externally and from within - # asynchronous methods. - # - # ### Class Variables - # - # Class variables should be avoided. Class variables represent shared state. - # Shared state is anathema to concurrency. Should there be a need to share - # state using class variables they *must* be thread-safe, preferably - # using the thread-safe classes within this library. When updating class - # variables, never assign a new value/object to the variable itself. Assignment - # is not thread-safe in Ruby. Instead, use the thread-safe update functions - # of the variable itself to change the value. - # - # The best practice is to *never* use class variables with `Async` classes. - # - # ### Class Methods - # - # Class methods which are pure functions are safe. Class methods which modify - # class variables should be avoided, for all the reasons listed above. - # - # ## An Important Note About Thread Safe Guarantees - # - # > Thread safe guarantees can only be made when asynchronous method calls - # > are not mixed with direct method calls. Use only direct method calls - # > when the object is used exclusively on a single thread. Use only - # > `async` and `await` when the object is shared between threads. Once you - # > call a method using `async` or `await`, you should no longer call methods - # > directly on the object. Use `async` and `await` exclusively from then on. - # - # @example - # - # class Echo - # include Concurrent::Async - # - # def echo(msg) - # print "#{msg}\n" - # end - # end - # - # horn = Echo.new - # horn.echo('zero') # synchronous, not thread-safe - # # returns the actual return value of the method - # - # horn.async.echo('one') # asynchronous, non-blocking, thread-safe - # # returns an IVar in the :pending state - # - # horn.await.echo('two') # synchronous, blocking, thread-safe - # # returns an IVar in the :complete state - # - # @see Concurrent::Actor - # @see https://en.wikipedia.org/wiki/Actor_model "Actor Model" at Wikipedia - # @see http://www.erlang.org/doc/man/gen_server.html Erlang gen_server - # @see http://c2.com/cgi/wiki?LetItCrash "Let It Crash" at http://c2.com/ - module Async - - # @!method self.new(*args, &block) - # - # Instanciate a new object and ensure proper initialization of the - # synchronization mechanisms. - # - # @param [Array] args Zero or more arguments to be passed to the - # object's initializer. - # @param [Proc] block Optional block to pass to the object's initializer. - # @return [Object] A properly initialized object of the asynchronous class. - - # Check for the presence of a method on an object and determine if a given - # set of arguments matches the required arity. - # - # @param [Object] obj the object to check against - # @param [Symbol] method the method to check the object for - # @param [Array] args zero or more arguments for the arity check - # - # @raise [NameError] the object does not respond to `method` method - # @raise [ArgumentError] the given `args` do not match the arity of `method` - # - # @note This check is imperfect because of the way Ruby reports the arity of - # methods with a variable number of arguments. It is possible to determine - # if too few arguments are given but impossible to determine if too many - # arguments are given. This check may also fail to recognize dynamic behavior - # of the object, such as methods simulated with `method_missing`. - # - # @see http://www.ruby-doc.org/core-2.1.1/Method.html#method-i-arity Method#arity - # @see http://ruby-doc.org/core-2.1.0/Object.html#method-i-respond_to-3F Object#respond_to? - # @see http://www.ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing BasicObject#method_missing - # - # @!visibility private - def self.validate_argc(obj, method, *args) - argc = args.length - arity = obj.method(method).arity - - if arity >= 0 && argc != arity - raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity})") - elsif arity < 0 && (arity = (arity + 1).abs) > argc - raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity}..*)") - end - end - - # @!visibility private - def self.included(base) - base.singleton_class.send(:alias_method, :original_new, :new) - base.extend(ClassMethods) - super(base) - end - - # @!visibility private - module ClassMethods - def new(*args, &block) - obj = original_new(*args, &block) - obj.send(:init_synchronization) - obj - end - ruby2_keywords :new if respond_to?(:ruby2_keywords, true) - end - private_constant :ClassMethods - - # Delegates asynchronous, thread-safe method calls to the wrapped object. - # - # @!visibility private - class AsyncDelegator < Synchronization::LockableObject - safe_initialization! - - # Create a new delegator object wrapping the given delegate. - # - # @param [Object] delegate the object to wrap and delegate method calls to - def initialize(delegate) - super() - @delegate = delegate - @queue = [] - @executor = Concurrent.global_io_executor - @ruby_pid = $$ - end - - # Delegates method calls to the wrapped object. - # - # @param [Symbol] method the method being called - # @param [Array] args zero or more arguments to the method - # - # @return [IVar] the result of the method call - # - # @raise [NameError] the object does not respond to `method` method - # @raise [ArgumentError] the given `args` do not match the arity of `method` - def method_missing(method, *args, &block) - super unless @delegate.respond_to?(method) - Async::validate_argc(@delegate, method, *args) - - ivar = Concurrent::IVar.new - synchronize do - reset_if_forked - @queue.push [ivar, method, args, block] - @executor.post { perform } if @queue.length == 1 - end - - ivar - end - - # Check whether the method is responsive - # - # @param [Symbol] method the method being called - def respond_to_missing?(method, include_private = false) - @delegate.respond_to?(method) || super - end - - # Perform all enqueued tasks. - # - # This method must be called from within the executor. It must not be - # called while already running. It will loop until the queue is empty. - def perform - loop do - ivar, method, args, block = synchronize { @queue.first } - break unless ivar # queue is empty - - begin - ivar.set(@delegate.send(method, *args, &block)) - rescue => error - ivar.fail(error) - end - - synchronize do - @queue.shift - return if @queue.empty? - end - end - end - - def reset_if_forked - if $$ != @ruby_pid - @queue.clear - @ruby_pid = $$ - end - end - end - private_constant :AsyncDelegator - - # Delegates synchronous, thread-safe method calls to the wrapped object. - # - # @!visibility private - class AwaitDelegator - - # Create a new delegator object wrapping the given delegate. - # - # @param [AsyncDelegator] delegate the object to wrap and delegate method calls to - def initialize(delegate) - @delegate = delegate - end - - # Delegates method calls to the wrapped object. - # - # @param [Symbol] method the method being called - # @param [Array] args zero or more arguments to the method - # - # @return [IVar] the result of the method call - # - # @raise [NameError] the object does not respond to `method` method - # @raise [ArgumentError] the given `args` do not match the arity of `method` - def method_missing(method, *args, &block) - ivar = @delegate.send(method, *args, &block) - ivar.wait - ivar - end - - # Check whether the method is responsive - # - # @param [Symbol] method the method being called - def respond_to_missing?(method, include_private = false) - @delegate.respond_to?(method) || super - end - end - private_constant :AwaitDelegator - - # Causes the chained method call to be performed asynchronously on the - # object's thread. The delegated method will return a future in the - # `:pending` state and the method call will have been scheduled on the - # object's thread. The final disposition of the method call can be obtained - # by inspecting the returned future. - # - # @!macro async_thread_safety_warning - # @note The method call is guaranteed to be thread safe with respect to - # all other method calls against the same object that are called with - # either `async` or `await`. The mutable nature of Ruby references - # (and object orientation in general) prevent any other thread safety - # guarantees. Do NOT mix direct method calls with delegated method calls. - # Use *only* delegated method calls when sharing the object between threads. - # - # @return [Concurrent::IVar] the pending result of the asynchronous operation - # - # @raise [NameError] the object does not respond to the requested method - # @raise [ArgumentError] the given `args` do not match the arity of - # the requested method - def async - @__async_delegator__ - end - alias_method :cast, :async - - # Causes the chained method call to be performed synchronously on the - # current thread. The delegated will return a future in either the - # `:fulfilled` or `:rejected` state and the delegated method will have - # completed. The final disposition of the delegated method can be obtained - # by inspecting the returned future. - # - # @!macro async_thread_safety_warning - # - # @return [Concurrent::IVar] the completed result of the synchronous operation - # - # @raise [NameError] the object does not respond to the requested method - # @raise [ArgumentError] the given `args` do not match the arity of the - # requested method - def await - @__await_delegator__ - end - alias_method :call, :await - - # Initialize the internal serializer and other stnchronization mechanisms. - # - # @note This method *must* be called immediately upon object construction. - # This is the only way thread-safe initialization can be guaranteed. - # - # @!visibility private - def init_synchronization - return self if defined?(@__async_initialized__) && @__async_initialized__ - @__async_initialized__ = true - @__async_delegator__ = AsyncDelegator.new(self) - @__await_delegator__ = AwaitDelegator.new(@__async_delegator__) - self - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atom.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atom.rb deleted file mode 100644 index 1074006..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atom.rb +++ /dev/null @@ -1,222 +0,0 @@ -require 'concurrent/atomic/atomic_reference' -require 'concurrent/collection/copy_on_notify_observer_set' -require 'concurrent/concern/observable' -require 'concurrent/synchronization/object' - -# @!macro thread_safe_variable_comparison -# -# ## Thread-safe Variable Classes -# -# Each of the thread-safe variable classes is designed to solve a different -# problem. In general: -# -# * *{Concurrent::Agent}:* Shared, mutable variable providing independent, -# uncoordinated, *asynchronous* change of individual values. Best used when -# the value will undergo frequent, complex updates. Suitable when the result -# of an update does not need to be known immediately. -# * *{Concurrent::Atom}:* Shared, mutable variable providing independent, -# uncoordinated, *synchronous* change of individual values. Best used when -# the value will undergo frequent reads but only occasional, though complex, -# updates. Suitable when the result of an update must be known immediately. -# * *{Concurrent::AtomicReference}:* A simple object reference that can be updated -# atomically. Updates are synchronous but fast. Best used when updates a -# simple set operations. Not suitable when updates are complex. -# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar -# but optimized for the given data type. -# * *{Concurrent::Exchanger}:* Shared, stateless synchronization point. Used -# when two or more threads need to exchange data. The threads will pair then -# block on each other until the exchange is complete. -# * *{Concurrent::MVar}:* Shared synchronization point. Used when one thread -# must give a value to another, which must take the value. The threads will -# block on each other until the exchange is complete. -# * *{Concurrent::ThreadLocalVar}:* Shared, mutable, isolated variable which -# holds a different value for each thread which has access. Often used as -# an instance variable in objects which must maintain different state -# for different threads. -# * *{Concurrent::TVar}:* Shared, mutable variables which provide -# *coordinated*, *synchronous*, change of *many* stated. Used when multiple -# value must change together, in an all-or-nothing transaction. - - -module Concurrent - - # Atoms provide a way to manage shared, synchronous, independent state. - # - # An atom is initialized with an initial value and an optional validation - # proc. At any time the value of the atom can be synchronously and safely - # changed. If a validator is given at construction then any new value - # will be checked against the validator and will be rejected if the - # validator returns false or raises an exception. - # - # There are two ways to change the value of an atom: {#compare_and_set} and - # {#swap}. The former will set the new value if and only if it validates and - # the current value matches the new value. The latter will atomically set the - # new value to the result of running the given block if and only if that - # value validates. - # - # ## Example - # - # ``` - # def next_fibonacci(set = nil) - # return [0, 1] if set.nil? - # set + [set[-2..-1].reduce{|sum,x| sum + x }] - # end - # - # # create an atom with an initial value - # atom = Concurrent::Atom.new(next_fibonacci) - # - # # send a few update requests - # 5.times do - # atom.swap{|set| next_fibonacci(set) } - # end - # - # # get the current value - # atom.value #=> [0, 1, 1, 2, 3, 5, 8] - # ``` - # - # ## Observation - # - # Atoms support observers through the {Concurrent::Observable} mixin module. - # Notification of observers occurs every time the value of the Atom changes. - # When notified the observer will receive three arguments: `time`, `old_value`, - # and `new_value`. The `time` argument is the time at which the value change - # occurred. The `old_value` is the value of the Atom when the change began - # The `new_value` is the value to which the Atom was set when the change - # completed. Note that `old_value` and `new_value` may be the same. This is - # not an error. It simply means that the change operation returned the same - # value. - # - # Unlike in Clojure, `Atom` cannot participate in {Concurrent::TVar} transactions. - # - # @!macro thread_safe_variable_comparison - # - # @see http://clojure.org/atoms Clojure Atoms - # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State - class Atom < Synchronization::Object - include Concern::Observable - - safe_initialization! - attr_atomic(:value) - private :value=, :swap_value, :compare_and_set_value, :update_value - public :value - alias_method :deref, :value - - # @!method value - # The current value of the atom. - # - # @return [Object] The current value. - - # Create a new atom with the given initial value. - # - # @param [Object] value The initial value - # @param [Hash] opts The options used to configure the atom - # @option opts [Proc] :validator (nil) Optional proc used to validate new - # values. It must accept one and only one argument which will be the - # intended new value. The validator will return true if the new value - # is acceptable else return false (preferrably) or raise an exception. - # - # @!macro deref_options - # - # @raise [ArgumentError] if the validator is not a `Proc` (when given) - def initialize(value, opts = {}) - super() - @Validator = opts.fetch(:validator, -> v { true }) - self.observers = Collection::CopyOnNotifyObserverSet.new - self.value = value - end - - # Atomically swaps the value of atom using the given block. The current - # value will be passed to the block, as will any arguments passed as - # arguments to the function. The new value will be validated against the - # (optional) validator proc given at construction. If validation fails the - # value will not be changed. - # - # Internally, {#swap} reads the current value, applies the block to it, and - # attempts to compare-and-set it in. Since another thread may have changed - # the value in the intervening time, it may have to retry, and does so in a - # spin loop. The net effect is that the value will always be the result of - # the application of the supplied block to a current value, atomically. - # However, because the block might be called multiple times, it must be free - # of side effects. - # - # @note The given block may be called multiple times, and thus should be free - # of side effects. - # - # @param [Object] args Zero or more arguments passed to the block. - # - # @yield [value, args] Calculates a new value for the atom based on the - # current value and any supplied arguments. - # @yieldparam value [Object] The current value of the atom. - # @yieldparam args [Object] All arguments passed to the function, in order. - # @yieldreturn [Object] The intended new value of the atom. - # - # @return [Object] The final value of the atom after all operations and - # validations are complete. - # - # @raise [ArgumentError] When no block is given. - def swap(*args) - raise ArgumentError.new('no block given') unless block_given? - - loop do - old_value = value - new_value = yield(old_value, *args) - begin - break old_value unless valid?(new_value) - break new_value if compare_and_set(old_value, new_value) - rescue - break old_value - end - end - end - - # Atomically sets the value of atom to the new value if and only if the - # current value of the atom is identical to the old value and the new - # value successfully validates against the (optional) validator given - # at construction. - # - # @param [Object] old_value The expected current value. - # @param [Object] new_value The intended new value. - # - # @return [Boolean] True if the value is changed else false. - def compare_and_set(old_value, new_value) - if valid?(new_value) && compare_and_set_value(old_value, new_value) - observers.notify_observers(Time.now, old_value, new_value) - true - else - false - end - end - - # Atomically sets the value of atom to the new value without regard for the - # current value so long as the new value successfully validates against the - # (optional) validator given at construction. - # - # @param [Object] new_value The intended new value. - # - # @return [Object] The final value of the atom after all operations and - # validations are complete. - def reset(new_value) - old_value = value - if valid?(new_value) - self.value = new_value - observers.notify_observers(Time.now, old_value, new_value) - new_value - else - old_value - end - end - - private - - # Is the new value valid? - # - # @param [Object] new_value The intended new value. - # @return [Boolean] false if the validator function returns false or raises - # an exception else true - def valid?(new_value) - @Validator.call(new_value) - rescue - false - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb deleted file mode 100644 index f775691..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +++ /dev/null @@ -1,127 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -require 'concurrent/atomic/mutex_atomic_boolean' - -module Concurrent - - ################################################################### - - # @!macro atomic_boolean_method_initialize - # - # Creates a new `AtomicBoolean` with the given initial value. - # - # @param [Boolean] initial the initial value - - # @!macro atomic_boolean_method_value_get - # - # Retrieves the current `Boolean` value. - # - # @return [Boolean] the current value - - # @!macro atomic_boolean_method_value_set - # - # Explicitly sets the value. - # - # @param [Boolean] value the new value to be set - # - # @return [Boolean] the current value - - # @!macro atomic_boolean_method_true_question - # - # Is the current value `true` - # - # @return [Boolean] true if the current value is `true`, else false - - # @!macro atomic_boolean_method_false_question - # - # Is the current value `false` - # - # @return [Boolean] true if the current value is `false`, else false - - # @!macro atomic_boolean_method_make_true - # - # Explicitly sets the value to true. - # - # @return [Boolean] true if value has changed, otherwise false - - # @!macro atomic_boolean_method_make_false - # - # Explicitly sets the value to false. - # - # @return [Boolean] true if value has changed, otherwise false - - ################################################################### - - # @!macro atomic_boolean_public_api - # - # @!method initialize(initial = false) - # @!macro atomic_boolean_method_initialize - # - # @!method value - # @!macro atomic_boolean_method_value_get - # - # @!method value=(value) - # @!macro atomic_boolean_method_value_set - # - # @!method true? - # @!macro atomic_boolean_method_true_question - # - # @!method false? - # @!macro atomic_boolean_method_false_question - # - # @!method make_true - # @!macro atomic_boolean_method_make_true - # - # @!method make_false - # @!macro atomic_boolean_method_make_false - - ################################################################### - - # @!visibility private - # @!macro internal_implementation_note - AtomicBooleanImplementation = case - when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? - CAtomicBoolean - when Concurrent.on_jruby? - JavaAtomicBoolean - else - MutexAtomicBoolean - end - private_constant :AtomicBooleanImplementation - - # @!macro atomic_boolean - # - # A boolean value that can be updated atomically. Reads and writes to an atomic - # boolean and thread-safe and guaranteed to succeed. Reads and writes may block - # briefly but no explicit locking is required. - # - # @!macro thread_safe_variable_comparison - # - # Performance: - # - # ``` - # Testing with ruby 2.1.2 - # Testing with Concurrent::MutexAtomicBoolean... - # 2.790000 0.000000 2.790000 ( 2.791454) - # Testing with Concurrent::CAtomicBoolean... - # 0.740000 0.000000 0.740000 ( 0.740206) - # - # Testing with jruby 1.9.3 - # Testing with Concurrent::MutexAtomicBoolean... - # 5.240000 2.520000 7.760000 ( 3.683000) - # Testing with Concurrent::JavaAtomicBoolean... - # 3.340000 0.010000 3.350000 ( 0.855000) - # ``` - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean - # - # @!macro atomic_boolean_public_api - class AtomicBoolean < AtomicBooleanImplementation - # @return [String] Short string representation. - def to_s - format '%s value:%s>', super[0..-2], value - end - - alias_method :inspect, :to_s - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb deleted file mode 100644 index 26cd05d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +++ /dev/null @@ -1,144 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -require 'concurrent/atomic/mutex_atomic_fixnum' - -module Concurrent - - ################################################################### - - # @!macro atomic_fixnum_method_initialize - # - # Creates a new `AtomicFixnum` with the given initial value. - # - # @param [Fixnum] initial the initial value - # @raise [ArgumentError] if the initial value is not a `Fixnum` - - # @!macro atomic_fixnum_method_value_get - # - # Retrieves the current `Fixnum` value. - # - # @return [Fixnum] the current value - - # @!macro atomic_fixnum_method_value_set - # - # Explicitly sets the value. - # - # @param [Fixnum] value the new value to be set - # - # @return [Fixnum] the current value - # - # @raise [ArgumentError] if the new value is not a `Fixnum` - - # @!macro atomic_fixnum_method_increment - # - # Increases the current value by the given amount (defaults to 1). - # - # @param [Fixnum] delta the amount by which to increase the current value - # - # @return [Fixnum] the current value after incrementation - - # @!macro atomic_fixnum_method_decrement - # - # Decreases the current value by the given amount (defaults to 1). - # - # @param [Fixnum] delta the amount by which to decrease the current value - # - # @return [Fixnum] the current value after decrementation - - # @!macro atomic_fixnum_method_compare_and_set - # - # Atomically sets the value to the given updated value if the current - # value == the expected value. - # - # @param [Fixnum] expect the expected value - # @param [Fixnum] update the new value - # - # @return [Boolean] true if the value was updated else false - - # @!macro atomic_fixnum_method_update - # - # Pass the current value to the given block, replacing it - # with the block's result. May retry if the value changes - # during the block's execution. - # - # @yield [Object] Calculate a new value for the atomic reference using - # given (old) value - # @yieldparam [Object] old_value the starting value of the atomic reference - # - # @return [Object] the new value - - ################################################################### - - # @!macro atomic_fixnum_public_api - # - # @!method initialize(initial = 0) - # @!macro atomic_fixnum_method_initialize - # - # @!method value - # @!macro atomic_fixnum_method_value_get - # - # @!method value=(value) - # @!macro atomic_fixnum_method_value_set - # - # @!method increment(delta = 1) - # @!macro atomic_fixnum_method_increment - # - # @!method decrement(delta = 1) - # @!macro atomic_fixnum_method_decrement - # - # @!method compare_and_set(expect, update) - # @!macro atomic_fixnum_method_compare_and_set - # - # @!method update - # @!macro atomic_fixnum_method_update - - ################################################################### - - # @!visibility private - # @!macro internal_implementation_note - AtomicFixnumImplementation = case - when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? - CAtomicFixnum - when Concurrent.on_jruby? - JavaAtomicFixnum - else - MutexAtomicFixnum - end - private_constant :AtomicFixnumImplementation - - # @!macro atomic_fixnum - # - # A numeric value that can be updated atomically. Reads and writes to an atomic - # fixnum and thread-safe and guaranteed to succeed. Reads and writes may block - # briefly but no explicit locking is required. - # - # @!macro thread_safe_variable_comparison - # - # Performance: - # - # ``` - # Testing with ruby 2.1.2 - # Testing with Concurrent::MutexAtomicFixnum... - # 3.130000 0.000000 3.130000 ( 3.136505) - # Testing with Concurrent::CAtomicFixnum... - # 0.790000 0.000000 0.790000 ( 0.785550) - # - # Testing with jruby 1.9.3 - # Testing with Concurrent::MutexAtomicFixnum... - # 5.460000 2.460000 7.920000 ( 3.715000) - # Testing with Concurrent::JavaAtomicFixnum... - # 4.520000 0.030000 4.550000 ( 1.187000) - # ``` - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong - # - # @!macro atomic_fixnum_public_api - class AtomicFixnum < AtomicFixnumImplementation - # @return [String] Short string representation. - def to_s - format '%s value:%s>', super[0..-2], value - end - - alias_method :inspect, :to_s - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb deleted file mode 100644 index e16be65..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +++ /dev/null @@ -1,167 +0,0 @@ -require 'concurrent/errors' -require 'concurrent/synchronization/object' - -module Concurrent - # An atomic reference which maintains an object reference along with a mark bit - # that can be updated atomically. - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html - # java.util.concurrent.atomic.AtomicMarkableReference - class AtomicMarkableReference < ::Concurrent::Synchronization::Object - - attr_atomic(:reference) - private :reference, :reference=, :swap_reference, :compare_and_set_reference, :update_reference - - def initialize(value = nil, mark = false) - super() - self.reference = immutable_array(value, mark) - end - - # Atomically sets the value and mark to the given updated value and - # mark given both: - # - the current value == the expected value && - # - the current mark == the expected mark - # - # @param [Object] expected_val the expected value - # @param [Object] new_val the new value - # @param [Boolean] expected_mark the expected mark - # @param [Boolean] new_mark the new mark - # - # @return [Boolean] `true` if successful. A `false` return indicates - # that the actual value was not equal to the expected value or the - # actual mark was not equal to the expected mark - def compare_and_set(expected_val, new_val, expected_mark, new_mark) - # Memoize a valid reference to the current AtomicReference for - # later comparison. - current = reference - curr_val, curr_mark = current - - # Ensure that that the expected marks match. - return false unless expected_mark == curr_mark - - if expected_val.is_a? Numeric - # If the object is a numeric, we need to ensure we are comparing - # the numerical values - return false unless expected_val == curr_val - else - # Otherwise, we need to ensure we are comparing the object identity. - # Theoretically, this could be incorrect if a user monkey-patched - # `Object#equal?`, but they should know that they are playing with - # fire at that point. - return false unless expected_val.equal? curr_val - end - - prospect = immutable_array(new_val, new_mark) - - compare_and_set_reference current, prospect - end - - alias_method :compare_and_swap, :compare_and_set - - # Gets the current reference and marked values. - # - # @return [Array] the current reference and marked values - def get - reference - end - - # Gets the current value of the reference - # - # @return [Object] the current value of the reference - def value - reference[0] - end - - # Gets the current marked value - # - # @return [Boolean] the current marked value - def mark - reference[1] - end - - alias_method :marked?, :mark - - # _Unconditionally_ sets to the given value of both the reference and - # the mark. - # - # @param [Object] new_val the new value - # @param [Boolean] new_mark the new mark - # - # @return [Array] both the new value and the new mark - def set(new_val, new_mark) - self.reference = immutable_array(new_val, new_mark) - end - - # Pass the current value and marked state to the given block, replacing it - # with the block's results. May retry if the value changes during the - # block's execution. - # - # @yield [Object] Calculate a new value and marked state for the atomic - # reference using given (old) value and (old) marked - # @yieldparam [Object] old_val the starting value of the atomic reference - # @yieldparam [Boolean] old_mark the starting state of marked - # - # @return [Array] the new value and new mark - def update - loop do - old_val, old_mark = reference - new_val, new_mark = yield old_val, old_mark - - if compare_and_set old_val, new_val, old_mark, new_mark - return immutable_array(new_val, new_mark) - end - end - end - - # Pass the current value to the given block, replacing it - # with the block's result. Raise an exception if the update - # fails. - # - # @yield [Object] Calculate a new value and marked state for the atomic - # reference using given (old) value and (old) marked - # @yieldparam [Object] old_val the starting value of the atomic reference - # @yieldparam [Boolean] old_mark the starting state of marked - # - # @return [Array] the new value and marked state - # - # @raise [Concurrent::ConcurrentUpdateError] if the update fails - def try_update! - old_val, old_mark = reference - new_val, new_mark = yield old_val, old_mark - - unless compare_and_set old_val, new_val, old_mark, new_mark - fail ::Concurrent::ConcurrentUpdateError, - 'AtomicMarkableReference: Update failed due to race condition.', - 'Note: If you would like to guarantee an update, please use ' + - 'the `AtomicMarkableReference#update` method.' - end - - immutable_array(new_val, new_mark) - end - - # Pass the current value to the given block, replacing it with the - # block's result. Simply return nil if update fails. - # - # @yield [Object] Calculate a new value and marked state for the atomic - # reference using given (old) value and (old) marked - # @yieldparam [Object] old_val the starting value of the atomic reference - # @yieldparam [Boolean] old_mark the starting state of marked - # - # @return [Array] the new value and marked state, or nil if - # the update failed - def try_update - old_val, old_mark = reference - new_val, new_mark = yield old_val, old_mark - - return unless compare_and_set old_val, new_val, old_mark, new_mark - - immutable_array(new_val, new_mark) - end - - private - - def immutable_array(*args) - args.freeze - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb deleted file mode 100644 index bb5fb77..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +++ /dev/null @@ -1,135 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -require 'concurrent/atomic_reference/atomic_direct_update' -require 'concurrent/atomic_reference/numeric_cas_wrapper' -require 'concurrent/atomic_reference/mutex_atomic' - -# Shim for TruffleRuby::AtomicReference -if Concurrent.on_truffleruby? && !defined?(TruffleRuby::AtomicReference) - # @!visibility private - module TruffleRuby - AtomicReference = Truffle::AtomicReference - end -end - -module Concurrent - - # @!macro internal_implementation_note - AtomicReferenceImplementation = case - when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? - # @!visibility private - # @!macro internal_implementation_note - class CAtomicReference - include AtomicDirectUpdate - include AtomicNumericCompareAndSetWrapper - alias_method :compare_and_swap, :compare_and_set - end - CAtomicReference - when Concurrent.on_jruby? - # @!visibility private - # @!macro internal_implementation_note - class JavaAtomicReference - include AtomicDirectUpdate - end - JavaAtomicReference - when Concurrent.on_truffleruby? - class TruffleRubyAtomicReference < TruffleRuby::AtomicReference - include AtomicDirectUpdate - alias_method :value, :get - alias_method :value=, :set - alias_method :compare_and_swap, :compare_and_set - alias_method :swap, :get_and_set - end - TruffleRubyAtomicReference - else - MutexAtomicReference - end - private_constant :AtomicReferenceImplementation - - # An object reference that may be updated atomically. All read and write - # operations have java volatile semantic. - # - # @!macro thread_safe_variable_comparison - # - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html - # - # @!method initialize(value = nil) - # @!macro atomic_reference_method_initialize - # @param [Object] value The initial value. - # - # @!method get - # @!macro atomic_reference_method_get - # Gets the current value. - # @return [Object] the current value - # - # @!method set(new_value) - # @!macro atomic_reference_method_set - # Sets to the given value. - # @param [Object] new_value the new value - # @return [Object] the new value - # - # @!method get_and_set(new_value) - # @!macro atomic_reference_method_get_and_set - # Atomically sets to the given value and returns the old value. - # @param [Object] new_value the new value - # @return [Object] the old value - # - # @!method compare_and_set(old_value, new_value) - # @!macro atomic_reference_method_compare_and_set - # - # Atomically sets the value to the given updated value if - # the current value == the expected value. - # - # @param [Object] old_value the expected value - # @param [Object] new_value the new value - # - # @return [Boolean] `true` if successful. A `false` return indicates - # that the actual value was not equal to the expected value. - # - # @!method update - # Pass the current value to the given block, replacing it - # with the block's result. May retry if the value changes - # during the block's execution. - # - # @yield [Object] Calculate a new value for the atomic reference using - # given (old) value - # @yieldparam [Object] old_value the starting value of the atomic reference - # @return [Object] the new value - # - # @!method try_update - # Pass the current value to the given block, replacing it - # with the block's result. Return nil if the update fails. - # - # @yield [Object] Calculate a new value for the atomic reference using - # given (old) value - # @yieldparam [Object] old_value the starting value of the atomic reference - # @note This method was altered to avoid raising an exception by default. - # Instead, this method now returns `nil` in case of failure. For more info, - # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 - # @return [Object] the new value, or nil if update failed - # - # @!method try_update! - # Pass the current value to the given block, replacing it - # with the block's result. Raise an exception if the update - # fails. - # - # @yield [Object] Calculate a new value for the atomic reference using - # given (old) value - # @yieldparam [Object] old_value the starting value of the atomic reference - # @note This behavior mimics the behavior of the original - # `AtomicReference#try_update` API. The reason this was changed was to - # avoid raising exceptions (which are inherently slow) by default. For more - # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 - # @return [Object] the new value - # @raise [Concurrent::ConcurrentUpdateError] if the update fails - class AtomicReference < AtomicReferenceImplementation - - # @return [String] Short string representation. - def to_s - format '%s value:%s>', super[0..-2], get - end - - alias_method :inspect, :to_s - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb deleted file mode 100644 index d883aed..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/atomic/mutex_count_down_latch' -require 'concurrent/atomic/java_count_down_latch' - -module Concurrent - - ################################################################### - - # @!macro count_down_latch_method_initialize - # - # Create a new `CountDownLatch` with the initial `count`. - # - # @param [new] count the initial count - # - # @raise [ArgumentError] if `count` is not an integer or is less than zero - - # @!macro count_down_latch_method_wait - # - # Block on the latch until the counter reaches zero or until `timeout` is reached. - # - # @param [Fixnum] timeout the number of seconds to wait for the counter or `nil` - # to block indefinitely - # @return [Boolean] `true` if the `count` reaches zero else false on `timeout` - - # @!macro count_down_latch_method_count_down - # - # Signal the latch to decrement the counter. Will signal all blocked threads when - # the `count` reaches zero. - - # @!macro count_down_latch_method_count - # - # The current value of the counter. - # - # @return [Fixnum] the current value of the counter - - ################################################################### - - # @!macro count_down_latch_public_api - # - # @!method initialize(count = 1) - # @!macro count_down_latch_method_initialize - # - # @!method wait(timeout = nil) - # @!macro count_down_latch_method_wait - # - # @!method count_down - # @!macro count_down_latch_method_count_down - # - # @!method count - # @!macro count_down_latch_method_count - - ################################################################### - - # @!visibility private - # @!macro internal_implementation_note - CountDownLatchImplementation = case - when Concurrent.on_jruby? - JavaCountDownLatch - else - MutexCountDownLatch - end - private_constant :CountDownLatchImplementation - - # @!macro count_down_latch - # - # A synchronization object that allows one thread to wait on multiple other threads. - # The thread that will wait creates a `CountDownLatch` and sets the initial value - # (normally equal to the number of other threads). The initiating thread passes the - # latch to the other threads then waits for the other threads by calling the `#wait` - # method. Each of the other threads calls `#count_down` when done with its work. - # When the latch counter reaches zero the waiting thread is unblocked and continues - # with its work. A `CountDownLatch` can be used only once. Its value cannot be reset. - # - # @!macro count_down_latch_public_api - # @example Waiter and Decrementer - # latch = Concurrent::CountDownLatch.new(3) - # - # waiter = Thread.new do - # latch.wait() - # puts ("Waiter released") - # end - # - # decrementer = Thread.new do - # sleep(1) - # latch.count_down - # puts latch.count - # - # sleep(1) - # latch.count_down - # puts latch.count - # - # sleep(1) - # latch.count_down - # puts latch.count - # end - # - # [waiter, decrementer].each(&:join) - class CountDownLatch < CountDownLatchImplementation - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb deleted file mode 100644 index 9ebe29d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'concurrent/synchronization/lockable_object' -require 'concurrent/utility/native_integer' - -module Concurrent - - # A synchronization aid that allows a set of threads to all wait for each - # other to reach a common barrier point. - # @example - # barrier = Concurrent::CyclicBarrier.new(3) - # jobs = Array.new(3) { |i| -> { sleep i; p done: i } } - # process = -> (i) do - # # waiting to start at the same time - # barrier.wait - # # execute job - # jobs[i].call - # # wait for others to finish - # barrier.wait - # end - # threads = 2.times.map do |i| - # Thread.new(i, &process) - # end - # - # # use main as well - # process.call 2 - # - # # here we can be sure that all jobs are processed - class CyclicBarrier < Synchronization::LockableObject - - # @!visibility private - Generation = Struct.new(:status) - private_constant :Generation - - # Create a new `CyclicBarrier` that waits for `parties` threads - # - # @param [Fixnum] parties the number of parties - # @yield an optional block that will be executed that will be executed after - # the last thread arrives and before the others are released - # - # @raise [ArgumentError] if `parties` is not an integer or is less than zero - def initialize(parties, &block) - Utility::NativeInteger.ensure_integer_and_bounds parties - Utility::NativeInteger.ensure_positive_and_no_zero parties - - super(&nil) - synchronize { ns_initialize parties, &block } - end - - # @return [Fixnum] the number of threads needed to pass the barrier - def parties - synchronize { @parties } - end - - # @return [Fixnum] the number of threads currently waiting on the barrier - def number_waiting - synchronize { @number_waiting } - end - - # Blocks on the barrier until the number of waiting threads is equal to - # `parties` or until `timeout` is reached or `reset` is called - # If a block has been passed to the constructor, it will be executed once by - # the last arrived thread before releasing the others - # @param [Fixnum] timeout the number of seconds to wait for the counter or - # `nil` to block indefinitely - # @return [Boolean] `true` if the `count` reaches zero else false on - # `timeout` or on `reset` or if the barrier is broken - def wait(timeout = nil) - synchronize do - - return false unless @generation.status == :waiting - - @number_waiting += 1 - - if @number_waiting == @parties - @action.call if @action - ns_generation_done @generation, :fulfilled - true - else - generation = @generation - if ns_wait_until(timeout) { generation.status != :waiting } - generation.status == :fulfilled - else - ns_generation_done generation, :broken, false - false - end - end - end - end - - # resets the barrier to its initial state - # If there is at least one waiting thread, it will be woken up, the `wait` - # method will return false and the barrier will be broken - # If the barrier is broken, this method restores it to the original state - # - # @return [nil] - def reset - synchronize { ns_generation_done @generation, :reset } - end - - # A barrier can be broken when: - # - a thread called the `reset` method while at least one other thread was waiting - # - at least one thread timed out on `wait` method - # - # A broken barrier can be restored using `reset` it's safer to create a new one - # @return [Boolean] true if the barrier is broken otherwise false - def broken? - synchronize { @generation.status != :waiting } - end - - protected - - def ns_generation_done(generation, status, continue = true) - generation.status = status - ns_next_generation if continue - ns_broadcast - end - - def ns_next_generation - @generation = Generation.new(:waiting) - @number_waiting = 0 - end - - def ns_initialize(parties, &block) - @parties = parties - @action = block - ns_next_generation - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/event.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/event.rb deleted file mode 100644 index ccf84c9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/event.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'thread' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # Old school kernel-style event reminiscent of Win32 programming in C++. - # - # When an `Event` is created it is in the `unset` state. Threads can choose to - # `#wait` on the event, blocking until released by another thread. When one - # thread wants to alert all blocking threads it calls the `#set` method which - # will then wake up all listeners. Once an `Event` has been set it remains set. - # New threads calling `#wait` will return immediately. An `Event` may be - # `#reset` at any time once it has been set. - # - # @see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655.aspx - # @example - # event = Concurrent::Event.new - # - # t1 = Thread.new do - # puts "t1 is waiting" - # event.wait(1) - # puts "event occurred" - # end - # - # t2 = Thread.new do - # puts "t2 calling set" - # event.set - # end - # - # [t1, t2].each(&:join) - # - # # prints: - # # t1 is waiting - # # t2 calling set - # # event occurred - class Event < Synchronization::LockableObject - - # Creates a new `Event` in the unset state. Threads calling `#wait` on the - # `Event` will block. - def initialize - super - synchronize { ns_initialize } - end - - # Is the object in the set state? - # - # @return [Boolean] indicating whether or not the `Event` has been set - def set? - synchronize { @set } - end - - # Trigger the event, setting the state to `set` and releasing all threads - # waiting on the event. Has no effect if the `Event` has already been set. - # - # @return [Boolean] should always return `true` - def set - synchronize { ns_set } - end - - def try? - synchronize { @set ? false : ns_set } - end - - # Reset a previously set event back to the `unset` state. - # Has no effect if the `Event` has not yet been set. - # - # @return [Boolean] should always return `true` - def reset - synchronize do - if @set - @set = false - @iteration +=1 - end - true - end - end - - # Wait a given number of seconds for the `Event` to be set by another - # thread. Will wait forever when no `timeout` value is given. Returns - # immediately if the `Event` has already been set. - # - # @return [Boolean] true if the `Event` was set before timeout else false - def wait(timeout = nil) - synchronize do - unless @set - iteration = @iteration - ns_wait_until(timeout) { iteration < @iteration || @set } - else - true - end - end - end - - protected - - def ns_set - unless @set - @set = true - ns_broadcast - end - true - end - - def ns_initialize - @set = false - @iteration = 0 - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb deleted file mode 100644 index e90fc24..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'concurrent/constants' -require_relative 'locals' - -module Concurrent - - # A `FiberLocalVar` is a variable where the value is different for each fiber. - # Each variable may have a default value, but when you modify the variable only - # the current fiber will ever see that change. - # - # This is similar to Ruby's built-in fiber-local variables (`Thread.current[:name]`), - # but with these major advantages: - # * `FiberLocalVar` has its own identity, it doesn't need a Symbol. - # * Each Ruby's built-in fiber-local variable leaks some memory forever (it's a Symbol held forever on the fiber), - # so it's only OK to create a small amount of them. - # `FiberLocalVar` has no such issue and it is fine to create many of them. - # * Ruby's built-in fiber-local variables leak forever the value set on each fiber (unless set to nil explicitly). - # `FiberLocalVar` automatically removes the mapping for each fiber once the `FiberLocalVar` instance is GC'd. - # - # @example - # v = FiberLocalVar.new(14) - # v.value #=> 14 - # v.value = 2 - # v.value #=> 2 - # - # @example - # v = FiberLocalVar.new(14) - # - # Fiber.new do - # v.value #=> 14 - # v.value = 1 - # v.value #=> 1 - # end.resume - # - # Fiber.new do - # v.value #=> 14 - # v.value = 2 - # v.value #=> 2 - # end.resume - # - # v.value #=> 14 - class FiberLocalVar - LOCALS = FiberLocals.new - - # Creates a fiber local variable. - # - # @param [Object] default the default value when otherwise unset - # @param [Proc] default_block Optional block that gets called to obtain the - # default value for each fiber - def initialize(default = nil, &default_block) - if default && block_given? - raise ArgumentError, "Cannot use both value and block as default value" - end - - if block_given? - @default_block = default_block - @default = nil - else - @default_block = nil - @default = default - end - - @index = LOCALS.next_index(self) - end - - # Returns the value in the current fiber's copy of this fiber-local variable. - # - # @return [Object] the current value - def value - LOCALS.fetch(@index) { default } - end - - # Sets the current fiber's copy of this fiber-local variable to the specified value. - # - # @param [Object] value the value to set - # @return [Object] the new value - def value=(value) - LOCALS.set(@index, value) - end - - # Bind the given value to fiber local storage during - # execution of the given block. - # - # @param [Object] value the value to bind - # @yield the operation to be performed with the bound variable - # @return [Object] the value - def bind(value) - if block_given? - old_value = self.value - self.value = value - begin - yield - ensure - self.value = old_value - end - end - end - - protected - - # @!visibility private - def default - if @default_block - self.value = @default_block.call - else - @default - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb deleted file mode 100644 index 3c119bc..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +++ /dev/null @@ -1,43 +0,0 @@ -if Concurrent.on_jruby? - require 'concurrent/utility/native_extension_loader' - - module Concurrent - - # @!macro count_down_latch - # @!visibility private - # @!macro internal_implementation_note - class JavaCountDownLatch - - # @!macro count_down_latch_method_initialize - def initialize(count = 1) - Utility::NativeInteger.ensure_integer_and_bounds(count) - Utility::NativeInteger.ensure_positive(count) - @latch = java.util.concurrent.CountDownLatch.new(count) - end - - # @!macro count_down_latch_method_wait - def wait(timeout = nil) - result = nil - if timeout.nil? - Synchronization::JRuby.sleep_interruptibly { @latch.await } - result = true - else - Synchronization::JRuby.sleep_interruptibly do - result = @latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) - end - end - result - end - - # @!macro count_down_latch_method_count_down - def count_down - @latch.countDown - end - - # @!macro count_down_latch_method_count - def count - @latch.getCount - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/locals.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/locals.rb deleted file mode 100644 index 0a276ae..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/locals.rb +++ /dev/null @@ -1,189 +0,0 @@ -require 'fiber' -require 'concurrent/utility/engine' -require 'concurrent/constants' - -module Concurrent - # @!visibility private - # @!macro internal_implementation_note - # - # An abstract implementation of local storage, with sub-classes for - # per-thread and per-fiber locals. - # - # Each execution context (EC, thread or fiber) has a lazily initialized array - # of local variable values. Each time a new local variable is created, we - # allocate an "index" for it. - # - # For example, if the allocated index is 1, that means slot #1 in EVERY EC's - # locals array will be used for the value of that variable. - # - # The good thing about using a per-EC structure to hold values, rather than - # a global, is that no synchronization is needed when reading and writing - # those values (since the structure is only ever accessed by a single - # thread). - # - # Of course, when a local variable is GC'd, 1) we need to recover its index - # for use by other new local variables (otherwise the locals arrays could - # get bigger and bigger with time), and 2) we need to null out all the - # references held in the now-unused slots (both to avoid blocking GC of those - # objects, and also to prevent "stale" values from being passed on to a new - # local when the index is reused). - # - # Because we need to null out freed slots, we need to keep references to - # ALL the locals arrays, so we can null out the appropriate slots in all of - # them. This is why we need to use a finalizer to clean up the locals array - # when the EC goes out of scope. - class AbstractLocals - def initialize - @free = [] - @lock = Mutex.new - @all_arrays = {} - @next = 0 - end - - def synchronize - @lock.synchronize { yield } - end - - if Concurrent.on_cruby? - def weak_synchronize - yield - end - else - alias_method :weak_synchronize, :synchronize - end - - def next_index(local) - index = synchronize do - if @free.empty? - @next += 1 - else - @free.pop - end - end - - # When the local goes out of scope, we should free the associated index - # and all values stored into it. - ObjectSpace.define_finalizer(local, local_finalizer(index)) - - index - end - - def free_index(index) - weak_synchronize do - # The cost of GC'ing a TLV is linear in the number of ECs using local - # variables. But that is natural! More ECs means more storage is used - # per local variable. So naturally more CPU time is required to free - # more storage. - # - # DO NOT use each_value which might conflict with new pair assignment - # into the hash in #set method. - @all_arrays.values.each do |locals| - locals[index] = nil - end - - # free index has to be published after the arrays are cleared: - @free << index - end - end - - def fetch(index) - locals = self.locals - value = locals ? locals[index] : nil - - if nil == value - yield - elsif NULL.equal?(value) - nil - else - value - end - end - - def set(index, value) - locals = self.locals! - locals[index] = (nil == value ? NULL : value) - - value - end - - private - - # When the local goes out of scope, clean up that slot across all locals currently assigned. - def local_finalizer(index) - proc do - free_index(index) - end - end - - # When a thread/fiber goes out of scope, remove the array from @all_arrays. - def thread_fiber_finalizer(array_object_id) - proc do - weak_synchronize do - @all_arrays.delete(array_object_id) - end - end - end - - # Returns the locals for the current scope, or nil if none exist. - def locals - raise NotImplementedError - end - - # Returns the locals for the current scope, creating them if necessary. - def locals! - raise NotImplementedError - end - end - - # @!visibility private - # @!macro internal_implementation_note - # An array-backed storage of indexed variables per thread. - class ThreadLocals < AbstractLocals - def locals - Thread.current.thread_variable_get(:concurrent_thread_locals) - end - - def locals! - thread = Thread.current - locals = thread.thread_variable_get(:concurrent_thread_locals) - - unless locals - locals = thread.thread_variable_set(:concurrent_thread_locals, []) - weak_synchronize do - @all_arrays[locals.object_id] = locals - end - # When the thread goes out of scope, we should delete the associated locals: - ObjectSpace.define_finalizer(thread, thread_fiber_finalizer(locals.object_id)) - end - - locals - end - end - - # @!visibility private - # @!macro internal_implementation_note - # An array-backed storage of indexed variables per fiber. - class FiberLocals < AbstractLocals - def locals - Thread.current[:concurrent_fiber_locals] - end - - def locals! - thread = Thread.current - locals = thread[:concurrent_fiber_locals] - - unless locals - locals = thread[:concurrent_fiber_locals] = [] - weak_synchronize do - @all_arrays[locals.object_id] = locals - end - # When the fiber goes out of scope, we should delete the associated locals: - ObjectSpace.define_finalizer(Fiber.current, thread_fiber_finalizer(locals.object_id)) - end - - locals - end - end - - private_constant :AbstractLocals, :ThreadLocals, :FiberLocals -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb deleted file mode 100644 index ebf23a2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'concurrent/utility/engine' -require_relative 'fiber_local_var' -require_relative 'thread_local_var' - -module Concurrent - # @!visibility private - def self.mutex_owned_per_thread? - return false if Concurrent.on_jruby? || Concurrent.on_truffleruby? - - mutex = Mutex.new - # Lock the mutex: - mutex.synchronize do - # Check if the mutex is still owned in a child fiber: - Fiber.new { mutex.owned? }.resume - end - end - - if mutex_owned_per_thread? - LockLocalVar = ThreadLocalVar - else - LockLocalVar = FiberLocalVar - end - - # Either {FiberLocalVar} or {ThreadLocalVar} depending on whether Mutex (and Monitor) - # are held, respectively, per Fiber or per Thread. - class LockLocalVar - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb deleted file mode 100644 index 015996b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'concurrent/synchronization/safe_initialization' - -module Concurrent - - # @!macro atomic_boolean - # @!visibility private - # @!macro internal_implementation_note - class MutexAtomicBoolean - extend Concurrent::Synchronization::SafeInitialization - - # @!macro atomic_boolean_method_initialize - def initialize(initial = false) - super() - @Lock = ::Mutex.new - @value = !!initial - end - - # @!macro atomic_boolean_method_value_get - def value - synchronize { @value } - end - - # @!macro atomic_boolean_method_value_set - def value=(value) - synchronize { @value = !!value } - end - - # @!macro atomic_boolean_method_true_question - def true? - synchronize { @value } - end - - # @!macro atomic_boolean_method_false_question - def false? - synchronize { !@value } - end - - # @!macro atomic_boolean_method_make_true - def make_true - synchronize { ns_make_value(true) } - end - - # @!macro atomic_boolean_method_make_false - def make_false - synchronize { ns_make_value(false) } - end - - protected - - # @!visibility private - def synchronize - if @Lock.owned? - yield - else - @Lock.synchronize { yield } - end - end - - private - - # @!visibility private - def ns_make_value(value) - old = @value - @value = value - old != @value - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb deleted file mode 100644 index 0ca3955..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'concurrent/synchronization/safe_initialization' -require 'concurrent/utility/native_integer' - -module Concurrent - - # @!macro atomic_fixnum - # @!visibility private - # @!macro internal_implementation_note - class MutexAtomicFixnum - extend Concurrent::Synchronization::SafeInitialization - - # @!macro atomic_fixnum_method_initialize - def initialize(initial = 0) - super() - @Lock = ::Mutex.new - ns_set(initial) - end - - # @!macro atomic_fixnum_method_value_get - def value - synchronize { @value } - end - - # @!macro atomic_fixnum_method_value_set - def value=(value) - synchronize { ns_set(value) } - end - - # @!macro atomic_fixnum_method_increment - def increment(delta = 1) - synchronize { ns_set(@value + delta.to_i) } - end - - alias_method :up, :increment - - # @!macro atomic_fixnum_method_decrement - def decrement(delta = 1) - synchronize { ns_set(@value - delta.to_i) } - end - - alias_method :down, :decrement - - # @!macro atomic_fixnum_method_compare_and_set - def compare_and_set(expect, update) - synchronize do - if @value == expect.to_i - @value = update.to_i - true - else - false - end - end - end - - # @!macro atomic_fixnum_method_update - def update - synchronize do - @value = yield @value - end - end - - protected - - # @!visibility private - def synchronize - if @Lock.owned? - yield - else - @Lock.synchronize { yield } - end - end - - private - - # @!visibility private - def ns_set(value) - Utility::NativeInteger.ensure_integer_and_bounds value - @value = value - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb deleted file mode 100644 index 29aa1ca..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'concurrent/synchronization/lockable_object' -require 'concurrent/utility/native_integer' - -module Concurrent - - # @!macro count_down_latch - # @!visibility private - # @!macro internal_implementation_note - class MutexCountDownLatch < Synchronization::LockableObject - - # @!macro count_down_latch_method_initialize - def initialize(count = 1) - Utility::NativeInteger.ensure_integer_and_bounds count - Utility::NativeInteger.ensure_positive count - - super() - synchronize { ns_initialize count } - end - - # @!macro count_down_latch_method_wait - def wait(timeout = nil) - synchronize { ns_wait_until(timeout) { @count == 0 } } - end - - # @!macro count_down_latch_method_count_down - def count_down - synchronize do - @count -= 1 if @count > 0 - ns_broadcast if @count == 0 - end - end - - # @!macro count_down_latch_method_count - def count - synchronize { @count } - end - - protected - - def ns_initialize(count) - @count = count - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb deleted file mode 100644 index 4347289..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +++ /dev/null @@ -1,131 +0,0 @@ -require 'concurrent/synchronization/lockable_object' -require 'concurrent/utility/native_integer' - -module Concurrent - - # @!macro semaphore - # @!visibility private - # @!macro internal_implementation_note - class MutexSemaphore < Synchronization::LockableObject - - # @!macro semaphore_method_initialize - def initialize(count) - Utility::NativeInteger.ensure_integer_and_bounds count - - super() - synchronize { ns_initialize count } - end - - # @!macro semaphore_method_acquire - def acquire(permits = 1) - Utility::NativeInteger.ensure_integer_and_bounds permits - Utility::NativeInteger.ensure_positive permits - - synchronize do - try_acquire_timed(permits, nil) - end - - return unless block_given? - - begin - yield - ensure - release(permits) - end - end - - # @!macro semaphore_method_available_permits - def available_permits - synchronize { @free } - end - - # @!macro semaphore_method_drain_permits - # - # Acquires and returns all permits that are immediately available. - # - # @return [Integer] - def drain_permits - synchronize do - @free.tap { |_| @free = 0 } - end - end - - # @!macro semaphore_method_try_acquire - def try_acquire(permits = 1, timeout = nil) - Utility::NativeInteger.ensure_integer_and_bounds permits - Utility::NativeInteger.ensure_positive permits - - acquired = synchronize do - if timeout.nil? - try_acquire_now(permits) - else - try_acquire_timed(permits, timeout) - end - end - - return acquired unless block_given? - return unless acquired - - begin - yield - ensure - release(permits) - end - end - - # @!macro semaphore_method_release - def release(permits = 1) - Utility::NativeInteger.ensure_integer_and_bounds permits - Utility::NativeInteger.ensure_positive permits - - synchronize do - @free += permits - permits.times { ns_signal } - end - nil - end - - # Shrinks the number of available permits by the indicated reduction. - # - # @param [Fixnum] reduction Number of permits to remove. - # - # @raise [ArgumentError] if `reduction` is not an integer or is negative - # - # @raise [ArgumentError] if `@free` - `@reduction` is less than zero - # - # @return [nil] - # - # @!visibility private - def reduce_permits(reduction) - Utility::NativeInteger.ensure_integer_and_bounds reduction - Utility::NativeInteger.ensure_positive reduction - - synchronize { @free -= reduction } - nil - end - - protected - - # @!visibility private - def ns_initialize(count) - @free = count - end - - private - - # @!visibility private - def try_acquire_now(permits) - if @free >= permits - @free -= permits - true - else - false - end - end - - # @!visibility private - def try_acquire_timed(permits, timeout) - ns_wait_until(timeout) { try_acquire_now(permits) } - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb deleted file mode 100644 index b26bd17..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +++ /dev/null @@ -1,255 +0,0 @@ -require 'thread' -require 'concurrent/atomic/atomic_fixnum' -require 'concurrent/errors' -require 'concurrent/synchronization/object' -require 'concurrent/synchronization/lock' - -module Concurrent - - # Ruby read-write lock implementation - # - # Allows any number of concurrent readers, but only one concurrent writer - # (And if the "write" lock is taken, any readers who come along will have to wait) - # - # If readers are already active when a writer comes along, the writer will wait for - # all the readers to finish before going ahead. - # Any additional readers that come when the writer is already waiting, will also - # wait (so writers are not starved). - # - # This implementation is based on `java.util.concurrent.ReentrantReadWriteLock`. - # - # @example - # lock = Concurrent::ReadWriteLock.new - # lock.with_read_lock { data.retrieve } - # lock.with_write_lock { data.modify! } - # - # @note Do **not** try to acquire the write lock while already holding a read lock - # **or** try to acquire the write lock while you already have it. - # This will lead to deadlock - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock - class ReadWriteLock < Synchronization::Object - - # @!visibility private - WAITING_WRITER = 1 << 15 - - # @!visibility private - RUNNING_WRITER = 1 << 29 - - # @!visibility private - MAX_READERS = WAITING_WRITER - 1 - - # @!visibility private - MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 - - safe_initialization! - - # Implementation notes: - # A goal is to make the uncontended path for both readers/writers lock-free - # Only if there is reader-writer or writer-writer contention, should locks be used - # Internal state is represented by a single integer ("counter"), and updated - # using atomic compare-and-swap operations - # When the counter is 0, the lock is free - # Each reader increments the counter by 1 when acquiring a read lock - # (and decrements by 1 when releasing the read lock) - # The counter is increased by (1 << 15) for each writer waiting to acquire the - # write lock, and by (1 << 29) if the write lock is taken - - # Create a new `ReadWriteLock` in the unlocked state. - def initialize - super() - @Counter = AtomicFixnum.new(0) # single integer which represents lock state - @ReadLock = Synchronization::Lock.new - @WriteLock = Synchronization::Lock.new - end - - # Execute a block operation within a read lock. - # - # @yield the task to be performed within the lock. - # - # @return [Object] the result of the block operation. - # - # @raise [ArgumentError] when no block is given. - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def with_read_lock - raise ArgumentError.new('no block given') unless block_given? - acquire_read_lock - begin - yield - ensure - release_read_lock - end - end - - # Execute a block operation within a write lock. - # - # @yield the task to be performed within the lock. - # - # @return [Object] the result of the block operation. - # - # @raise [ArgumentError] when no block is given. - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def with_write_lock - raise ArgumentError.new('no block given') unless block_given? - acquire_write_lock - begin - yield - ensure - release_write_lock - end - end - - # Acquire a read lock. If a write lock has been acquired will block until - # it is released. Will not block if other read locks have been acquired. - # - # @return [Boolean] true if the lock is successfully acquired - # - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def acquire_read_lock - while true - c = @Counter.value - raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) - - # If a writer is waiting when we first queue up, we need to wait - if waiting_writer?(c) - @ReadLock.wait_until { !waiting_writer? } - - # after a reader has waited once, they are allowed to "barge" ahead of waiting writers - # but if a writer is *running*, the reader still needs to wait (naturally) - while true - c = @Counter.value - if running_writer?(c) - @ReadLock.wait_until { !running_writer? } - else - return if @Counter.compare_and_set(c, c+1) - end - end - else - break if @Counter.compare_and_set(c, c+1) - end - end - true - end - - # Release a previously acquired read lock. - # - # @return [Boolean] true if the lock is successfully released - def release_read_lock - while true - c = @Counter.value - if @Counter.compare_and_set(c, c-1) - # If one or more writers were waiting, and we were the last reader, wake a writer up - if waiting_writer?(c) && running_readers(c) == 1 - @WriteLock.signal - end - break - end - end - true - end - - # Acquire a write lock. Will block and wait for all active readers and writers. - # - # @return [Boolean] true if the lock is successfully acquired - # - # @raise [Concurrent::ResourceLimitError] if the maximum number of writers - # is exceeded. - def acquire_write_lock - while true - c = @Counter.value - raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) - - if c == 0 # no readers OR writers running - # if we successfully swap the RUNNING_WRITER bit on, then we can go ahead - break if @Counter.compare_and_set(0, RUNNING_WRITER) - elsif @Counter.compare_and_set(c, c+WAITING_WRITER) - while true - # Now we have successfully incremented, so no more readers will be able to increment - # (they will wait instead) - # However, readers OR writers could decrement right here, OR another writer could increment - @WriteLock.wait_until do - # So we have to do another check inside the synchronized section - # If a writer OR reader is running, then go to sleep - c = @Counter.value - !running_writer?(c) && !running_readers?(c) - end - - # We just came out of a wait - # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, - # Then we are OK to stop waiting and go ahead - # Otherwise go back and wait again - c = @Counter.value - break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) - end - break - end - end - true - end - - # Release a previously acquired write lock. - # - # @return [Boolean] true if the lock is successfully released - def release_write_lock - return true unless running_writer? - c = @Counter.update { |counter| counter - RUNNING_WRITER } - @ReadLock.broadcast - @WriteLock.signal if waiting_writers(c) > 0 - true - end - - # Queries if the write lock is held by any thread. - # - # @return [Boolean] true if the write lock is held else false` - def write_locked? - @Counter.value >= RUNNING_WRITER - end - - # Queries whether any threads are waiting to acquire the read or write lock. - # - # @return [Boolean] true if any threads are waiting for a lock else false - def has_waiters? - waiting_writer?(@Counter.value) - end - - private - - # @!visibility private - def running_readers(c = @Counter.value) - c & MAX_READERS - end - - # @!visibility private - def running_readers?(c = @Counter.value) - (c & MAX_READERS) > 0 - end - - # @!visibility private - def running_writer?(c = @Counter.value) - c >= RUNNING_WRITER - end - - # @!visibility private - def waiting_writers(c = @Counter.value) - (c & MAX_WRITERS) / WAITING_WRITER - end - - # @!visibility private - def waiting_writer?(c = @Counter.value) - c >= WAITING_WRITER - end - - # @!visibility private - def max_readers?(c = @Counter.value) - (c & MAX_READERS) == MAX_READERS - end - - # @!visibility private - def max_writers?(c = @Counter.value) - (c & MAX_WRITERS) == MAX_WRITERS - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb deleted file mode 100644 index 6d72a3a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +++ /dev/null @@ -1,379 +0,0 @@ -require 'thread' -require 'concurrent/atomic/atomic_reference' -require 'concurrent/atomic/atomic_fixnum' -require 'concurrent/errors' -require 'concurrent/synchronization/object' -require 'concurrent/synchronization/lock' -require 'concurrent/atomic/lock_local_var' - -module Concurrent - - # Re-entrant read-write lock implementation - # - # Allows any number of concurrent readers, but only one concurrent writer - # (And while the "write" lock is taken, no read locks can be obtained either. - # Hence, the write lock can also be called an "exclusive" lock.) - # - # If another thread has taken a read lock, any thread which wants a write lock - # will block until all the readers release their locks. However, once a thread - # starts waiting to obtain a write lock, any additional readers that come along - # will also wait (so writers are not starved). - # - # A thread can acquire both a read and write lock at the same time. A thread can - # also acquire a read lock OR a write lock more than once. Only when the read (or - # write) lock is released as many times as it was acquired, will the thread - # actually let it go, allowing other threads which might have been waiting - # to proceed. Therefore the lock can be upgraded by first acquiring - # read lock and then write lock and that the lock can be downgraded by first - # having both read and write lock a releasing just the write lock. - # - # If both read and write locks are acquired by the same thread, it is not strictly - # necessary to release them in the same order they were acquired. In other words, - # the following code is legal: - # - # @example - # lock = Concurrent::ReentrantReadWriteLock.new - # lock.acquire_write_lock - # lock.acquire_read_lock - # lock.release_write_lock - # # At this point, the current thread is holding only a read lock, not a write - # # lock. So other threads can take read locks, but not a write lock. - # lock.release_read_lock - # # Now the current thread is not holding either a read or write lock, so - # # another thread could potentially acquire a write lock. - # - # This implementation was inspired by `java.util.concurrent.ReentrantReadWriteLock`. - # - # @example - # lock = Concurrent::ReentrantReadWriteLock.new - # lock.with_read_lock { data.retrieve } - # lock.with_write_lock { data.modify! } - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock - class ReentrantReadWriteLock < Synchronization::Object - - # Implementation notes: - # - # A goal is to make the uncontended path for both readers/writers mutex-free - # Only if there is reader-writer or writer-writer contention, should mutexes be used - # Otherwise, a single CAS operation is all we need to acquire/release a lock - # - # Internal state is represented by a single integer ("counter"), and updated - # using atomic compare-and-swap operations - # When the counter is 0, the lock is free - # Each thread which has one OR MORE read locks increments the counter by 1 - # (and decrements by 1 when releasing the read lock) - # The counter is increased by (1 << 15) for each writer waiting to acquire the - # write lock, and by (1 << 29) if the write lock is taken - # - # Additionally, each thread uses a thread-local variable to count how many times - # it has acquired a read lock, AND how many times it has acquired a write lock. - # It uses a similar trick; an increment of 1 means a read lock was taken, and - # an increment of (1 << 15) means a write lock was taken - # This is what makes re-entrancy possible - # - # 2 rules are followed to ensure good liveness properties: - # 1) Once a writer has queued up and is waiting for a write lock, no other thread - # can take a lock without waiting - # 2) When a write lock is released, readers are given the "first chance" to wake - # up and acquire a read lock - # Following these rules means readers and writers tend to "take turns", so neither - # can starve the other, even under heavy contention - - # @!visibility private - READER_BITS = 15 - # @!visibility private - WRITER_BITS = 14 - - # Used with @Counter: - # @!visibility private - WAITING_WRITER = 1 << READER_BITS - # @!visibility private - RUNNING_WRITER = 1 << (READER_BITS + WRITER_BITS) - # @!visibility private - MAX_READERS = WAITING_WRITER - 1 - # @!visibility private - MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 - - # Used with @HeldCount: - # @!visibility private - WRITE_LOCK_HELD = 1 << READER_BITS - # @!visibility private - READ_LOCK_MASK = WRITE_LOCK_HELD - 1 - # @!visibility private - WRITE_LOCK_MASK = MAX_WRITERS - - safe_initialization! - - # Create a new `ReentrantReadWriteLock` in the unlocked state. - def initialize - super() - @Counter = AtomicFixnum.new(0) # single integer which represents lock state - @ReadQueue = Synchronization::Lock.new # used to queue waiting readers - @WriteQueue = Synchronization::Lock.new # used to queue waiting writers - @HeldCount = LockLocalVar.new(0) # indicates # of R & W locks held by this thread - end - - # Execute a block operation within a read lock. - # - # @yield the task to be performed within the lock. - # - # @return [Object] the result of the block operation. - # - # @raise [ArgumentError] when no block is given. - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def with_read_lock - raise ArgumentError.new('no block given') unless block_given? - acquire_read_lock - begin - yield - ensure - release_read_lock - end - end - - # Execute a block operation within a write lock. - # - # @yield the task to be performed within the lock. - # - # @return [Object] the result of the block operation. - # - # @raise [ArgumentError] when no block is given. - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def with_write_lock - raise ArgumentError.new('no block given') unless block_given? - acquire_write_lock - begin - yield - ensure - release_write_lock - end - end - - # Acquire a read lock. If a write lock is held by another thread, will block - # until it is released. - # - # @return [Boolean] true if the lock is successfully acquired - # - # @raise [Concurrent::ResourceLimitError] if the maximum number of readers - # is exceeded. - def acquire_read_lock - if (held = @HeldCount.value) > 0 - # If we already have a lock, there's no need to wait - if held & READ_LOCK_MASK == 0 - # But we do need to update the counter, if we were holding a write - # lock but not a read lock - @Counter.update { |c| c + 1 } - end - @HeldCount.value = held + 1 - return true - end - - while true - c = @Counter.value - raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) - - # If a writer is waiting OR running when we first queue up, we need to wait - if waiting_or_running_writer?(c) - # Before going to sleep, check again with the ReadQueue mutex held - @ReadQueue.synchronize do - @ReadQueue.ns_wait if waiting_or_running_writer? - end - # Note: the above 'synchronize' block could have used #wait_until, - # but that waits repeatedly in a loop, checking the wait condition - # each time it wakes up (to protect against spurious wakeups) - # But we are already in a loop, which is only broken when we successfully - # acquire the lock! So we don't care about spurious wakeups, and would - # rather not pay the extra overhead of using #wait_until - - # After a reader has waited once, they are allowed to "barge" ahead of waiting writers - # But if a writer is *running*, the reader still needs to wait (naturally) - while true - c = @Counter.value - if running_writer?(c) - @ReadQueue.synchronize do - @ReadQueue.ns_wait if running_writer? - end - elsif @Counter.compare_and_set(c, c+1) - @HeldCount.value = held + 1 - return true - end - end - elsif @Counter.compare_and_set(c, c+1) - @HeldCount.value = held + 1 - return true - end - end - end - - # Try to acquire a read lock and return true if we succeed. If it cannot be - # acquired immediately, return false. - # - # @return [Boolean] true if the lock is successfully acquired - def try_read_lock - if (held = @HeldCount.value) > 0 - if held & READ_LOCK_MASK == 0 - # If we hold a write lock, but not a read lock... - @Counter.update { |c| c + 1 } - end - @HeldCount.value = held + 1 - return true - else - c = @Counter.value - if !waiting_or_running_writer?(c) && @Counter.compare_and_set(c, c+1) - @HeldCount.value = held + 1 - return true - end - end - false - end - - # Release a previously acquired read lock. - # - # @return [Boolean] true if the lock is successfully released - def release_read_lock - held = @HeldCount.value = @HeldCount.value - 1 - rlocks_held = held & READ_LOCK_MASK - if rlocks_held == 0 - c = @Counter.update { |counter| counter - 1 } - # If one or more writers were waiting, and we were the last reader, wake a writer up - if waiting_or_running_writer?(c) && running_readers(c) == 0 - @WriteQueue.signal - end - elsif rlocks_held == READ_LOCK_MASK - raise IllegalOperationError, "Cannot release a read lock which is not held" - end - true - end - - # Acquire a write lock. Will block and wait for all active readers and writers. - # - # @return [Boolean] true if the lock is successfully acquired - # - # @raise [Concurrent::ResourceLimitError] if the maximum number of writers - # is exceeded. - def acquire_write_lock - if (held = @HeldCount.value) >= WRITE_LOCK_HELD - # if we already have a write (exclusive) lock, there's no need to wait - @HeldCount.value = held + WRITE_LOCK_HELD - return true - end - - while true - c = @Counter.value - raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) - - # To go ahead and take the lock without waiting, there must be no writer - # running right now, AND no writers who came before us still waiting to - # acquire the lock - # Additionally, if any read locks have been taken, we must hold all of them - if held > 0 && @Counter.compare_and_set(1, c+RUNNING_WRITER) - # If we are the only one reader and successfully swap the RUNNING_WRITER bit on, then we can go ahead - @HeldCount.value = held + WRITE_LOCK_HELD - return true - elsif @Counter.compare_and_set(c, c+WAITING_WRITER) - while true - # Now we have successfully incremented, so no more readers will be able to increment - # (they will wait instead) - # However, readers OR writers could decrement right here - @WriteQueue.synchronize do - # So we have to do another check inside the synchronized section - # If a writer OR another reader is running, then go to sleep - c = @Counter.value - @WriteQueue.ns_wait if running_writer?(c) || running_readers(c) != held - end - # Note: if you are thinking of replacing the above 'synchronize' block - # with #wait_until, read the comment in #acquire_read_lock first! - - # We just came out of a wait - # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, - # then we are OK to stop waiting and go ahead - # Otherwise go back and wait again - c = @Counter.value - if !running_writer?(c) && - running_readers(c) == held && - @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) - @HeldCount.value = held + WRITE_LOCK_HELD - return true - end - end - end - end - end - - # Try to acquire a write lock and return true if we succeed. If it cannot be - # acquired immediately, return false. - # - # @return [Boolean] true if the lock is successfully acquired - def try_write_lock - if (held = @HeldCount.value) >= WRITE_LOCK_HELD - @HeldCount.value = held + WRITE_LOCK_HELD - return true - else - c = @Counter.value - if !waiting_or_running_writer?(c) && - running_readers(c) == held && - @Counter.compare_and_set(c, c+RUNNING_WRITER) - @HeldCount.value = held + WRITE_LOCK_HELD - return true - end - end - false - end - - # Release a previously acquired write lock. - # - # @return [Boolean] true if the lock is successfully released - def release_write_lock - held = @HeldCount.value = @HeldCount.value - WRITE_LOCK_HELD - wlocks_held = held & WRITE_LOCK_MASK - if wlocks_held == 0 - c = @Counter.update { |counter| counter - RUNNING_WRITER } - @ReadQueue.broadcast - @WriteQueue.signal if waiting_writers(c) > 0 - elsif wlocks_held == WRITE_LOCK_MASK - raise IllegalOperationError, "Cannot release a write lock which is not held" - end - true - end - - private - - # @!visibility private - def running_readers(c = @Counter.value) - c & MAX_READERS - end - - # @!visibility private - def running_readers?(c = @Counter.value) - (c & MAX_READERS) > 0 - end - - # @!visibility private - def running_writer?(c = @Counter.value) - c >= RUNNING_WRITER - end - - # @!visibility private - def waiting_writers(c = @Counter.value) - (c & MAX_WRITERS) >> READER_BITS - end - - # @!visibility private - def waiting_or_running_writer?(c = @Counter.value) - c >= WAITING_WRITER - end - - # @!visibility private - def max_readers?(c = @Counter.value) - (c & MAX_READERS) == MAX_READERS - end - - # @!visibility private - def max_writers?(c = @Counter.value) - (c & MAX_WRITERS) == MAX_WRITERS - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/semaphore.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/semaphore.rb deleted file mode 100644 index f0799f0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +++ /dev/null @@ -1,163 +0,0 @@ -require 'concurrent/atomic/mutex_semaphore' - -module Concurrent - - ################################################################### - - # @!macro semaphore_method_initialize - # - # Create a new `Semaphore` with the initial `count`. - # - # @param [Fixnum] count the initial count - # - # @raise [ArgumentError] if `count` is not an integer - - # @!macro semaphore_method_acquire - # - # Acquires the given number of permits from this semaphore, - # blocking until all are available. If a block is given, - # yields to it and releases the permits afterwards. - # - # @param [Fixnum] permits Number of permits to acquire - # - # @raise [ArgumentError] if `permits` is not an integer or is less than zero - # - # @return [nil, BasicObject] Without a block, `nil` is returned. If a block - # is given, its return value is returned. - - # @!macro semaphore_method_available_permits - # - # Returns the current number of permits available in this semaphore. - # - # @return [Integer] - - # @!macro semaphore_method_drain_permits - # - # Acquires and returns all permits that are immediately available. - # - # @return [Integer] - - # @!macro semaphore_method_try_acquire - # - # Acquires the given number of permits from this semaphore, - # only if all are available at the time of invocation or within - # `timeout` interval. If a block is given, yields to it if the permits - # were successfully acquired, and releases them afterward, returning the - # block's return value. - # - # @param [Fixnum] permits the number of permits to acquire - # - # @param [Fixnum] timeout the number of seconds to wait for the counter - # or `nil` to return immediately - # - # @raise [ArgumentError] if `permits` is not an integer or is less than zero - # - # @return [true, false, nil, BasicObject] `false` if no permits are - # available, `true` when acquired a permit. If a block is given, the - # block's return value is returned if the permits were acquired; if not, - # `nil` is returned. - - # @!macro semaphore_method_release - # - # Releases the given number of permits, returning them to the semaphore. - # - # @param [Fixnum] permits Number of permits to return to the semaphore. - # - # @raise [ArgumentError] if `permits` is not a number or is less than zero - # - # @return [nil] - - ################################################################### - - # @!macro semaphore_public_api - # - # @!method initialize(count) - # @!macro semaphore_method_initialize - # - # @!method acquire(permits = 1) - # @!macro semaphore_method_acquire - # - # @!method available_permits - # @!macro semaphore_method_available_permits - # - # @!method drain_permits - # @!macro semaphore_method_drain_permits - # - # @!method try_acquire(permits = 1, timeout = nil) - # @!macro semaphore_method_try_acquire - # - # @!method release(permits = 1) - # @!macro semaphore_method_release - - ################################################################### - - # @!visibility private - # @!macro internal_implementation_note - SemaphoreImplementation = if Concurrent.on_jruby? - require 'concurrent/utility/native_extension_loader' - JavaSemaphore - else - MutexSemaphore - end - private_constant :SemaphoreImplementation - - # @!macro semaphore - # - # A counting semaphore. Conceptually, a semaphore maintains a set of - # permits. Each {#acquire} blocks if necessary until a permit is - # available, and then takes it. Each {#release} adds a permit, potentially - # releasing a blocking acquirer. - # However, no actual permit objects are used; the Semaphore just keeps a - # count of the number available and acts accordingly. - # Alternatively, permits may be acquired within a block, and automatically - # released after the block finishes executing. - # - # @!macro semaphore_public_api - # @example - # semaphore = Concurrent::Semaphore.new(2) - # - # t1 = Thread.new do - # semaphore.acquire - # puts "Thread 1 acquired semaphore" - # end - # - # t2 = Thread.new do - # semaphore.acquire - # puts "Thread 2 acquired semaphore" - # end - # - # t3 = Thread.new do - # semaphore.acquire - # puts "Thread 3 acquired semaphore" - # end - # - # t4 = Thread.new do - # sleep(2) - # puts "Thread 4 releasing semaphore" - # semaphore.release - # end - # - # [t1, t2, t3, t4].each(&:join) - # - # # prints: - # # Thread 3 acquired semaphore - # # Thread 2 acquired semaphore - # # Thread 4 releasing semaphore - # # Thread 1 acquired semaphore - # - # @example - # semaphore = Concurrent::Semaphore.new(1) - # - # puts semaphore.available_permits - # semaphore.acquire do - # puts semaphore.available_permits - # end - # puts semaphore.available_permits - # - # # prints: - # # 1 - # # 0 - # # 1 - class Semaphore < SemaphoreImplementation - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb deleted file mode 100644 index 3b7e12b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'concurrent/constants' -require_relative 'locals' - -module Concurrent - - # A `ThreadLocalVar` is a variable where the value is different for each thread. - # Each variable may have a default value, but when you modify the variable only - # the current thread will ever see that change. - # - # This is similar to Ruby's built-in thread-local variables (`Thread#thread_variable_get`), - # but with these major advantages: - # * `ThreadLocalVar` has its own identity, it doesn't need a Symbol. - # * Each Ruby's built-in thread-local variable leaks some memory forever (it's a Symbol held forever on the thread), - # so it's only OK to create a small amount of them. - # `ThreadLocalVar` has no such issue and it is fine to create many of them. - # * Ruby's built-in thread-local variables leak forever the value set on each thread (unless set to nil explicitly). - # `ThreadLocalVar` automatically removes the mapping for each thread once the `ThreadLocalVar` instance is GC'd. - # - # @!macro thread_safe_variable_comparison - # - # @example - # v = ThreadLocalVar.new(14) - # v.value #=> 14 - # v.value = 2 - # v.value #=> 2 - # - # @example - # v = ThreadLocalVar.new(14) - # - # t1 = Thread.new do - # v.value #=> 14 - # v.value = 1 - # v.value #=> 1 - # end - # - # t2 = Thread.new do - # v.value #=> 14 - # v.value = 2 - # v.value #=> 2 - # end - # - # v.value #=> 14 - class ThreadLocalVar - LOCALS = ThreadLocals.new - - # Creates a thread local variable. - # - # @param [Object] default the default value when otherwise unset - # @param [Proc] default_block Optional block that gets called to obtain the - # default value for each thread - def initialize(default = nil, &default_block) - if default && block_given? - raise ArgumentError, "Cannot use both value and block as default value" - end - - if block_given? - @default_block = default_block - @default = nil - else - @default_block = nil - @default = default - end - - @index = LOCALS.next_index(self) - end - - # Returns the value in the current thread's copy of this thread-local variable. - # - # @return [Object] the current value - def value - LOCALS.fetch(@index) { default } - end - - # Sets the current thread's copy of this thread-local variable to the specified value. - # - # @param [Object] value the value to set - # @return [Object] the new value - def value=(value) - LOCALS.set(@index, value) - end - - # Bind the given value to thread local storage during - # execution of the given block. - # - # @param [Object] value the value to bind - # @yield the operation to be performed with the bound variable - # @return [Object] the value - def bind(value) - if block_given? - old_value = self.value - self.value = value - begin - yield - ensure - self.value = old_value - end - end - end - - protected - - # @!visibility private - def default - if @default_block - self.value = @default_block.call - else - @default - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb deleted file mode 100644 index 5d2d7ed..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'concurrent/errors' - -module Concurrent - - # Define update methods that use direct paths - # - # @!visibility private - # @!macro internal_implementation_note - module AtomicDirectUpdate - def update - true until compare_and_set(old_value = get, new_value = yield(old_value)) - new_value - end - - def try_update - old_value = get - new_value = yield old_value - - return unless compare_and_set old_value, new_value - - new_value - end - - def try_update! - old_value = get - new_value = yield old_value - unless compare_and_set(old_value, new_value) - if $VERBOSE - raise ConcurrentUpdateError, "Update failed" - else - raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE - end - end - new_value - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb deleted file mode 100644 index e5e2a63..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'concurrent/atomic_reference/atomic_direct_update' -require 'concurrent/atomic_reference/numeric_cas_wrapper' -require 'concurrent/synchronization/safe_initialization' - -module Concurrent - - # @!visibility private - # @!macro internal_implementation_note - class MutexAtomicReference - extend Concurrent::Synchronization::SafeInitialization - include AtomicDirectUpdate - include AtomicNumericCompareAndSetWrapper - alias_method :compare_and_swap, :compare_and_set - - # @!macro atomic_reference_method_initialize - def initialize(value = nil) - super() - @Lock = ::Mutex.new - @value = value - end - - # @!macro atomic_reference_method_get - def get - synchronize { @value } - end - alias_method :value, :get - - # @!macro atomic_reference_method_set - def set(new_value) - synchronize { @value = new_value } - end - alias_method :value=, :set - - # @!macro atomic_reference_method_get_and_set - def get_and_set(new_value) - synchronize do - old_value = @value - @value = new_value - old_value - end - end - alias_method :swap, :get_and_set - - # @!macro atomic_reference_method_compare_and_set - def _compare_and_set(old_value, new_value) - synchronize do - if @value.equal? old_value - @value = new_value - true - else - false - end - end - end - - protected - - # @!visibility private - def synchronize - if @Lock.owned? - yield - else - @Lock.synchronize { yield } - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb deleted file mode 100644 index 709a382..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Concurrent - - # Special "compare and set" handling of numeric values. - # - # @!visibility private - # @!macro internal_implementation_note - module AtomicNumericCompareAndSetWrapper - - # @!macro atomic_reference_method_compare_and_set - def compare_and_set(old_value, new_value) - if old_value.kind_of? Numeric - while true - old = get - - return false unless old.kind_of? Numeric - - return false unless old == old_value - - result = _compare_and_set(old, new_value) - return result if result - end - else - _compare_and_set(old_value, new_value) - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomics.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomics.rb deleted file mode 100644 index 16cbe66..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/atomics.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'concurrent/atomic/atomic_reference' -require 'concurrent/atomic/atomic_boolean' -require 'concurrent/atomic/atomic_fixnum' -require 'concurrent/atomic/cyclic_barrier' -require 'concurrent/atomic/count_down_latch' -require 'concurrent/atomic/event' -require 'concurrent/atomic/read_write_lock' -require 'concurrent/atomic/reentrant_read_write_lock' -require 'concurrent/atomic/semaphore' -require 'concurrent/atomic/thread_local_var' diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb deleted file mode 100644 index 7c700bd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +++ /dev/null @@ -1,107 +0,0 @@ -require 'concurrent/synchronization/lockable_object' - -module Concurrent - module Collection - - # A thread safe observer set implemented using copy-on-read approach: - # observers are added and removed from a thread safe collection; every time - # a notification is required the internal data structure is copied to - # prevent concurrency issues - # - # @api private - class CopyOnNotifyObserverSet < Synchronization::LockableObject - - def initialize - super() - synchronize { ns_initialize } - end - - # @!macro observable_add_observer - def add_observer(observer = nil, func = :update, &block) - if observer.nil? && block.nil? - raise ArgumentError, 'should pass observer as a first argument or block' - elsif observer && block - raise ArgumentError.new('cannot provide both an observer and a block') - end - - if block - observer = block - func = :call - end - - synchronize do - @observers[observer] = func - observer - end - end - - # @!macro observable_delete_observer - def delete_observer(observer) - synchronize do - @observers.delete(observer) - observer - end - end - - # @!macro observable_delete_observers - def delete_observers - synchronize do - @observers.clear - self - end - end - - # @!macro observable_count_observers - def count_observers - synchronize { @observers.count } - end - - # Notifies all registered observers with optional args - # @param [Object] args arguments to be passed to each observer - # @return [CopyOnWriteObserverSet] self - def notify_observers(*args, &block) - observers = duplicate_observers - notify_to(observers, *args, &block) - self - end - - # Notifies all registered observers with optional args and deletes them. - # - # @param [Object] args arguments to be passed to each observer - # @return [CopyOnWriteObserverSet] self - def notify_and_delete_observers(*args, &block) - observers = duplicate_and_clear_observers - notify_to(observers, *args, &block) - self - end - - protected - - def ns_initialize - @observers = {} - end - - private - - def duplicate_and_clear_observers - synchronize do - observers = @observers.dup - @observers.clear - observers - end - end - - def duplicate_observers - synchronize { @observers.dup } - end - - def notify_to(observers, *args) - raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? - observers.each do |observer, function| - args = yield if block_given? - observer.send(function, *args) - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb deleted file mode 100644 index bcb6750..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'concurrent/synchronization/lockable_object' - -module Concurrent - module Collection - - # A thread safe observer set implemented using copy-on-write approach: - # every time an observer is added or removed the whole internal data structure is - # duplicated and replaced with a new one. - # - # @api private - class CopyOnWriteObserverSet < Synchronization::LockableObject - - def initialize - super() - synchronize { ns_initialize } - end - - # @!macro observable_add_observer - def add_observer(observer = nil, func = :update, &block) - if observer.nil? && block.nil? - raise ArgumentError, 'should pass observer as a first argument or block' - elsif observer && block - raise ArgumentError.new('cannot provide both an observer and a block') - end - - if block - observer = block - func = :call - end - - synchronize do - new_observers = @observers.dup - new_observers[observer] = func - @observers = new_observers - observer - end - end - - # @!macro observable_delete_observer - def delete_observer(observer) - synchronize do - new_observers = @observers.dup - new_observers.delete(observer) - @observers = new_observers - observer - end - end - - # @!macro observable_delete_observers - def delete_observers - self.observers = {} - self - end - - # @!macro observable_count_observers - def count_observers - observers.count - end - - # Notifies all registered observers with optional args - # @param [Object] args arguments to be passed to each observer - # @return [CopyOnWriteObserverSet] self - def notify_observers(*args, &block) - notify_to(observers, *args, &block) - self - end - - # Notifies all registered observers with optional args and deletes them. - # - # @param [Object] args arguments to be passed to each observer - # @return [CopyOnWriteObserverSet] self - def notify_and_delete_observers(*args, &block) - old = clear_observers_and_return_old - notify_to(old, *args, &block) - self - end - - protected - - def ns_initialize - @observers = {} - end - - private - - def notify_to(observers, *args) - raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? - observers.each do |observer, function| - args = yield if block_given? - observer.send(function, *args) - end - end - - def observers - synchronize { @observers } - end - - def observers=(new_set) - synchronize { @observers = new_set } - end - - def clear_observers_and_return_old - synchronize do - old_observers = @observers - @observers = {} - old_observers - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb deleted file mode 100644 index 2be9e43..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb +++ /dev/null @@ -1,84 +0,0 @@ -if Concurrent.on_jruby? - - module Concurrent - module Collection - - - # @!macro priority_queue - # - # @!visibility private - # @!macro internal_implementation_note - class JavaNonConcurrentPriorityQueue - - # @!macro priority_queue_method_initialize - def initialize(opts = {}) - order = opts.fetch(:order, :max) - if [:min, :low].include?(order) - @queue = java.util.PriorityQueue.new(11) # 11 is the default initial capacity - else - @queue = java.util.PriorityQueue.new(11, java.util.Collections.reverseOrder()) - end - end - - # @!macro priority_queue_method_clear - def clear - @queue.clear - true - end - - # @!macro priority_queue_method_delete - def delete(item) - found = false - while @queue.remove(item) do - found = true - end - found - end - - # @!macro priority_queue_method_empty - def empty? - @queue.size == 0 - end - - # @!macro priority_queue_method_include - def include?(item) - @queue.contains(item) - end - alias_method :has_priority?, :include? - - # @!macro priority_queue_method_length - def length - @queue.size - end - alias_method :size, :length - - # @!macro priority_queue_method_peek - def peek - @queue.peek - end - - # @!macro priority_queue_method_pop - def pop - @queue.poll - end - alias_method :deq, :pop - alias_method :shift, :pop - - # @!macro priority_queue_method_push - def push(item) - raise ArgumentError.new('cannot enqueue nil') if item.nil? - @queue.add(item) - end - alias_method :<<, :push - alias_method :enq, :push - - # @!macro priority_queue_method_from_list - def self.from_list(list, opts = {}) - queue = new(opts) - list.each{|item| queue << item } - queue - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb deleted file mode 100644 index 3704410..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +++ /dev/null @@ -1,160 +0,0 @@ -require 'concurrent/synchronization/object' - -module Concurrent - - # @!macro warn.edge - class LockFreeStack < Synchronization::Object - - safe_initialization! - - class Node - # TODO (pitr-ch 20-Dec-2016): Could be unified with Stack class? - - # @return [Node] - attr_reader :next_node - - # @return [Object] - attr_reader :value - - # @!visibility private - # allow to nil-ify to free GC when the entry is no longer relevant, not synchronised - attr_writer :value - - def initialize(value, next_node) - @value = value - @next_node = next_node - end - - singleton_class.send :alias_method, :[], :new - end - - # The singleton for empty node - EMPTY = Node[nil, nil] - def EMPTY.next_node - self - end - - attr_atomic(:head) - private :head, :head=, :swap_head, :compare_and_set_head, :update_head - - # @!visibility private - def self.of1(value) - new Node[value, EMPTY] - end - - # @!visibility private - def self.of2(value1, value2) - new Node[value1, Node[value2, EMPTY]] - end - - # @param [Node] head - def initialize(head = EMPTY) - super() - self.head = head - end - - # @param [Node] head - # @return [true, false] - def empty?(head = head()) - head.equal? EMPTY - end - - # @param [Node] head - # @param [Object] value - # @return [true, false] - def compare_and_push(head, value) - compare_and_set_head head, Node[value, head] - end - - # @param [Object] value - # @return [self] - def push(value) - while true - current_head = head - return self if compare_and_set_head current_head, Node[value, current_head] - end - end - - # @return [Node] - def peek - head - end - - # @param [Node] head - # @return [true, false] - def compare_and_pop(head) - compare_and_set_head head, head.next_node - end - - # @return [Object] - def pop - while true - current_head = head - return current_head.value if compare_and_set_head current_head, current_head.next_node - end - end - - # @param [Node] head - # @return [true, false] - def compare_and_clear(head) - compare_and_set_head head, EMPTY - end - - include Enumerable - - # @param [Node] head - # @return [self] - def each(head = nil) - return to_enum(:each, head) unless block_given? - it = head || peek - until it.equal?(EMPTY) - yield it.value - it = it.next_node - end - self - end - - # @return [true, false] - def clear - while true - current_head = head - return false if current_head == EMPTY - return true if compare_and_set_head current_head, EMPTY - end - end - - # @param [Node] head - # @return [true, false] - def clear_if(head) - compare_and_set_head head, EMPTY - end - - # @param [Node] head - # @param [Node] new_head - # @return [true, false] - def replace_if(head, new_head) - compare_and_set_head head, new_head - end - - # @return [self] - # @yield over the cleared stack - # @yieldparam [Object] value - def clear_each(&block) - while true - current_head = head - return self if current_head == EMPTY - if compare_and_set_head current_head, EMPTY - each current_head, &block - return self - end - end - end - - # @return [String] Short string representation. - def to_s - format '%s %s>', super[0..-2], to_a.to_s - end - - alias_method :inspect, :to_s - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb deleted file mode 100644 index e0cf999..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'thread' -require 'concurrent/collection/map/non_concurrent_map_backend' - -module Concurrent - - # @!visibility private - module Collection - - # @!visibility private - class MriMapBackend < NonConcurrentMapBackend - - def initialize(options = nil, &default_proc) - super(options, &default_proc) - @write_lock = Mutex.new - end - - def []=(key, value) - @write_lock.synchronize { super } - end - - def compute_if_absent(key) - if NULL != (stored_value = @backend.fetch(key, NULL)) # fast non-blocking path for the most likely case - stored_value - else - @write_lock.synchronize { super } - end - end - - def compute_if_present(key) - @write_lock.synchronize { super } - end - - def compute(key) - @write_lock.synchronize { super } - end - - def merge_pair(key, value) - @write_lock.synchronize { super } - end - - def replace_pair(key, old_value, new_value) - @write_lock.synchronize { super } - end - - def replace_if_exists(key, new_value) - @write_lock.synchronize { super } - end - - def get_and_set(key, value) - @write_lock.synchronize { super } - end - - def delete(key) - @write_lock.synchronize { super } - end - - def delete_pair(key, value) - @write_lock.synchronize { super } - end - - def clear - @write_lock.synchronize { super } - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb deleted file mode 100644 index ca5fd9b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'concurrent/constants' - -module Concurrent - - # @!visibility private - module Collection - - # @!visibility private - class NonConcurrentMapBackend - - # WARNING: all public methods of the class must operate on the @backend - # directly without calling each other. This is important because of the - # SynchronizedMapBackend which uses a non-reentrant mutex for performance - # reasons. - def initialize(options = nil, &default_proc) - validate_options_hash!(options) if options.kind_of?(::Hash) - set_backend(default_proc) - @default_proc = default_proc - end - - def [](key) - @backend[key] - end - - def []=(key, value) - @backend[key] = value - end - - def compute_if_absent(key) - if NULL != (stored_value = @backend.fetch(key, NULL)) - stored_value - else - @backend[key] = yield - end - end - - def replace_pair(key, old_value, new_value) - if pair?(key, old_value) - @backend[key] = new_value - true - else - false - end - end - - def replace_if_exists(key, new_value) - if NULL != (stored_value = @backend.fetch(key, NULL)) - @backend[key] = new_value - stored_value - end - end - - def compute_if_present(key) - if NULL != (stored_value = @backend.fetch(key, NULL)) - store_computed_value(key, yield(stored_value)) - end - end - - def compute(key) - store_computed_value(key, yield(get_or_default(key, nil))) - end - - def merge_pair(key, value) - if NULL == (stored_value = @backend.fetch(key, NULL)) - @backend[key] = value - else - store_computed_value(key, yield(stored_value)) - end - end - - def get_and_set(key, value) - stored_value = get_or_default(key, nil) - @backend[key] = value - stored_value - end - - def key?(key) - @backend.key?(key) - end - - def delete(key) - @backend.delete(key) - end - - def delete_pair(key, value) - if pair?(key, value) - @backend.delete(key) - true - else - false - end - end - - def clear - @backend.clear - self - end - - def each_pair - dupped_backend.each_pair do |k, v| - yield k, v - end - self - end - - def size - @backend.size - end - - def get_or_default(key, default_value) - @backend.fetch(key, default_value) - end - - private - - def set_backend(default_proc) - if default_proc - @backend = ::Hash.new { |_h, key| default_proc.call(self, key) } - else - @backend = {} - end - end - - def initialize_copy(other) - super - set_backend(@default_proc) - self - end - - def dupped_backend - @backend.dup - end - - def pair?(key, expected_value) - NULL != (stored_value = @backend.fetch(key, NULL)) && expected_value.equal?(stored_value) - end - - def store_computed_value(key, new_value) - if new_value.nil? - @backend.delete(key) - nil - else - @backend[key] = new_value - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb deleted file mode 100644 index efa161e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'concurrent/collection/map/non_concurrent_map_backend' - -module Concurrent - - # @!visibility private - module Collection - - # @!visibility private - class SynchronizedMapBackend < NonConcurrentMapBackend - - def initialize(*args, &block) - super - - # WARNING: Mutex is a non-reentrant lock, so the synchronized methods are - # not allowed to call each other. - @mutex = Mutex.new - end - - def [](key) - @mutex.synchronize { super } - end - - def []=(key, value) - @mutex.synchronize { super } - end - - def compute_if_absent(key) - @mutex.synchronize { super } - end - - def compute_if_present(key) - @mutex.synchronize { super } - end - - def compute(key) - @mutex.synchronize { super } - end - - def merge_pair(key, value) - @mutex.synchronize { super } - end - - def replace_pair(key, old_value, new_value) - @mutex.synchronize { super } - end - - def replace_if_exists(key, new_value) - @mutex.synchronize { super } - end - - def get_and_set(key, value) - @mutex.synchronize { super } - end - - def key?(key) - @mutex.synchronize { super } - end - - def delete(key) - @mutex.synchronize { super } - end - - def delete_pair(key, value) - @mutex.synchronize { super } - end - - def clear - @mutex.synchronize { super } - end - - def size - @mutex.synchronize { super } - end - - def get_or_default(key, default_value) - @mutex.synchronize { super } - end - - private - def dupped_backend - @mutex.synchronize { super } - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb deleted file mode 100644 index 68a1b38..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Concurrent - - # @!visibility private - module Collection - - # @!visibility private - class TruffleRubyMapBackend < TruffleRuby::ConcurrentMap - def initialize(options = nil) - options ||= {} - super(initial_capacity: options[:initial_capacity], load_factor: options[:load_factor]) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb deleted file mode 100644 index 694cd7a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb +++ /dev/null @@ -1,143 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/collection/java_non_concurrent_priority_queue' -require 'concurrent/collection/ruby_non_concurrent_priority_queue' - -module Concurrent - module Collection - - # @!visibility private - # @!macro internal_implementation_note - NonConcurrentPriorityQueueImplementation = case - when Concurrent.on_jruby? - JavaNonConcurrentPriorityQueue - else - RubyNonConcurrentPriorityQueue - end - private_constant :NonConcurrentPriorityQueueImplementation - - # @!macro priority_queue - # - # A queue collection in which the elements are sorted based on their - # comparison (spaceship) operator `<=>`. Items are added to the queue - # at a position relative to their priority. On removal the element - # with the "highest" priority is removed. By default the sort order is - # from highest to lowest, but a lowest-to-highest sort order can be - # set on construction. - # - # The API is based on the `Queue` class from the Ruby standard library. - # - # The pure Ruby implementation, `RubyNonConcurrentPriorityQueue` uses a heap algorithm - # stored in an array. The algorithm is based on the work of Robert Sedgewick - # and Kevin Wayne. - # - # The JRuby native implementation is a thin wrapper around the standard - # library `java.util.NonConcurrentPriorityQueue`. - # - # When running under JRuby the class `NonConcurrentPriorityQueue` extends `JavaNonConcurrentPriorityQueue`. - # When running under all other interpreters it extends `RubyNonConcurrentPriorityQueue`. - # - # @note This implementation is *not* thread safe. - # - # @see http://en.wikipedia.org/wiki/Priority_queue - # @see http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/Queue.html - # - # @see http://algs4.cs.princeton.edu/24pq/index.php#2.6 - # @see http://algs4.cs.princeton.edu/24pq/MaxPQ.java.html - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html - # - # @!visibility private - class NonConcurrentPriorityQueue < NonConcurrentPriorityQueueImplementation - - alias_method :has_priority?, :include? - - alias_method :size, :length - - alias_method :deq, :pop - alias_method :shift, :pop - - alias_method :<<, :push - alias_method :enq, :push - - # @!method initialize(opts = {}) - # @!macro priority_queue_method_initialize - # - # Create a new priority queue with no items. - # - # @param [Hash] opts the options for creating the queue - # @option opts [Symbol] :order (:max) dictates the order in which items are - # stored: from highest to lowest when `:max` or `:high`; from lowest to - # highest when `:min` or `:low` - - # @!method clear - # @!macro priority_queue_method_clear - # - # Removes all of the elements from this priority queue. - - # @!method delete(item) - # @!macro priority_queue_method_delete - # - # Deletes all items from `self` that are equal to `item`. - # - # @param [Object] item the item to be removed from the queue - # @return [Object] true if the item is found else false - - # @!method empty? - # @!macro priority_queue_method_empty - # - # Returns `true` if `self` contains no elements. - # - # @return [Boolean] true if there are no items in the queue else false - - # @!method include?(item) - # @!macro priority_queue_method_include - # - # Returns `true` if the given item is present in `self` (that is, if any - # element == `item`), otherwise returns false. - # - # @param [Object] item the item to search for - # - # @return [Boolean] true if the item is found else false - - # @!method length - # @!macro priority_queue_method_length - # - # The current length of the queue. - # - # @return [Fixnum] the number of items in the queue - - # @!method peek - # @!macro priority_queue_method_peek - # - # Retrieves, but does not remove, the head of this queue, or returns `nil` - # if this queue is empty. - # - # @return [Object] the head of the queue or `nil` when empty - - # @!method pop - # @!macro priority_queue_method_pop - # - # Retrieves and removes the head of this queue, or returns `nil` if this - # queue is empty. - # - # @return [Object] the head of the queue or `nil` when empty - - # @!method push(item) - # @!macro priority_queue_method_push - # - # Inserts the specified element into this priority queue. - # - # @param [Object] item the item to insert onto the queue - - # @!method self.from_list(list, opts = {}) - # @!macro priority_queue_method_from_list - # - # Create a new priority queue from the given list. - # - # @param [Enumerable] list the list to build the queue from - # @param [Hash] opts the options for creating the queue - # - # @return [NonConcurrentPriorityQueue] the newly created and populated queue - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb deleted file mode 100644 index 322b4ac..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +++ /dev/null @@ -1,160 +0,0 @@ -module Concurrent - module Collection - - # @!macro priority_queue - # - # @!visibility private - # @!macro internal_implementation_note - class RubyNonConcurrentPriorityQueue - - # @!macro priority_queue_method_initialize - def initialize(opts = {}) - order = opts.fetch(:order, :max) - @comparator = [:min, :low].include?(order) ? -1 : 1 - clear - end - - # @!macro priority_queue_method_clear - def clear - @queue = [nil] - @length = 0 - true - end - - # @!macro priority_queue_method_delete - def delete(item) - return false if empty? - original_length = @length - k = 1 - while k <= @length - if @queue[k] == item - swap(k, @length) - @length -= 1 - sink(k) || swim(k) - @queue.pop - else - k += 1 - end - end - @length != original_length - end - - # @!macro priority_queue_method_empty - def empty? - size == 0 - end - - # @!macro priority_queue_method_include - def include?(item) - @queue.include?(item) - end - alias_method :has_priority?, :include? - - # @!macro priority_queue_method_length - def length - @length - end - alias_method :size, :length - - # @!macro priority_queue_method_peek - def peek - empty? ? nil : @queue[1] - end - - # @!macro priority_queue_method_pop - def pop - return nil if empty? - max = @queue[1] - swap(1, @length) - @length -= 1 - sink(1) - @queue.pop - max - end - alias_method :deq, :pop - alias_method :shift, :pop - - # @!macro priority_queue_method_push - def push(item) - raise ArgumentError.new('cannot enqueue nil') if item.nil? - @length += 1 - @queue << item - swim(@length) - true - end - alias_method :<<, :push - alias_method :enq, :push - - # @!macro priority_queue_method_from_list - def self.from_list(list, opts = {}) - queue = new(opts) - list.each{|item| queue << item } - queue - end - - private - - # Exchange the values at the given indexes within the internal array. - # - # @param [Integer] x the first index to swap - # @param [Integer] y the second index to swap - # - # @!visibility private - def swap(x, y) - temp = @queue[x] - @queue[x] = @queue[y] - @queue[y] = temp - end - - # Are the items at the given indexes ordered based on the priority - # order specified at construction? - # - # @param [Integer] x the first index from which to retrieve a comparable value - # @param [Integer] y the second index from which to retrieve a comparable value - # - # @return [Boolean] true if the two elements are in the correct priority order - # else false - # - # @!visibility private - def ordered?(x, y) - (@queue[x] <=> @queue[y]) == @comparator - end - - # Percolate down to maintain heap invariant. - # - # @param [Integer] k the index at which to start the percolation - # - # @!visibility private - def sink(k) - success = false - - while (j = (2 * k)) <= @length do - j += 1 if j < @length && ! ordered?(j, j+1) - break if ordered?(k, j) - swap(k, j) - success = true - k = j - end - - success - end - - # Percolate up to maintain heap invariant. - # - # @param [Integer] k the index at which to start the percolation - # - # @!visibility private - def swim(k) - success = false - - while k > 1 && ! ordered?(k/2, k) do - swap(k, k/2) - k = k/2 - success = true - end - - success - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/deprecation.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/deprecation.rb deleted file mode 100644 index 35ae4b2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/deprecation.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'concurrent/concern/logging' - -module Concurrent - module Concern - - # @!visibility private - # @!macro internal_implementation_note - module Deprecation - # TODO require additional parameter: a version. Display when it'll be removed based on that. Error if not removed. - include Concern::Logging - - def deprecated(message, strip = 2) - caller_line = caller(strip).first if strip > 0 - klass = if Module === self - self - else - self.class - end - message = if strip > 0 - format("[DEPRECATED] %s\ncalled on: %s", message, caller_line) - else - format('[DEPRECATED] %s', message) - end - log WARN, klass.to_s, message - end - - def deprecated_method(old_name, new_name) - deprecated "`#{old_name}` is deprecated and it'll removed in next release, use `#{new_name}` instead", 3 - end - - extend self - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb deleted file mode 100644 index dc172ba..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb +++ /dev/null @@ -1,73 +0,0 @@ -module Concurrent - module Concern - - # Object references in Ruby are mutable. This can lead to serious problems when - # the `#value` of a concurrent object is a mutable reference. Which is always the - # case unless the value is a `Fixnum`, `Symbol`, or similar "primitive" data type. - # Most classes in this library that expose a `#value` getter method do so using the - # `Dereferenceable` mixin module. - # - # @!macro copy_options - module Dereferenceable - # NOTE: This module is going away in 2.0. In the mean time we need it to - # play nicely with the synchronization layer. This means that the - # including class SHOULD be synchronized and it MUST implement a - # `#synchronize` method. Not doing so will lead to runtime errors. - - # Return the value this object represents after applying the options specified - # by the `#set_deref_options` method. - # - # @return [Object] the current value of the object - def value - synchronize { apply_deref_options(@value) } - end - alias_method :deref, :value - - protected - - # Set the internal value of this object - # - # @param [Object] value the new value - def value=(value) - synchronize{ @value = value } - end - - # @!macro dereferenceable_set_deref_options - # Set the options which define the operations #value performs before - # returning data to the caller (dereferencing). - # - # @note Most classes that include this module will call `#set_deref_options` - # from within the constructor, thus allowing these options to be set at - # object creation. - # - # @param [Hash] opts the options defining dereference behavior. - # @option opts [String] :dup_on_deref (false) call `#dup` before returning the data - # @option opts [String] :freeze_on_deref (false) call `#freeze` before returning the data - # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing - # the internal value and returning the value returned from the proc - def set_deref_options(opts = {}) - synchronize{ ns_set_deref_options(opts) } - end - - # @!macro dereferenceable_set_deref_options - # @!visibility private - def ns_set_deref_options(opts) - @dup_on_deref = opts[:dup_on_deref] || opts[:dup] - @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze] - @copy_on_deref = opts[:copy_on_deref] || opts[:copy] - @do_nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref) - nil - end - - # @!visibility private - def apply_deref_options(value) - return nil if value.nil? - return value if @do_nothing_on_deref - value = @copy_on_deref.call(value) if @copy_on_deref - value = value.dup if @dup_on_deref - value = value.freeze if @freeze_on_deref - value - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/logging.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/logging.rb deleted file mode 100644 index 568a539..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/logging.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'logger' -require 'concurrent/atomic/atomic_reference' - -module Concurrent - module Concern - - # Include where logging is needed - # - # @!visibility private - module Logging - include Logger::Severity - - # Logs through {Concurrent.global_logger}, it can be overridden by setting @logger - # @param [Integer] level one of Logger::Severity constants - # @param [String] progname e.g. a path of an Actor - # @param [String, nil] message when nil block is used to generate the message - # @yieldreturn [String] a message - def log(level, progname, message = nil, &block) - logger = if defined?(@logger) && @logger - @logger - else - Concurrent.global_logger - end - logger.call level, progname, message, &block - rescue => error - $stderr.puts "`Concurrent.configuration.logger` failed to log #{[level, progname, message, block]}\n" + - "#{error.message} (#{error.class})\n#{error.backtrace.join "\n"}" - end - end - end -end - -module Concurrent - extend Concern::Logging - - # @return [Logger] Logger with provided level and output. - def self.create_simple_logger(level = Logger::FATAL, output = $stderr) - # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking - lambda do |severity, progname, message = nil, &block| - return false if severity < level - - message = block ? block.call : message - formatted_message = case message - when String - message - when Exception - format "%s (%s)\n%s", - message.message, message.class, (message.backtrace || []).join("\n") - else - message.inspect - end - - output.print format "[%s] %5s -- %s: %s\n", - Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'), - Logger::SEV_LABEL[severity], - progname, - formatted_message - true - end - end - - # Use logger created by #create_simple_logger to log concurrent-ruby messages. - def self.use_simple_logger(level = Logger::FATAL, output = $stderr) - Concurrent.global_logger = create_simple_logger level, output - end - - # @return [Logger] Logger with provided level and output. - # @deprecated - def self.create_stdlib_logger(level = Logger::FATAL, output = $stderr) - logger = Logger.new(output) - logger.level = level - logger.formatter = lambda do |severity, datetime, progname, msg| - formatted_message = case msg - when String - msg - when Exception - format "%s (%s)\n%s", - msg.message, msg.class, (msg.backtrace || []).join("\n") - else - msg.inspect - end - format "[%s] %5s -- %s: %s\n", - datetime.strftime('%Y-%m-%d %H:%M:%S.%L'), - severity, - progname, - formatted_message - end - - lambda do |loglevel, progname, message = nil, &block| - logger.add loglevel, message, progname, &block - end - end - - # Use logger created by #create_stdlib_logger to log concurrent-ruby messages. - # @deprecated - def self.use_stdlib_logger(level = Logger::FATAL, output = $stderr) - Concurrent.global_logger = create_stdlib_logger level, output - end - - # TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods - - # Suppresses all output when used for logging. - NULL_LOGGER = lambda { |level, progname, message = nil, &block| } - - # @!visibility private - GLOBAL_LOGGER = AtomicReference.new(create_simple_logger(Logger::WARN)) - private_constant :GLOBAL_LOGGER - - def self.global_logger - GLOBAL_LOGGER.value - end - - def self.global_logger=(value) - GLOBAL_LOGGER.value = value - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/obligation.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/obligation.rb deleted file mode 100644 index 2c9ac12..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/obligation.rb +++ /dev/null @@ -1,220 +0,0 @@ -require 'thread' -require 'timeout' - -require 'concurrent/atomic/event' -require 'concurrent/concern/dereferenceable' - -module Concurrent - module Concern - - module Obligation - include Concern::Dereferenceable - # NOTE: The Dereferenceable module is going away in 2.0. In the mean time - # we need it to place nicely with the synchronization layer. This means - # that the including class SHOULD be synchronized and it MUST implement a - # `#synchronize` method. Not doing so will lead to runtime errors. - - # Has the obligation been fulfilled? - # - # @return [Boolean] - def fulfilled? - state == :fulfilled - end - alias_method :realized?, :fulfilled? - - # Has the obligation been rejected? - # - # @return [Boolean] - def rejected? - state == :rejected - end - - # Is obligation completion still pending? - # - # @return [Boolean] - def pending? - state == :pending - end - - # Is the obligation still unscheduled? - # - # @return [Boolean] - def unscheduled? - state == :unscheduled - end - - # Has the obligation completed processing? - # - # @return [Boolean] - def complete? - [:fulfilled, :rejected].include? state - end - - # Is the obligation still awaiting completion of processing? - # - # @return [Boolean] - def incomplete? - ! complete? - end - - # The current value of the obligation. Will be `nil` while the state is - # pending or the operation has been rejected. - # - # @param [Numeric] timeout the maximum time in seconds to wait. - # @return [Object] see Dereferenceable#deref - def value(timeout = nil) - wait timeout - deref - end - - # Wait until obligation is complete or the timeout has been reached. - # - # @param [Numeric] timeout the maximum time in seconds to wait. - # @return [Obligation] self - def wait(timeout = nil) - event.wait(timeout) if timeout != 0 && incomplete? - self - end - - # Wait until obligation is complete or the timeout is reached. Will re-raise - # any exceptions raised during processing (but will not raise an exception - # on timeout). - # - # @param [Numeric] timeout the maximum time in seconds to wait. - # @return [Obligation] self - # @raise [Exception] raises the reason when rejected - def wait!(timeout = nil) - wait(timeout).tap { raise self if rejected? } - end - alias_method :no_error!, :wait! - - # The current value of the obligation. Will be `nil` while the state is - # pending or the operation has been rejected. Will re-raise any exceptions - # raised during processing (but will not raise an exception on timeout). - # - # @param [Numeric] timeout the maximum time in seconds to wait. - # @return [Object] see Dereferenceable#deref - # @raise [Exception] raises the reason when rejected - def value!(timeout = nil) - wait(timeout) - if rejected? - raise self - else - deref - end - end - - # The current state of the obligation. - # - # @return [Symbol] the current state - def state - synchronize { @state } - end - - # If an exception was raised during processing this will return the - # exception object. Will return `nil` when the state is pending or if - # the obligation has been successfully fulfilled. - # - # @return [Exception] the exception raised during processing or `nil` - def reason - synchronize { @reason } - end - - # @example allows Obligation to be risen - # rejected_ivar = Ivar.new.fail - # raise rejected_ivar - def exception(*args) - raise 'obligation is not rejected' unless rejected? - reason.exception(*args) - end - - protected - - # @!visibility private - def get_arguments_from(opts = {}) - [*opts.fetch(:args, [])] - end - - # @!visibility private - def init_obligation - @event = Event.new - @value = @reason = nil - end - - # @!visibility private - def event - @event - end - - # @!visibility private - def set_state(success, value, reason) - if success - @value = value - @state = :fulfilled - else - @reason = reason - @state = :rejected - end - end - - # @!visibility private - def state=(value) - synchronize { ns_set_state(value) } - end - - # Atomic compare and set operation - # State is set to `next_state` only if `current state == expected_current`. - # - # @param [Symbol] next_state - # @param [Symbol] expected_current - # - # @return [Boolean] true is state is changed, false otherwise - # - # @!visibility private - def compare_and_set_state(next_state, *expected_current) - synchronize do - if expected_current.include? @state - @state = next_state - true - else - false - end - end - end - - # Executes the block within mutex if current state is included in expected_states - # - # @return block value if executed, false otherwise - # - # @!visibility private - def if_state(*expected_states) - synchronize do - raise ArgumentError.new('no block given') unless block_given? - - if expected_states.include? @state - yield - else - false - end - end - end - - protected - - # Am I in the current state? - # - # @param [Symbol] expected The state to check against - # @return [Boolean] true if in the expected state else false - # - # @!visibility private - def ns_check_state?(expected) - @state == expected - end - - # @!visibility private - def ns_set_state(value) - @state = value - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/observable.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/observable.rb deleted file mode 100644 index b513271..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concern/observable.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'concurrent/collection/copy_on_notify_observer_set' -require 'concurrent/collection/copy_on_write_observer_set' - -module Concurrent - module Concern - - # The [observer pattern](http://en.wikipedia.org/wiki/Observer_pattern) is one - # of the most useful design patterns. - # - # The workflow is very simple: - # - an `observer` can register itself to a `subject` via a callback - # - many `observers` can be registered to the same `subject` - # - the `subject` notifies all registered observers when its status changes - # - an `observer` can deregister itself when is no more interested to receive - # event notifications - # - # In a single threaded environment the whole pattern is very easy: the - # `subject` can use a simple data structure to manage all its subscribed - # `observer`s and every `observer` can react directly to every event without - # caring about synchronization. - # - # In a multi threaded environment things are more complex. The `subject` must - # synchronize the access to its data structure and to do so currently we're - # using two specialized ObserverSet: {Concurrent::Concern::CopyOnWriteObserverSet} - # and {Concurrent::Concern::CopyOnNotifyObserverSet}. - # - # When implementing and `observer` there's a very important rule to remember: - # **there are no guarantees about the thread that will execute the callback** - # - # Let's take this example - # ``` - # class Observer - # def initialize - # @count = 0 - # end - # - # def update - # @count += 1 - # end - # end - # - # obs = Observer.new - # [obj1, obj2, obj3, obj4].each { |o| o.add_observer(obs) } - # # execute [obj1, obj2, obj3, obj4] - # ``` - # - # `obs` is wrong because the variable `@count` can be accessed by different - # threads at the same time, so it should be synchronized (using either a Mutex - # or an AtomicFixum) - module Observable - - # @!macro observable_add_observer - # - # Adds an observer to this set. If a block is passed, the observer will be - # created by this method and no other params should be passed. - # - # @param [Object] observer the observer to add - # @param [Symbol] func the function to call on the observer during notification. - # Default is :update - # @return [Object] the added observer - def add_observer(observer = nil, func = :update, &block) - observers.add_observer(observer, func, &block) - end - - # As `#add_observer` but can be used for chaining. - # - # @param [Object] observer the observer to add - # @param [Symbol] func the function to call on the observer during notification. - # @return [Observable] self - def with_observer(observer = nil, func = :update, &block) - add_observer(observer, func, &block) - self - end - - # @!macro observable_delete_observer - # - # Remove `observer` as an observer on this object so that it will no - # longer receive notifications. - # - # @param [Object] observer the observer to remove - # @return [Object] the deleted observer - def delete_observer(observer) - observers.delete_observer(observer) - end - - # @!macro observable_delete_observers - # - # Remove all observers associated with this object. - # - # @return [Observable] self - def delete_observers - observers.delete_observers - self - end - - # @!macro observable_count_observers - # - # Return the number of observers associated with this object. - # - # @return [Integer] the observers count - def count_observers - observers.count_observers - end - - protected - - attr_accessor :observers - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concurrent_ruby.jar b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concurrent_ruby.jar deleted file mode 100644 index c0d7b15..0000000 Binary files a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/concurrent_ruby.jar and /dev/null differ diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/configuration.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/configuration.rb deleted file mode 100644 index 5571d39..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/configuration.rb +++ /dev/null @@ -1,105 +0,0 @@ -require 'thread' -require 'concurrent/delay' -require 'concurrent/errors' -require 'concurrent/concern/deprecation' -require 'concurrent/executor/immediate_executor' -require 'concurrent/executor/fixed_thread_pool' -require 'concurrent/executor/cached_thread_pool' -require 'concurrent/utility/processor_counter' - -module Concurrent - extend Concern::Deprecation - - autoload :Options, 'concurrent/options' - autoload :TimerSet, 'concurrent/executor/timer_set' - autoload :ThreadPoolExecutor, 'concurrent/executor/thread_pool_executor' - - # @!visibility private - GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor } - private_constant :GLOBAL_FAST_EXECUTOR - - # @!visibility private - GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor } - private_constant :GLOBAL_IO_EXECUTOR - - # @!visibility private - GLOBAL_TIMER_SET = Delay.new { TimerSet.new } - private_constant :GLOBAL_TIMER_SET - - # @!visibility private - GLOBAL_IMMEDIATE_EXECUTOR = ImmediateExecutor.new - private_constant :GLOBAL_IMMEDIATE_EXECUTOR - - # Disables AtExit handlers including pool auto-termination handlers. - # When disabled it will be the application programmer's responsibility - # to ensure that the handlers are shutdown properly prior to application - # exit by calling `AtExit.run` method. - # - # @note this option should be needed only because of `at_exit` ordering - # issues which may arise when running some of the testing frameworks. - # E.g. Minitest's test-suite runs itself in `at_exit` callback which - # executes after the pools are already terminated. Then auto termination - # needs to be disabled and called manually after test-suite ends. - # @note This method should *never* be called - # from within a gem. It should *only* be used from within the main - # application and even then it should be used only when necessary. - # @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841. - # - def self.disable_at_exit_handlers! - deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841." - end - - # Global thread pool optimized for short, fast *operations*. - # - # @return [ThreadPoolExecutor] the thread pool - def self.global_fast_executor - GLOBAL_FAST_EXECUTOR.value! - end - - # Global thread pool optimized for long, blocking (IO) *tasks*. - # - # @return [ThreadPoolExecutor] the thread pool - def self.global_io_executor - GLOBAL_IO_EXECUTOR.value! - end - - def self.global_immediate_executor - GLOBAL_IMMEDIATE_EXECUTOR - end - - # Global thread pool user for global *timers*. - # - # @return [Concurrent::TimerSet] the thread pool - def self.global_timer_set - GLOBAL_TIMER_SET.value! - end - - # General access point to global executors. - # @param [Symbol, Executor] executor_identifier symbols: - # - :fast - {Concurrent.global_fast_executor} - # - :io - {Concurrent.global_io_executor} - # - :immediate - {Concurrent.global_immediate_executor} - # @return [Executor] - def self.executor(executor_identifier) - Options.executor(executor_identifier) - end - - def self.new_fast_executor(opts = {}) - FixedThreadPool.new( - [2, Concurrent.processor_count].max, - auto_terminate: opts.fetch(:auto_terminate, true), - idletime: 60, # 1 minute - max_queue: 0, # unlimited - fallback_policy: :abort, # shouldn't matter -- 0 max queue - name: "fast" - ) - end - - def self.new_io_executor(opts = {}) - CachedThreadPool.new( - auto_terminate: opts.fetch(:auto_terminate, true), - fallback_policy: :abort, # shouldn't matter -- 0 max queue - name: "io" - ) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/constants.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/constants.rb deleted file mode 100644 index 676c2af..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/constants.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Concurrent - - # Various classes within allows for +nil+ values to be stored, - # so a special +NULL+ token is required to indicate the "nil-ness". - # @!visibility private - NULL = ::Object.new - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/dataflow.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/dataflow.rb deleted file mode 100644 index d55f19d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/dataflow.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'concurrent/future' -require 'concurrent/atomic/atomic_fixnum' - -module Concurrent - - # @!visibility private - class DependencyCounter # :nodoc: - - def initialize(count, &block) - @counter = AtomicFixnum.new(count) - @block = block - end - - def update(time, value, reason) - if @counter.decrement == 0 - @block.call - end - end - end - - # Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available. - # {include:file:docs-source/dataflow.md} - # - # @param [Future] inputs zero or more `Future` operations that this dataflow depends upon - # - # @yield The operation to perform once all the dependencies are met - # @yieldparam [Future] inputs each of the `Future` inputs to the dataflow - # @yieldreturn [Object] the result of the block operation - # - # @return [Object] the result of all the operations - # - # @raise [ArgumentError] if no block is given - # @raise [ArgumentError] if any of the inputs are not `IVar`s - def dataflow(*inputs, &block) - dataflow_with(Concurrent.global_io_executor, *inputs, &block) - end - module_function :dataflow - - def dataflow_with(executor, *inputs, &block) - call_dataflow(:value, executor, *inputs, &block) - end - module_function :dataflow_with - - def dataflow!(*inputs, &block) - dataflow_with!(Concurrent.global_io_executor, *inputs, &block) - end - module_function :dataflow! - - def dataflow_with!(executor, *inputs, &block) - call_dataflow(:value!, executor, *inputs, &block) - end - module_function :dataflow_with! - - private - - def call_dataflow(method, executor, *inputs, &block) - raise ArgumentError.new('an executor must be provided') if executor.nil? - raise ArgumentError.new('no block given') unless block_given? - unless inputs.all? { |input| input.is_a? IVar } - raise ArgumentError.new("Not all dependencies are IVars.\nDependencies: #{ inputs.inspect }") - end - - result = Future.new(executor: executor) do - values = inputs.map { |input| input.send(method) } - block.call(*values) - end - - if inputs.empty? - result.execute - else - counter = DependencyCounter.new(inputs.size) { result.execute } - - inputs.each do |input| - input.add_observer counter - end - end - - result - end - module_function :call_dataflow -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/delay.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/delay.rb deleted file mode 100644 index 923773c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/delay.rb +++ /dev/null @@ -1,199 +0,0 @@ -require 'thread' -require 'concurrent/concern/obligation' -require 'concurrent/executor/immediate_executor' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # This file has circular require issues. It must be autoloaded here. - autoload :Options, 'concurrent/options' - - # Lazy evaluation of a block yielding an immutable result. Useful for - # expensive operations that may never be needed. It may be non-blocking, - # supports the `Concern::Obligation` interface, and accepts the injection of - # custom executor upon which to execute the block. Processing of - # block will be deferred until the first time `#value` is called. - # At that time the caller can choose to return immediately and let - # the block execute asynchronously, block indefinitely, or block - # with a timeout. - # - # When a `Delay` is created its state is set to `pending`. The value and - # reason are both `nil`. The first time the `#value` method is called the - # enclosed opration will be run and the calling thread will block. Other - # threads attempting to call `#value` will block as well. Once the operation - # is complete the *value* will be set to the result of the operation or the - # *reason* will be set to the raised exception, as appropriate. All threads - # blocked on `#value` will return. Subsequent calls to `#value` will immediately - # return the cached value. The operation will only be run once. This means that - # any side effects created by the operation will only happen once as well. - # - # `Delay` includes the `Concurrent::Concern::Dereferenceable` mixin to support thread - # safety of the reference returned by `#value`. - # - # @!macro copy_options - # - # @!macro delay_note_regarding_blocking - # @note The default behavior of `Delay` is to block indefinitely when - # calling either `value` or `wait`, executing the delayed operation on - # the current thread. This makes the `timeout` value completely - # irrelevant. To enable non-blocking behavior, use the `executor` - # constructor option. This will cause the delayed operation to be - # execute on the given executor, allowing the call to timeout. - # - # @see Concurrent::Concern::Dereferenceable - class Delay < Synchronization::LockableObject - include Concern::Obligation - - # NOTE: Because the global thread pools are lazy-loaded with these objects - # there is a performance hit every time we post a new task to one of these - # thread pools. Subsequently it is critical that `Delay` perform as fast - # as possible post-completion. This class has been highly optimized using - # the benchmark script `examples/lazy_and_delay.rb`. Do NOT attempt to - # DRY-up this class or perform other refactoring with running the - # benchmarks and ensuring that performance is not negatively impacted. - - # Create a new `Delay` in the `:pending` state. - # - # @!macro executor_and_deref_options - # - # @yield the delayed operation to perform - # - # @raise [ArgumentError] if no block is given - def initialize(opts = {}, &block) - raise ArgumentError.new('no block given') unless block_given? - super(&nil) - synchronize { ns_initialize(opts, &block) } - end - - # Return the value this object represents after applying the options - # specified by the `#set_deref_options` method. If the delayed operation - # raised an exception this method will return nil. The exception object - # can be accessed via the `#reason` method. - # - # @param [Numeric] timeout the maximum number of seconds to wait - # @return [Object] the current value of the object - # - # @!macro delay_note_regarding_blocking - def value(timeout = nil) - if @executor # TODO (pitr 12-Sep-2015): broken unsafe read? - super - else - # this function has been optimized for performance and - # should not be modified without running new benchmarks - synchronize do - execute = @evaluation_started = true unless @evaluation_started - if execute - begin - set_state(true, @task.call, nil) - rescue => ex - set_state(false, nil, ex) - end - elsif incomplete? - raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay' - end - end - if @do_nothing_on_deref - @value - else - apply_deref_options(@value) - end - end - end - - # Return the value this object represents after applying the options - # specified by the `#set_deref_options` method. If the delayed operation - # raised an exception, this method will raise that exception (even when) - # the operation has already been executed). - # - # @param [Numeric] timeout the maximum number of seconds to wait - # @return [Object] the current value of the object - # @raise [Exception] when `#rejected?` raises `#reason` - # - # @!macro delay_note_regarding_blocking - def value!(timeout = nil) - if @executor - super - else - result = value - raise @reason if @reason - result - end - end - - # Return the value this object represents after applying the options - # specified by the `#set_deref_options` method. - # - # @param [Integer] timeout (nil) the maximum number of seconds to wait for - # the value to be computed. When `nil` the caller will block indefinitely. - # - # @return [Object] self - # - # @!macro delay_note_regarding_blocking - def wait(timeout = nil) - if @executor - execute_task_once - super(timeout) - else - value - end - self - end - - # Reconfigures the block returning the value if still `#incomplete?` - # - # @yield the delayed operation to perform - # @return [true, false] if success - def reconfigure(&block) - synchronize do - raise ArgumentError.new('no block given') unless block_given? - unless @evaluation_started - @task = block - true - else - false - end - end - end - - protected - - def ns_initialize(opts, &block) - init_obligation - set_deref_options(opts) - @executor = opts[:executor] - - @task = block - @state = :pending - @evaluation_started = false - end - - private - - # @!visibility private - def execute_task_once # :nodoc: - # this function has been optimized for performance and - # should not be modified without running new benchmarks - execute = task = nil - synchronize do - execute = @evaluation_started = true unless @evaluation_started - task = @task - end - - if execute - executor = Options.executor_from_options(executor: @executor) - executor.post do - begin - result = task.call - success = true - rescue => ex - reason = ex - end - synchronize do - set_state(success, result, reason) - event.set - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/errors.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/errors.rb deleted file mode 100644 index 74f1fc3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/errors.rb +++ /dev/null @@ -1,74 +0,0 @@ -module Concurrent - - Error = Class.new(StandardError) - - # Raised when errors occur during configuration. - ConfigurationError = Class.new(Error) - - # Raised when an asynchronous operation is cancelled before execution. - CancelledOperationError = Class.new(Error) - - # Raised when a lifecycle method (such as `stop`) is called in an improper - # sequence or when the object is in an inappropriate state. - LifecycleError = Class.new(Error) - - # Raised when an attempt is made to violate an immutability guarantee. - ImmutabilityError = Class.new(Error) - - # Raised when an operation is attempted which is not legal given the - # receiver's current state - IllegalOperationError = Class.new(Error) - - # Raised when an object's methods are called when it has not been - # properly initialized. - InitializationError = Class.new(Error) - - # Raised when an object with a start/stop lifecycle has been started an - # excessive number of times. Often used in conjunction with a restart - # policy or strategy. - MaxRestartFrequencyError = Class.new(Error) - - # Raised when an attempt is made to modify an immutable object - # (such as an `IVar`) after its final state has been set. - class MultipleAssignmentError < Error - attr_reader :inspection_data - - def initialize(message = nil, inspection_data = nil) - @inspection_data = inspection_data - super message - end - - def inspect - format '%s %s>', super[0..-2], @inspection_data.inspect - end - end - - # Raised by an `Executor` when it is unable to process a given task, - # possibly because of a reject policy or other internal error. - RejectedExecutionError = Class.new(Error) - - # Raised when any finite resource, such as a lock counter, exceeds its - # maximum limit/threshold. - ResourceLimitError = Class.new(Error) - - # Raised when an operation times out. - TimeoutError = Class.new(Error) - - # Aggregates multiple exceptions. - class MultipleErrors < Error - attr_reader :errors - - def initialize(errors, message = "#{errors.size} errors") - @errors = errors - super [*message, - *errors.map { |e| [format('%s (%s)', e.message, e.class), *e.backtrace] }.flatten(1) - ].join("\n") - end - end - - # @!macro internal_implementation_note - class ConcurrentUpdateError < ThreadError - # frozen pre-allocated backtrace to speed ConcurrentUpdateError - CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/exchanger.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/exchanger.rb deleted file mode 100644 index a5405d2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/exchanger.rb +++ /dev/null @@ -1,353 +0,0 @@ -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/maybe' -require 'concurrent/atomic/atomic_reference' -require 'concurrent/atomic/count_down_latch' -require 'concurrent/utility/engine' -require 'concurrent/utility/monotonic_time' - -module Concurrent - - # @!macro exchanger - # - # A synchronization point at which threads can pair and swap elements within - # pairs. Each thread presents some object on entry to the exchange method, - # matches with a partner thread, and receives its partner's object on return. - # - # @!macro thread_safe_variable_comparison - # - # This implementation is very simple, using only a single slot for each - # exchanger (unlike more advanced implementations which use an "arena"). - # This approach will work perfectly fine when there are only a few threads - # accessing a single `Exchanger`. Beyond a handful of threads the performance - # will degrade rapidly due to contention on the single slot, but the algorithm - # will remain correct. - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html java.util.concurrent.Exchanger - # @example - # - # exchanger = Concurrent::Exchanger.new - # - # threads = [ - # Thread.new { puts "first: " << exchanger.exchange('foo', 1) }, #=> "first: bar" - # Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo" - # ] - # threads.each {|t| t.join(2) } - - # @!visibility private - class AbstractExchanger < Synchronization::Object - - # @!visibility private - CANCEL = ::Object.new - private_constant :CANCEL - - def initialize - super - end - - # @!macro exchanger_method_do_exchange - # - # Waits for another thread to arrive at this exchange point (unless the - # current thread is interrupted), and then transfers the given object to - # it, receiving its object in return. The timeout value indicates the - # approximate number of seconds the method should block while waiting - # for the exchange. When the timeout value is `nil` the method will - # block indefinitely. - # - # @param [Object] value the value to exchange with another thread - # @param [Numeric, nil] timeout in seconds, `nil` blocks indefinitely - # - # @!macro exchanger_method_exchange - # - # In some edge cases when a `timeout` is given a return value of `nil` may be - # ambiguous. Specifically, if `nil` is a valid value in the exchange it will - # be impossible to tell whether `nil` is the actual return value or if it - # signifies timeout. When `nil` is a valid value in the exchange consider - # using {#exchange!} or {#try_exchange} instead. - # - # @return [Object] the value exchanged by the other thread or `nil` on timeout - def exchange(value, timeout = nil) - (value = do_exchange(value, timeout)) == CANCEL ? nil : value - end - - # @!macro exchanger_method_do_exchange - # @!macro exchanger_method_exchange_bang - # - # On timeout a {Concurrent::TimeoutError} exception will be raised. - # - # @return [Object] the value exchanged by the other thread - # @raise [Concurrent::TimeoutError] on timeout - def exchange!(value, timeout = nil) - if (value = do_exchange(value, timeout)) == CANCEL - raise Concurrent::TimeoutError - else - value - end - end - - # @!macro exchanger_method_do_exchange - # @!macro exchanger_method_try_exchange - # - # The return value will be a {Concurrent::Maybe} set to `Just` on success or - # `Nothing` on timeout. - # - # @return [Concurrent::Maybe] on success a `Just` maybe will be returned with - # the item exchanged by the other thread as `#value`; on timeout a - # `Nothing` maybe will be returned with {Concurrent::TimeoutError} as `#reason` - # - # @example - # - # exchanger = Concurrent::Exchanger.new - # - # result = exchanger.exchange(:foo, 0.5) - # - # if result.just? - # puts result.value #=> :bar - # else - # puts 'timeout' - # end - def try_exchange(value, timeout = nil) - if (value = do_exchange(value, timeout)) == CANCEL - Concurrent::Maybe.nothing(Concurrent::TimeoutError) - else - Concurrent::Maybe.just(value) - end - end - - private - - # @!macro exchanger_method_do_exchange - # - # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout - def do_exchange(value, timeout) - raise NotImplementedError - end - end - - # @!macro internal_implementation_note - # @!visibility private - class RubyExchanger < AbstractExchanger - # A simplified version of java.util.concurrent.Exchanger written by - # Doug Lea, Bill Scherer, and Michael Scott with assistance from members - # of JCP JSR-166 Expert Group and released to the public domain. It does - # not include the arena or the multi-processor spin loops. - # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/Exchanger.java - - safe_initialization! - - class Node < Concurrent::Synchronization::Object - attr_atomic :value - safe_initialization! - - def initialize(item) - super() - @Item = item - @Latch = Concurrent::CountDownLatch.new - self.value = nil - end - - def latch - @Latch - end - - def item - @Item - end - end - private_constant :Node - - def initialize - super - end - - private - - attr_atomic(:slot) - - # @!macro exchanger_method_do_exchange - # - # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout - def do_exchange(value, timeout) - - # ALGORITHM - # - # From the original Java version: - # - # > The basic idea is to maintain a "slot", which is a reference to - # > a Node containing both an Item to offer and a "hole" waiting to - # > get filled in. If an incoming "occupying" thread sees that the - # > slot is null, it CAS'es (compareAndSets) a Node there and waits - # > for another to invoke exchange. That second "fulfilling" thread - # > sees that the slot is non-null, and so CASes it back to null, - # > also exchanging items by CASing the hole, plus waking up the - # > occupying thread if it is blocked. In each case CAS'es may - # > fail because a slot at first appears non-null but is null upon - # > CAS, or vice-versa. So threads may need to retry these - # > actions. - # - # This version: - # - # An exchange occurs between an "occupier" thread and a "fulfiller" thread. - # The "slot" is used to setup this interaction. The first thread in the - # exchange puts itself into the slot (occupies) and waits for a fulfiller. - # The second thread removes the occupier from the slot and attempts to - # perform the exchange. Removing the occupier also frees the slot for - # another occupier/fulfiller pair. - # - # Because the occupier and the fulfiller are operating independently and - # because there may be contention with other threads, any failed operation - # indicates contention. Both the occupier and the fulfiller operate within - # spin loops. Any failed actions along the happy path will cause the thread - # to repeat the loop and try again. - # - # When a timeout value is given the thread must be cognizant of time spent - # in the spin loop. The remaining time is checked every loop. When the time - # runs out the thread will exit. - # - # A "node" is the data structure used to perform the exchange. Only the - # occupier's node is necessary. It's the node used for the exchange. - # Each node has an "item," a "hole" (self), and a "latch." The item is the - # node's initial value. It never changes. It's what the fulfiller returns on - # success. The occupier's hole is where the fulfiller put its item. It's the - # item that the occupier returns on success. The latch is used for synchronization. - # Because a thread may act as either an occupier or fulfiller (or possibly - # both in periods of high contention) every thread creates a node when - # the exchange method is first called. - # - # The following steps occur within the spin loop. If any actions fail - # the thread will loop and try again, so long as there is time remaining. - # If time runs out the thread will return CANCEL. - # - # Check the slot for an occupier: - # - # * If the slot is empty try to occupy - # * If the slot is full try to fulfill - # - # Attempt to occupy: - # - # * Attempt to CAS myself into the slot - # * Go to sleep and wait to be woken by a fulfiller - # * If the sleep is successful then the fulfiller completed its happy path - # - Return the value from my hole (the value given by the fulfiller) - # * When the sleep fails (time ran out) attempt to cancel the operation - # - Attempt to CAS myself out of the hole - # - If successful there is no contention - # - Return CANCEL - # - On failure, I am competing with a fulfiller - # - Attempt to CAS my hole to CANCEL - # - On success - # - Let the fulfiller deal with my cancel - # - Return CANCEL - # - On failure the fulfiller has completed its happy path - # - Return th value from my hole (the fulfiller's value) - # - # Attempt to fulfill: - # - # * Attempt to CAS the occupier out of the slot - # - On failure loop again - # * Attempt to CAS my item into the occupier's hole - # - On failure the occupier is trying to cancel - # - Loop again - # - On success we are on the happy path - # - Wake the sleeping occupier - # - Return the occupier's item - - value = NULL if value.nil? # The sentinel allows nil to be a valid value - me = Node.new(value) # create my node in case I need to occupy - end_at = Concurrent.monotonic_time + timeout.to_f # The time to give up - - result = loop do - other = slot - if other && compare_and_set_slot(other, nil) - # try to fulfill - if other.compare_and_set_value(nil, value) - # happy path - other.latch.count_down - break other.item - end - elsif other.nil? && compare_and_set_slot(nil, me) - # try to occupy - timeout = end_at - Concurrent.monotonic_time if timeout - if me.latch.wait(timeout) - # happy path - break me.value - else - # attempt to remove myself from the slot - if compare_and_set_slot(me, nil) - break CANCEL - elsif !me.compare_and_set_value(nil, CANCEL) - # I've failed to block the fulfiller - break me.value - end - end - end - break CANCEL if timeout && Concurrent.monotonic_time >= end_at - end - - result == NULL ? nil : result - end - end - - if Concurrent.on_jruby? - require 'concurrent/utility/native_extension_loader' - - # @!macro internal_implementation_note - # @!visibility private - class JavaExchanger < AbstractExchanger - - def initialize - @exchanger = java.util.concurrent.Exchanger.new - end - - private - - # @!macro exchanger_method_do_exchange - # - # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout - def do_exchange(value, timeout) - result = nil - if timeout.nil? - Synchronization::JRuby.sleep_interruptibly do - result = @exchanger.exchange(value) - end - else - Synchronization::JRuby.sleep_interruptibly do - result = @exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) - end - end - result - rescue java.util.concurrent.TimeoutException - CANCEL - end - end - end - - # @!visibility private - # @!macro internal_implementation_note - ExchangerImplementation = case - when Concurrent.on_jruby? - JavaExchanger - else - RubyExchanger - end - private_constant :ExchangerImplementation - - # @!macro exchanger - class Exchanger < ExchangerImplementation - - # @!method initialize - # Creates exchanger instance - - # @!method exchange(value, timeout = nil) - # @!macro exchanger_method_do_exchange - # @!macro exchanger_method_exchange - - # @!method exchange!(value, timeout = nil) - # @!macro exchanger_method_do_exchange - # @!macro exchanger_method_exchange_bang - - # @!method try_exchange(value, timeout = nil) - # @!macro exchanger_method_do_exchange - # @!macro exchanger_method_try_exchange - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb deleted file mode 100644 index ac42953..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +++ /dev/null @@ -1,131 +0,0 @@ -require 'concurrent/errors' -require 'concurrent/concern/deprecation' -require 'concurrent/executor/executor_service' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # @!macro abstract_executor_service_public_api - # @!visibility private - class AbstractExecutorService < Synchronization::LockableObject - include ExecutorService - include Concern::Deprecation - - # The set of possible fallback policies that may be set at thread pool creation. - FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze - - # @!macro executor_service_attr_reader_fallback_policy - attr_reader :fallback_policy - - attr_reader :name - - # Create a new thread pool. - def initialize(opts = {}, &block) - super(&nil) - synchronize do - @auto_terminate = opts.fetch(:auto_terminate, true) - @name = opts.fetch(:name) if opts.key?(:name) - ns_initialize(opts, &block) - end - end - - def to_s - name ? "#{super[0..-2]} name: #{name}>" : super - end - - # @!macro executor_service_method_shutdown - def shutdown - raise NotImplementedError - end - - # @!macro executor_service_method_kill - def kill - raise NotImplementedError - end - - # @!macro executor_service_method_wait_for_termination - def wait_for_termination(timeout = nil) - raise NotImplementedError - end - - # @!macro executor_service_method_running_question - def running? - synchronize { ns_running? } - end - - # @!macro executor_service_method_shuttingdown_question - def shuttingdown? - synchronize { ns_shuttingdown? } - end - - # @!macro executor_service_method_shutdown_question - def shutdown? - synchronize { ns_shutdown? } - end - - # @!macro executor_service_method_auto_terminate_question - def auto_terminate? - synchronize { @auto_terminate } - end - - # @!macro executor_service_method_auto_terminate_setter - def auto_terminate=(value) - deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized." - end - - private - - # Returns an action which executes the `fallback_policy` once the queue - # size reaches `max_queue`. The reason for the indirection of an action - # is so that the work can be deferred outside of synchronization. - # - # @param [Array] args the arguments to the task which is being handled. - # - # @!visibility private - def fallback_action(*args) - case fallback_policy - when :abort - lambda { raise RejectedExecutionError } - when :discard - lambda { false } - when :caller_runs - lambda { - begin - yield(*args) - rescue => ex - # let it fail - log DEBUG, ex - end - true - } - else - lambda { fail "Unknown fallback policy #{fallback_policy}" } - end - end - - def ns_execute(*args, &task) - raise NotImplementedError - end - - # @!macro executor_service_method_ns_shutdown_execution - # - # Callback method called when an orderly shutdown has completed. - # The default behavior is to signal all waiting threads. - def ns_shutdown_execution - # do nothing - end - - # @!macro executor_service_method_ns_kill_execution - # - # Callback method called when the executor has been killed. - # The default behavior is to do nothing. - def ns_kill_execution - # do nothing - end - - def ns_auto_terminate? - @auto_terminate - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb deleted file mode 100644 index de50ed1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/executor/thread_pool_executor' - -module Concurrent - - # A thread pool that dynamically grows and shrinks to fit the current workload. - # New threads are created as needed, existing threads are reused, and threads - # that remain idle for too long are killed and removed from the pool. These - # pools are particularly suited to applications that perform a high volume of - # short-lived tasks. - # - # On creation a `CachedThreadPool` has zero running threads. New threads are - # created on the pool as new operations are `#post`. The size of the pool - # will grow until `#max_length` threads are in the pool or until the number - # of threads exceeds the number of running and pending operations. When a new - # operation is post to the pool the first available idle thread will be tasked - # with the new operation. - # - # Should a thread crash for any reason the thread will immediately be removed - # from the pool. Similarly, threads which remain idle for an extended period - # of time will be killed and reclaimed. Thus these thread pools are very - # efficient at reclaiming unused resources. - # - # The API and behavior of this class are based on Java's `CachedThreadPool` - # - # @!macro thread_pool_options - class CachedThreadPool < ThreadPoolExecutor - - # @!macro cached_thread_pool_method_initialize - # - # Create a new thread pool. - # - # @param [Hash] opts the options defining pool behavior. - # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy - # - # @raise [ArgumentError] if `fallback_policy` is not a known policy - # - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool-- - def initialize(opts = {}) - defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT } - overrides = { min_threads: 0, - max_threads: DEFAULT_MAX_POOL_SIZE, - max_queue: DEFAULT_MAX_QUEUE_SIZE } - super(defaults.merge(opts).merge(overrides)) - end - - private - - # @!macro cached_thread_pool_method_initialize - # @!visibility private - def ns_initialize(opts) - super(opts) - if Concurrent.on_jruby? - @max_queue = 0 - @executor = java.util.concurrent.Executors.newCachedThreadPool( - DaemonThreadFactory.new(ns_auto_terminate?)) - @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new) - @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/executor_service.rb deleted file mode 100644 index 7e34491..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/executor_service.rb +++ /dev/null @@ -1,185 +0,0 @@ -require 'concurrent/concern/logging' - -module Concurrent - - ################################################################### - - # @!macro executor_service_method_post - # - # Submit a task to the executor for asynchronous processing. - # - # @param [Array] args zero or more arguments to be passed to the task - # - # @yield the asynchronous task to perform - # - # @return [Boolean] `true` if the task is queued, `false` if the executor - # is not running - # - # @raise [ArgumentError] if no task is given - - # @!macro executor_service_method_left_shift - # - # Submit a task to the executor for asynchronous processing. - # - # @param [Proc] task the asynchronous task to perform - # - # @return [self] returns itself - - # @!macro executor_service_method_can_overflow_question - # - # Does the task queue have a maximum size? - # - # @return [Boolean] True if the task queue has a maximum size else false. - - # @!macro executor_service_method_serialized_question - # - # Does this executor guarantee serialization of its operations? - # - # @return [Boolean] True if the executor guarantees that all operations - # will be post in the order they are received and no two operations may - # occur simultaneously. Else false. - - ################################################################### - - # @!macro executor_service_public_api - # - # @!method post(*args, &task) - # @!macro executor_service_method_post - # - # @!method <<(task) - # @!macro executor_service_method_left_shift - # - # @!method can_overflow? - # @!macro executor_service_method_can_overflow_question - # - # @!method serialized? - # @!macro executor_service_method_serialized_question - - ################################################################### - - # @!macro executor_service_attr_reader_fallback_policy - # @return [Symbol] The fallback policy in effect. Either `:abort`, `:discard`, or `:caller_runs`. - - # @!macro executor_service_method_shutdown - # - # Begin an orderly shutdown. Tasks already in the queue will be executed, - # but no new tasks will be accepted. Has no additional effect if the - # thread pool is not running. - - # @!macro executor_service_method_kill - # - # Begin an immediate shutdown. In-progress tasks will be allowed to - # complete but enqueued tasks will be dismissed and no new tasks - # will be accepted. Has no additional effect if the thread pool is - # not running. - - # @!macro executor_service_method_wait_for_termination - # - # Block until executor shutdown is complete or until `timeout` seconds have - # passed. - # - # @note Does not initiate shutdown or termination. Either `shutdown` or `kill` - # must be called before this method (or on another thread). - # - # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete - # - # @return [Boolean] `true` if shutdown complete or false on `timeout` - - # @!macro executor_service_method_running_question - # - # Is the executor running? - # - # @return [Boolean] `true` when running, `false` when shutting down or shutdown - - # @!macro executor_service_method_shuttingdown_question - # - # Is the executor shuttingdown? - # - # @return [Boolean] `true` when not running and not shutdown, else `false` - - # @!macro executor_service_method_shutdown_question - # - # Is the executor shutdown? - # - # @return [Boolean] `true` when shutdown, `false` when shutting down or running - - # @!macro executor_service_method_auto_terminate_question - # - # Is the executor auto-terminate when the application exits? - # - # @return [Boolean] `true` when auto-termination is enabled else `false`. - - # @!macro executor_service_method_auto_terminate_setter - # - # - # Set the auto-terminate behavior for this executor. - # @deprecated Has no effect - # @param [Boolean] value The new auto-terminate value to set for this executor. - # @return [Boolean] `true` when auto-termination is enabled else `false`. - - ################################################################### - - # @!macro abstract_executor_service_public_api - # - # @!macro executor_service_public_api - # - # @!attribute [r] fallback_policy - # @!macro executor_service_attr_reader_fallback_policy - # - # @!method shutdown - # @!macro executor_service_method_shutdown - # - # @!method kill - # @!macro executor_service_method_kill - # - # @!method wait_for_termination(timeout = nil) - # @!macro executor_service_method_wait_for_termination - # - # @!method running? - # @!macro executor_service_method_running_question - # - # @!method shuttingdown? - # @!macro executor_service_method_shuttingdown_question - # - # @!method shutdown? - # @!macro executor_service_method_shutdown_question - # - # @!method auto_terminate? - # @!macro executor_service_method_auto_terminate_question - # - # @!method auto_terminate=(value) - # @!macro executor_service_method_auto_terminate_setter - - ################################################################### - - # @!macro executor_service_public_api - # @!visibility private - module ExecutorService - include Concern::Logging - - # @!macro executor_service_method_post - def post(*args, &task) - raise NotImplementedError - end - - # @!macro executor_service_method_left_shift - def <<(task) - post(&task) - self - end - - # @!macro executor_service_method_can_overflow_question - # - # @note Always returns `false` - def can_overflow? - false - end - - # @!macro executor_service_method_serialized_question - # - # @note Always returns `false` - def serialized? - false - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb deleted file mode 100644 index 993c3f1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +++ /dev/null @@ -1,224 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/executor/thread_pool_executor' - -module Concurrent - - # @!macro thread_pool_executor_constant_default_max_pool_size - # Default maximum number of threads that will be created in the pool. - - # @!macro thread_pool_executor_constant_default_min_pool_size - # Default minimum number of threads that will be retained in the pool. - - # @!macro thread_pool_executor_constant_default_max_queue_size - # Default maximum number of tasks that may be added to the task queue. - - # @!macro thread_pool_executor_constant_default_thread_timeout - # Default maximum number of seconds a thread in the pool may remain idle - # before being reclaimed. - - # @!macro thread_pool_executor_constant_default_synchronous - # Default value of the :synchronous option. - - # @!macro thread_pool_executor_attr_reader_max_length - # The maximum number of threads that may be created in the pool. - # @return [Integer] The maximum number of threads that may be created in the pool. - - # @!macro thread_pool_executor_attr_reader_min_length - # The minimum number of threads that may be retained in the pool. - # @return [Integer] The minimum number of threads that may be retained in the pool. - - # @!macro thread_pool_executor_attr_reader_largest_length - # The largest number of threads that have been created in the pool since construction. - # @return [Integer] The largest number of threads that have been created in the pool since construction. - - # @!macro thread_pool_executor_attr_reader_scheduled_task_count - # The number of tasks that have been scheduled for execution on the pool since construction. - # @return [Integer] The number of tasks that have been scheduled for execution on the pool since construction. - - # @!macro thread_pool_executor_attr_reader_completed_task_count - # The number of tasks that have been completed by the pool since construction. - # @return [Integer] The number of tasks that have been completed by the pool since construction. - - # @!macro thread_pool_executor_method_active_count - # The number of threads that are actively executing tasks. - # @return [Integer] The number of threads that are actively executing tasks. - - # @!macro thread_pool_executor_attr_reader_idletime - # The number of seconds that a thread may be idle before being reclaimed. - # @return [Integer] The number of seconds that a thread may be idle before being reclaimed. - - # @!macro thread_pool_executor_attr_reader_synchronous - # Whether or not a value of 0 for :max_queue option means the queue must perform direct hand-off or rather unbounded queue. - # @return [true, false] - - # @!macro thread_pool_executor_attr_reader_max_queue - # The maximum number of tasks that may be waiting in the work queue at any one time. - # When the queue size reaches `max_queue` subsequent tasks will be rejected in - # accordance with the configured `fallback_policy`. - # - # @return [Integer] The maximum number of tasks that may be waiting in the work queue at any one time. - # When the queue size reaches `max_queue` subsequent tasks will be rejected in - # accordance with the configured `fallback_policy`. - - # @!macro thread_pool_executor_attr_reader_length - # The number of threads currently in the pool. - # @return [Integer] The number of threads currently in the pool. - - # @!macro thread_pool_executor_attr_reader_queue_length - # The number of tasks in the queue awaiting execution. - # @return [Integer] The number of tasks in the queue awaiting execution. - - # @!macro thread_pool_executor_attr_reader_remaining_capacity - # Number of tasks that may be enqueued before reaching `max_queue` and rejecting - # new tasks. A value of -1 indicates that the queue may grow without bound. - # - # @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting - # new tasks. A value of -1 indicates that the queue may grow without bound. - - # @!macro thread_pool_executor_method_prune_pool - # Prune the thread pool of unneeded threads - # - # What is being pruned is controlled by the min_threads and idletime - # parameters passed at pool creation time - # - # This is a no-op on some pool implementation (e.g. the Java one). The Ruby - # pool will auto-prune each time a new job is posted. You will need to call - # this method explicitely in case your application post jobs in bursts (a - # lot of jobs and then nothing for long periods) - - # @!macro thread_pool_executor_public_api - # - # @!macro abstract_executor_service_public_api - # - # @!attribute [r] max_length - # @!macro thread_pool_executor_attr_reader_max_length - # - # @!attribute [r] min_length - # @!macro thread_pool_executor_attr_reader_min_length - # - # @!attribute [r] largest_length - # @!macro thread_pool_executor_attr_reader_largest_length - # - # @!attribute [r] scheduled_task_count - # @!macro thread_pool_executor_attr_reader_scheduled_task_count - # - # @!attribute [r] completed_task_count - # @!macro thread_pool_executor_attr_reader_completed_task_count - # - # @!attribute [r] idletime - # @!macro thread_pool_executor_attr_reader_idletime - # - # @!attribute [r] max_queue - # @!macro thread_pool_executor_attr_reader_max_queue - # - # @!attribute [r] length - # @!macro thread_pool_executor_attr_reader_length - # - # @!attribute [r] queue_length - # @!macro thread_pool_executor_attr_reader_queue_length - # - # @!attribute [r] remaining_capacity - # @!macro thread_pool_executor_attr_reader_remaining_capacity - # - # @!method can_overflow? - # @!macro executor_service_method_can_overflow_question - # - # @!method prune_pool - # @!macro thread_pool_executor_method_prune_pool - - - - - # @!macro thread_pool_options - # - # **Thread Pool Options** - # - # Thread pools support several configuration options: - # - # * `idletime`: The number of seconds that a thread may be idle before being reclaimed. - # * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and - # a `-worker-` name is given to its threads if supported by used Ruby - # implementation. `` is uniq for each thread. - # * `max_queue`: The maximum number of tasks that may be waiting in the work queue at - # any one time. When the queue size reaches `max_queue` and no new threads can be created, - # subsequent tasks will be rejected in accordance with the configured `fallback_policy`. - # * `auto_terminate`: When true (default), the threads started will be marked as daemon. - # * `fallback_policy`: The policy defining how rejected tasks are handled. - # - # Three fallback policies are supported: - # - # * `:abort`: Raise a `RejectedExecutionError` exception and discard the task. - # * `:discard`: Discard the task and return false. - # * `:caller_runs`: Execute the task on the calling thread. - # - # **Shutting Down Thread Pools** - # - # Killing a thread pool while tasks are still being processed, either by calling - # the `#kill` method or at application exit, will have unpredictable results. There - # is no way for the thread pool to know what resources are being used by the - # in-progress tasks. When those tasks are killed the impact on those resources - # cannot be predicted. The *best* practice is to explicitly shutdown all thread - # pools using the provided methods: - # - # * Call `#shutdown` to initiate an orderly termination of all in-progress tasks - # * Call `#wait_for_termination` with an appropriate timeout interval an allow - # the orderly shutdown to complete - # * Call `#kill` *only when* the thread pool fails to shutdown in the allotted time - # - # On some runtime platforms (most notably the JVM) the application will not - # exit until all thread pools have been shutdown. To prevent applications from - # "hanging" on exit, all threads can be marked as daemon according to the - # `:auto_terminate` option. - # - # ```ruby - # pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon - # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon - # ``` - # - # @note Failure to properly shutdown a thread pool can lead to unpredictable results. - # Please read *Shutting Down Thread Pools* for more information. - # - # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface - # @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean- - - - - - - # @!macro fixed_thread_pool - # - # A thread pool that reuses a fixed number of threads operating off an unbounded queue. - # At any point, at most `num_threads` will be active processing tasks. When all threads are busy new - # tasks `#post` to the thread pool are enqueued until a thread becomes available. - # Should a thread crash for any reason the thread will immediately be removed - # from the pool and replaced. - # - # The API and behavior of this class are based on Java's `FixedThreadPool` - # - # @!macro thread_pool_options - class FixedThreadPool < ThreadPoolExecutor - - # @!macro fixed_thread_pool_method_initialize - # - # Create a new thread pool. - # - # @param [Integer] num_threads the number of threads to allocate - # @param [Hash] opts the options defining pool behavior. - # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy - # - # @raise [ArgumentError] if `num_threads` is less than or equal to zero - # @raise [ArgumentError] if `fallback_policy` is not a known policy - # - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int- - def initialize(num_threads, opts = {}) - raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1 - defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE, - idletime: DEFAULT_THREAD_IDLETIMEOUT } - overrides = { min_threads: num_threads, - max_threads: num_threads } - super(defaults.merge(opts).merge(overrides)) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb deleted file mode 100644 index 282df7a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'concurrent/atomic/event' -require 'concurrent/executor/abstract_executor_service' -require 'concurrent/executor/serial_executor_service' - -module Concurrent - - # An executor service which runs all operations on the current thread, - # blocking as necessary. Operations are performed in the order they are - # received and no two operations can be performed simultaneously. - # - # This executor service exists mainly for testing an debugging. When used - # it immediately runs every `#post` operation on the current thread, blocking - # that thread until the operation is complete. This can be very beneficial - # during testing because it makes all operations deterministic. - # - # @note Intended for use primarily in testing and debugging. - class ImmediateExecutor < AbstractExecutorService - include SerialExecutorService - - # Creates a new executor - def initialize - @stopped = Concurrent::Event.new - end - - # @!macro executor_service_method_post - def post(*args, &task) - raise ArgumentError.new('no block given') unless block_given? - return false unless running? - task.call(*args) - true - end - - # @!macro executor_service_method_left_shift - def <<(task) - post(&task) - self - end - - # @!macro executor_service_method_running_question - def running? - ! shutdown? - end - - # @!macro executor_service_method_shuttingdown_question - def shuttingdown? - false - end - - # @!macro executor_service_method_shutdown_question - def shutdown? - @stopped.set? - end - - # @!macro executor_service_method_shutdown - def shutdown - @stopped.set - true - end - alias_method :kill, :shutdown - - # @!macro executor_service_method_wait_for_termination - def wait_for_termination(timeout = nil) - @stopped.wait(timeout) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb deleted file mode 100644 index 4f9769f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'concurrent/executor/immediate_executor' -require 'concurrent/executor/simple_executor_service' - -module Concurrent - # An executor service which runs all operations on a new thread, blocking - # until it completes. Operations are performed in the order they are received - # and no two operations can be performed simultaneously. - # - # This executor service exists mainly for testing an debugging. When used it - # immediately runs every `#post` operation on a new thread, blocking the - # current thread until the operation is complete. This is similar to how the - # ImmediateExecutor works, but the operation has the full stack of the new - # thread at its disposal. This can be helpful when the operations will spawn - # more operations on the same executor and so on - such a situation might - # overflow the single stack in case of an ImmediateExecutor, which is - # inconsistent with how it would behave for a threaded executor. - # - # @note Intended for use primarily in testing and debugging. - class IndirectImmediateExecutor < ImmediateExecutor - # Creates a new executor - def initialize - super - @internal_executor = SimpleExecutorService.new - end - - # @!macro executor_service_method_post - def post(*args, &task) - raise ArgumentError.new("no block given") unless block_given? - return false unless running? - - event = Concurrent::Event.new - @internal_executor.post do - begin - task.call(*args) - ensure - event.set - end - end - event.wait - - true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb deleted file mode 100644 index b2bc69a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'concurrent/utility/engine' - -if Concurrent.on_jruby? - require 'concurrent/errors' - require 'concurrent/executor/abstract_executor_service' - - module Concurrent - - # @!macro abstract_executor_service_public_api - # @!visibility private - class JavaExecutorService < AbstractExecutorService - java_import 'java.lang.Runnable' - - FALLBACK_POLICY_CLASSES = { - abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy, - discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy, - caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy - }.freeze - private_constant :FALLBACK_POLICY_CLASSES - - def post(*args, &task) - raise ArgumentError.new('no block given') unless block_given? - return fallback_action(*args, &task).call unless running? - @executor.submit Job.new(args, task) - true - rescue Java::JavaUtilConcurrent::RejectedExecutionException - raise RejectedExecutionError - end - - def wait_for_termination(timeout = nil) - if timeout.nil? - ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok - true - else - @executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) - end - end - - def shutdown - synchronize do - @executor.shutdown - nil - end - end - - def kill - synchronize do - @executor.shutdownNow - nil - end - end - - private - - def ns_running? - !(ns_shuttingdown? || ns_shutdown?) - end - - def ns_shuttingdown? - @executor.isShutdown && !@executor.isTerminated - end - - def ns_shutdown? - @executor.isTerminated - end - - class Job - include Runnable - def initialize(args, block) - @args = args - @block = block - end - - def run - @block.call(*@args) - end - end - private_constant :Job - end - - class DaemonThreadFactory - # hide include from YARD - send :include, java.util.concurrent.ThreadFactory - - def initialize(daemonize = true) - @daemonize = daemonize - @java_thread_factory = java.util.concurrent.Executors.defaultThreadFactory - end - - def newThread(runnable) - thread = @java_thread_factory.newThread(runnable) - thread.setDaemon(@daemonize) - return thread - end - end - - private_constant :DaemonThreadFactory - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb deleted file mode 100644 index 7aa24f2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb +++ /dev/null @@ -1,30 +0,0 @@ -if Concurrent.on_jruby? - - require 'concurrent/executor/java_executor_service' - require 'concurrent/executor/serial_executor_service' - - module Concurrent - - # @!macro single_thread_executor - # @!macro abstract_executor_service_public_api - # @!visibility private - class JavaSingleThreadExecutor < JavaExecutorService - include SerialExecutorService - - # @!macro single_thread_executor_method_initialize - def initialize(opts = {}) - super(opts) - end - - private - - def ns_initialize(opts) - @executor = java.util.concurrent.Executors.newSingleThreadExecutor( - DaemonThreadFactory.new(ns_auto_terminate?) - ) - @fallback_policy = opts.fetch(:fallback_policy, :discard) - raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb deleted file mode 100644 index 598a5f9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +++ /dev/null @@ -1,145 +0,0 @@ -if Concurrent.on_jruby? - - require 'concurrent/executor/java_executor_service' - - module Concurrent - - # @!macro thread_pool_executor - # @!macro thread_pool_options - # @!visibility private - class JavaThreadPoolExecutor < JavaExecutorService - - # @!macro thread_pool_executor_constant_default_max_pool_size - DEFAULT_MAX_POOL_SIZE = java.lang.Integer::MAX_VALUE # 2147483647 - - # @!macro thread_pool_executor_constant_default_min_pool_size - DEFAULT_MIN_POOL_SIZE = 0 - - # @!macro thread_pool_executor_constant_default_max_queue_size - DEFAULT_MAX_QUEUE_SIZE = 0 - - # @!macro thread_pool_executor_constant_default_thread_timeout - DEFAULT_THREAD_IDLETIMEOUT = 60 - - # @!macro thread_pool_executor_constant_default_synchronous - DEFAULT_SYNCHRONOUS = false - - # @!macro thread_pool_executor_attr_reader_max_length - attr_reader :max_length - - # @!macro thread_pool_executor_attr_reader_max_queue - attr_reader :max_queue - - # @!macro thread_pool_executor_attr_reader_synchronous - attr_reader :synchronous - - # @!macro thread_pool_executor_method_initialize - def initialize(opts = {}) - super(opts) - end - - # @!macro executor_service_method_can_overflow_question - def can_overflow? - @max_queue != 0 - end - - # @!macro thread_pool_executor_attr_reader_min_length - def min_length - @executor.getCorePoolSize - end - - # @!macro thread_pool_executor_attr_reader_max_length - def max_length - @executor.getMaximumPoolSize - end - - # @!macro thread_pool_executor_attr_reader_length - def length - @executor.getPoolSize - end - - # @!macro thread_pool_executor_attr_reader_largest_length - def largest_length - @executor.getLargestPoolSize - end - - # @!macro thread_pool_executor_attr_reader_scheduled_task_count - def scheduled_task_count - @executor.getTaskCount - end - - # @!macro thread_pool_executor_attr_reader_completed_task_count - def completed_task_count - @executor.getCompletedTaskCount - end - - # @!macro thread_pool_executor_method_active_count - def active_count - @executor.getActiveCount - end - - # @!macro thread_pool_executor_attr_reader_idletime - def idletime - @executor.getKeepAliveTime(java.util.concurrent.TimeUnit::SECONDS) - end - - # @!macro thread_pool_executor_attr_reader_queue_length - def queue_length - @executor.getQueue.size - end - - # @!macro thread_pool_executor_attr_reader_remaining_capacity - def remaining_capacity - @max_queue == 0 ? -1 : @executor.getQueue.remainingCapacity - end - - # @!macro executor_service_method_running_question - def running? - super && !@executor.isTerminating - end - - # @!macro thread_pool_executor_method_prune_pool - def prune_pool - end - - private - - def ns_initialize(opts) - min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i - max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i - idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i - @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i - @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) - @fallback_policy = opts.fetch(:fallback_policy, :abort) - - raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 - raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE - raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE - raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE - raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length - raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy) - - if @max_queue == 0 - if @synchronous - queue = java.util.concurrent.SynchronousQueue.new - else - queue = java.util.concurrent.LinkedBlockingQueue.new - end - else - queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue) - end - - @executor = java.util.concurrent.ThreadPoolExecutor.new( - min_length, - max_length, - idletime, - java.util.concurrent.TimeUnit::SECONDS, - queue, - DaemonThreadFactory.new(ns_auto_terminate?), - FALLBACK_POLICY_CLASSES[@fallback_policy].new) - - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb deleted file mode 100644 index 1f7301b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'concurrent/executor/abstract_executor_service' -require 'concurrent/atomic/event' - -module Concurrent - - # @!macro abstract_executor_service_public_api - # @!visibility private - class RubyExecutorService < AbstractExecutorService - safe_initialization! - - def initialize(*args, &block) - super - @StopEvent = Event.new - @StoppedEvent = Event.new - end - - def post(*args, &task) - raise ArgumentError.new('no block given') unless block_given? - deferred_action = synchronize { - if running? - ns_execute(*args, &task) - else - fallback_action(*args, &task) - end - } - if deferred_action - deferred_action.call - else - true - end - end - - def shutdown - synchronize do - break unless running? - stop_event.set - ns_shutdown_execution - end - true - end - - def kill - synchronize do - break if shutdown? - stop_event.set - ns_kill_execution - stopped_event.set - end - true - end - - def wait_for_termination(timeout = nil) - stopped_event.wait(timeout) - end - - private - - def stop_event - @StopEvent - end - - def stopped_event - @StoppedEvent - end - - def ns_shutdown_execution - stopped_event.set - end - - def ns_running? - !stop_event.set? - end - - def ns_shuttingdown? - !(ns_running? || ns_shutdown?) - end - - def ns_shutdown? - stopped_event.set? - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb deleted file mode 100644 index 916337d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'concurrent/executor/ruby_thread_pool_executor' - -module Concurrent - - # @!macro single_thread_executor - # @!macro abstract_executor_service_public_api - # @!visibility private - class RubySingleThreadExecutor < RubyThreadPoolExecutor - - # @!macro single_thread_executor_method_initialize - def initialize(opts = {}) - super( - min_threads: 1, - max_threads: 1, - max_queue: 0, - idletime: DEFAULT_THREAD_IDLETIMEOUT, - fallback_policy: opts.fetch(:fallback_policy, :discard), - ) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb deleted file mode 100644 index 9375acf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +++ /dev/null @@ -1,373 +0,0 @@ -require 'thread' -require 'concurrent/atomic/event' -require 'concurrent/concern/logging' -require 'concurrent/executor/ruby_executor_service' -require 'concurrent/utility/monotonic_time' - -module Concurrent - - # @!macro thread_pool_executor - # @!macro thread_pool_options - # @!visibility private - class RubyThreadPoolExecutor < RubyExecutorService - - # @!macro thread_pool_executor_constant_default_max_pool_size - DEFAULT_MAX_POOL_SIZE = 2_147_483_647 # java.lang.Integer::MAX_VALUE - - # @!macro thread_pool_executor_constant_default_min_pool_size - DEFAULT_MIN_POOL_SIZE = 0 - - # @!macro thread_pool_executor_constant_default_max_queue_size - DEFAULT_MAX_QUEUE_SIZE = 0 - - # @!macro thread_pool_executor_constant_default_thread_timeout - DEFAULT_THREAD_IDLETIMEOUT = 60 - - # @!macro thread_pool_executor_constant_default_synchronous - DEFAULT_SYNCHRONOUS = false - - # @!macro thread_pool_executor_attr_reader_max_length - attr_reader :max_length - - # @!macro thread_pool_executor_attr_reader_min_length - attr_reader :min_length - - # @!macro thread_pool_executor_attr_reader_idletime - attr_reader :idletime - - # @!macro thread_pool_executor_attr_reader_max_queue - attr_reader :max_queue - - # @!macro thread_pool_executor_attr_reader_synchronous - attr_reader :synchronous - - # @!macro thread_pool_executor_method_initialize - def initialize(opts = {}) - super(opts) - end - - # @!macro thread_pool_executor_attr_reader_largest_length - def largest_length - synchronize { @largest_length } - end - - # @!macro thread_pool_executor_attr_reader_scheduled_task_count - def scheduled_task_count - synchronize { @scheduled_task_count } - end - - # @!macro thread_pool_executor_attr_reader_completed_task_count - def completed_task_count - synchronize { @completed_task_count } - end - - # @!macro thread_pool_executor_method_active_count - def active_count - synchronize do - @pool.length - @ready.length - end - end - - # @!macro executor_service_method_can_overflow_question - def can_overflow? - synchronize { ns_limited_queue? } - end - - # @!macro thread_pool_executor_attr_reader_length - def length - synchronize { @pool.length } - end - - # @!macro thread_pool_executor_attr_reader_queue_length - def queue_length - synchronize { @queue.length } - end - - # @!macro thread_pool_executor_attr_reader_remaining_capacity - def remaining_capacity - synchronize do - if ns_limited_queue? - @max_queue - @queue.length - else - -1 - end - end - end - - # @!visibility private - def remove_busy_worker(worker) - synchronize { ns_remove_busy_worker worker } - end - - # @!visibility private - def ready_worker(worker, last_message) - synchronize { ns_ready_worker worker, last_message } - end - - # @!visibility private - def worker_died(worker) - synchronize { ns_worker_died worker } - end - - # @!visibility private - def worker_task_completed - synchronize { @completed_task_count += 1 } - end - - # @!macro thread_pool_executor_method_prune_pool - def prune_pool - synchronize { ns_prune_pool } - end - - private - - # @!visibility private - def ns_initialize(opts) - @min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i - @max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i - @idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i - @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i - @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) - @fallback_policy = opts.fetch(:fallback_policy, :abort) - - raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 - raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICIES.include?(@fallback_policy) - raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @max_length < DEFAULT_MIN_POOL_SIZE - raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if @max_length > DEFAULT_MAX_POOL_SIZE - raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @min_length < DEFAULT_MIN_POOL_SIZE - raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length - - @pool = [] # all workers - @ready = [] # used as a stash (most idle worker is at the start) - @queue = [] # used as queue - # @ready or @queue is empty at all times - @scheduled_task_count = 0 - @completed_task_count = 0 - @largest_length = 0 - @workers_counter = 0 - @ruby_pid = $$ # detects if Ruby has forked - - @gc_interval = opts.fetch(:gc_interval, @idletime / 2.0).to_i # undocumented - @next_gc_time = Concurrent.monotonic_time + @gc_interval - end - - # @!visibility private - def ns_limited_queue? - @max_queue != 0 - end - - # @!visibility private - def ns_execute(*args, &task) - ns_reset_if_forked - - if ns_assign_worker(*args, &task) || ns_enqueue(*args, &task) - @scheduled_task_count += 1 - else - return fallback_action(*args, &task) - end - - ns_prune_pool if @next_gc_time < Concurrent.monotonic_time - nil - end - - # @!visibility private - def ns_shutdown_execution - ns_reset_if_forked - - if @pool.empty? - # nothing to do - stopped_event.set - end - - if @queue.empty? - # no more tasks will be accepted, just stop all workers - @pool.each(&:stop) - end - end - - # @!visibility private - def ns_kill_execution - # TODO log out unprocessed tasks in queue - # TODO try to shutdown first? - @pool.each(&:kill) - @pool.clear - @ready.clear - end - - # tries to assign task to a worker, tries to get one from @ready or to create new one - # @return [true, false] if task is assigned to a worker - # - # @!visibility private - def ns_assign_worker(*args, &task) - # keep growing if the pool is not at the minimum yet - worker, _ = (@ready.pop if @pool.size >= @min_length) || ns_add_busy_worker - if worker - worker << [task, args] - true - else - false - end - rescue ThreadError - # Raised when the operating system refuses to create the new thread - return false - end - - # tries to enqueue task - # @return [true, false] if enqueued - # - # @!visibility private - def ns_enqueue(*args, &task) - return false if @synchronous - - if !ns_limited_queue? || @queue.size < @max_queue - @queue << [task, args] - true - else - false - end - end - - # @!visibility private - def ns_worker_died(worker) - ns_remove_busy_worker worker - replacement_worker = ns_add_busy_worker - ns_ready_worker replacement_worker, Concurrent.monotonic_time, false if replacement_worker - end - - # creates new worker which has to receive work to do after it's added - # @return [nil, Worker] nil of max capacity is reached - # - # @!visibility private - def ns_add_busy_worker - return if @pool.size >= @max_length - - @workers_counter += 1 - @pool << (worker = Worker.new(self, @workers_counter)) - @largest_length = @pool.length if @pool.length > @largest_length - worker - end - - # handle ready worker, giving it new job or assigning back to @ready - # - # @!visibility private - def ns_ready_worker(worker, last_message, success = true) - task_and_args = @queue.shift - if task_and_args - worker << task_and_args - else - # stop workers when !running?, do not return them to @ready - if running? - raise unless last_message - @ready.push([worker, last_message]) - else - worker.stop - end - end - end - - # removes a worker which is not in not tracked in @ready - # - # @!visibility private - def ns_remove_busy_worker(worker) - @pool.delete(worker) - stopped_event.set if @pool.empty? && !running? - true - end - - # try oldest worker if it is idle for enough time, it's returned back at the start - # - # @!visibility private - def ns_prune_pool - now = Concurrent.monotonic_time - stopped_workers = 0 - while !@ready.empty? && (@pool.size - stopped_workers > @min_length) - worker, last_message = @ready.first - if now - last_message > self.idletime - stopped_workers += 1 - @ready.shift - worker << :stop - else break - end - end - - @next_gc_time = Concurrent.monotonic_time + @gc_interval - end - - def ns_reset_if_forked - if $$ != @ruby_pid - @queue.clear - @ready.clear - @pool.clear - @scheduled_task_count = 0 - @completed_task_count = 0 - @largest_length = 0 - @workers_counter = 0 - @ruby_pid = $$ - end - end - - # @!visibility private - class Worker - include Concern::Logging - - def initialize(pool, id) - # instance variables accessed only under pool's lock so no need to sync here again - @queue = Queue.new - @pool = pool - @thread = create_worker @queue, pool, pool.idletime - - if @thread.respond_to?(:name=) - @thread.name = [pool.name, 'worker', id].compact.join('-') - end - end - - def <<(message) - @queue << message - end - - def stop - @queue << :stop - end - - def kill - @thread.kill - end - - private - - def create_worker(queue, pool, idletime) - Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime| - catch(:stop) do - loop do - - case message = my_queue.pop - when :stop - my_pool.remove_busy_worker(self) - throw :stop - - else - task, args = message - run_task my_pool, task, args - my_pool.ready_worker(self, Concurrent.monotonic_time) - end - end - end - end - end - - def run_task(pool, task, args) - task.call(*args) - pool.worker_task_completed - rescue => ex - # let it fail - log DEBUG, ex - rescue Exception => ex - log ERROR, ex - pool.worker_died(self) - throw :stop - end - end - - private_constant :Worker - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb deleted file mode 100644 index f796b85..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # A simple utility class that executes a callable and returns and array of three elements: - # success - indicating if the callable has been executed without errors - # value - filled by the callable result if it has been executed without errors, nil otherwise - # reason - the error risen by the callable if it has been executed with errors, nil otherwise - class SafeTaskExecutor < Synchronization::LockableObject - - def initialize(task, opts = {}) - @task = task - @exception_class = opts.fetch(:rescue_exception, false) ? Exception : StandardError - super() # ensures visibility - end - - # @return [Array] - def execute(*args) - success = true - value = reason = nil - - synchronize do - begin - value = @task.call(*args) - success = true - rescue @exception_class => ex - reason = ex - success = false - end - end - - [success, value, reason] - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb deleted file mode 100644 index f1c38ec..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'concurrent/executor/executor_service' - -module Concurrent - - # Indicates that the including `ExecutorService` guarantees - # that all operations will occur in the order they are post and that no - # two operations may occur simultaneously. This module provides no - # functionality and provides no guarantees. That is the responsibility - # of the including class. This module exists solely to allow the including - # object to be interrogated for its serialization status. - # - # @example - # class Foo - # include Concurrent::SerialExecutor - # end - # - # foo = Foo.new - # - # foo.is_a? Concurrent::ExecutorService #=> true - # foo.is_a? Concurrent::SerialExecutor #=> true - # foo.serialized? #=> true - # - # @!visibility private - module SerialExecutorService - include ExecutorService - - # @!macro executor_service_method_serialized_question - # - # @note Always returns `true` - def serialized? - true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb deleted file mode 100644 index 4db7c7f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +++ /dev/null @@ -1,107 +0,0 @@ -require 'concurrent/errors' -require 'concurrent/concern/logging' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # Ensures passed jobs in a serialized order never running at the same time. - class SerializedExecution < Synchronization::LockableObject - include Concern::Logging - - def initialize() - super() - synchronize { ns_initialize } - end - - Job = Struct.new(:executor, :args, :block) do - def call - block.call(*args) - end - end - - # Submit a task to the executor for asynchronous processing. - # - # @param [Executor] executor to be used for this job - # - # @param [Array] args zero or more arguments to be passed to the task - # - # @yield the asynchronous task to perform - # - # @return [Boolean] `true` if the task is queued, `false` if the executor - # is not running - # - # @raise [ArgumentError] if no task is given - def post(executor, *args, &task) - posts [[executor, args, task]] - true - end - - # As {#post} but allows to submit multiple tasks at once, it's guaranteed that they will not - # be interleaved by other tasks. - # - # @param [Array, Proc)>] posts array of triplets where - # first is a {ExecutorService}, second is array of args for task, third is a task (Proc) - def posts(posts) - # if can_overflow? - # raise ArgumentError, 'SerializedExecution does not support thread-pools which can overflow' - # end - - return nil if posts.empty? - - jobs = posts.map { |executor, args, task| Job.new executor, args, task } - - job_to_post = synchronize do - if @being_executed - @stash.push(*jobs) - nil - else - @being_executed = true - @stash.push(*jobs[1..-1]) - jobs.first - end - end - - call_job job_to_post if job_to_post - true - end - - private - - def ns_initialize - @being_executed = false - @stash = [] - end - - def call_job(job) - did_it_run = begin - job.executor.post { work(job) } - true - rescue RejectedExecutionError => ex - false - end - - # TODO not the best idea to run it myself - unless did_it_run - begin - work job - rescue => ex - # let it fail - log DEBUG, ex - end - end - end - - # ensures next job is executed if any is stashed - def work(job) - job.call - ensure - synchronize do - job = @stash.shift || (@being_executed = false) - end - - # TODO maybe be able to tell caching pool to just enqueue this job, because the current one end at the end - # of this block - call_job job if job - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb deleted file mode 100644 index 8197781..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'delegate' -require 'concurrent/executor/serial_executor_service' -require 'concurrent/executor/serialized_execution' - -module Concurrent - - # A wrapper/delegator for any `ExecutorService` that - # guarantees serialized execution of tasks. - # - # @see [SimpleDelegator](http://www.ruby-doc.org/stdlib-2.1.2/libdoc/delegate/rdoc/SimpleDelegator.html) - # @see Concurrent::SerializedExecution - class SerializedExecutionDelegator < SimpleDelegator - include SerialExecutorService - - def initialize(executor) - @executor = executor - @serializer = SerializedExecution.new - super(executor) - end - - # @!macro executor_service_method_post - def post(*args, &task) - raise ArgumentError.new('no block given') unless block_given? - return false unless running? - @serializer.post(@executor, *args, &task) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb deleted file mode 100644 index 0bc62af..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'concurrent/atomic/atomic_boolean' -require 'concurrent/atomic/atomic_fixnum' -require 'concurrent/atomic/event' -require 'concurrent/executor/executor_service' -require 'concurrent/executor/ruby_executor_service' - -module Concurrent - - # An executor service in which every operation spawns a new, - # independently operating thread. - # - # This is perhaps the most inefficient executor service in this - # library. It exists mainly for testing an debugging. Thread creation - # and management is expensive in Ruby and this executor performs no - # resource pooling. This can be very beneficial during testing and - # debugging because it decouples the using code from the underlying - # executor implementation. In production this executor will likely - # lead to suboptimal performance. - # - # @note Intended for use primarily in testing and debugging. - class SimpleExecutorService < RubyExecutorService - - # @!macro executor_service_method_post - def self.post(*args) - raise ArgumentError.new('no block given') unless block_given? - Thread.new(*args) do - Thread.current.abort_on_exception = false - yield(*args) - end - true - end - - # @!macro executor_service_method_left_shift - def self.<<(task) - post(&task) - self - end - - # @!macro executor_service_method_post - def post(*args, &task) - raise ArgumentError.new('no block given') unless block_given? - return false unless running? - @count.increment - Thread.new(*args) do - Thread.current.abort_on_exception = false - begin - yield(*args) - ensure - @count.decrement - @stopped.set if @running.false? && @count.value == 0 - end - end - end - - # @!macro executor_service_method_left_shift - def <<(task) - post(&task) - self - end - - # @!macro executor_service_method_running_question - def running? - @running.true? - end - - # @!macro executor_service_method_shuttingdown_question - def shuttingdown? - @running.false? && ! @stopped.set? - end - - # @!macro executor_service_method_shutdown_question - def shutdown? - @stopped.set? - end - - # @!macro executor_service_method_shutdown - def shutdown - @running.make_false - @stopped.set if @count.value == 0 - true - end - - # @!macro executor_service_method_kill - def kill - @running.make_false - @stopped.set - true - end - - # @!macro executor_service_method_wait_for_termination - def wait_for_termination(timeout = nil) - @stopped.wait(timeout) - end - - private - - def ns_initialize(*args) - @running = Concurrent::AtomicBoolean.new(true) - @stopped = Concurrent::Event.new - @count = Concurrent::AtomicFixnum.new(0) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb deleted file mode 100644 index f1474ea..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/executor/ruby_single_thread_executor' - -module Concurrent - - if Concurrent.on_jruby? - require 'concurrent/executor/java_single_thread_executor' - end - - SingleThreadExecutorImplementation = case - when Concurrent.on_jruby? - JavaSingleThreadExecutor - else - RubySingleThreadExecutor - end - private_constant :SingleThreadExecutorImplementation - - # @!macro single_thread_executor - # - # A thread pool with a single thread an unlimited queue. Should the thread - # die for any reason it will be removed and replaced, thus ensuring that - # the executor will always remain viable and available to process jobs. - # - # A common pattern for background processing is to create a single thread - # on which an infinite loop is run. The thread's loop blocks on an input - # source (perhaps blocking I/O or a queue) and processes each input as it - # is received. This pattern has several issues. The thread itself is highly - # susceptible to errors during processing. Also, the thread itself must be - # constantly monitored and restarted should it die. `SingleThreadExecutor` - # encapsulates all these bahaviors. The task processor is highly resilient - # to errors from within tasks. Also, should the thread die it will - # automatically be restarted. - # - # The API and behavior of this class are based on Java's `SingleThreadExecutor`. - # - # @!macro abstract_executor_service_public_api - class SingleThreadExecutor < SingleThreadExecutorImplementation - - # @!macro single_thread_executor_method_initialize - # - # Create a new thread pool. - # - # @option opts [Symbol] :fallback_policy (:discard) the policy for handling new - # tasks that are received when the queue size has reached - # `max_queue` or the executor has shut down - # - # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified - # in `FALLBACK_POLICIES` - # - # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html - # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html - - # @!method initialize(opts = {}) - # @!macro single_thread_executor_method_initialize - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb deleted file mode 100644 index 253d46a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/executor/ruby_thread_pool_executor' - -module Concurrent - - if Concurrent.on_jruby? - require 'concurrent/executor/java_thread_pool_executor' - end - - ThreadPoolExecutorImplementation = case - when Concurrent.on_jruby? - JavaThreadPoolExecutor - else - RubyThreadPoolExecutor - end - private_constant :ThreadPoolExecutorImplementation - - # @!macro thread_pool_executor - # - # An abstraction composed of one or more threads and a task queue. Tasks - # (blocks or `proc` objects) are submitted to the pool and added to the queue. - # The threads in the pool remove the tasks and execute them in the order - # they were received. - # - # A `ThreadPoolExecutor` will automatically adjust the pool size according - # to the bounds set by `min-threads` and `max-threads`. When a new task is - # submitted and fewer than `min-threads` threads are running, a new thread - # is created to handle the request, even if other worker threads are idle. - # If there are more than `min-threads` but less than `max-threads` threads - # running, a new thread will be created only if the queue is full. - # - # Threads that are idle for too long will be garbage collected, down to the - # configured minimum options. Should a thread crash it, too, will be garbage collected. - # - # `ThreadPoolExecutor` is based on the Java class of the same name. From - # the official Java documentation; - # - # > Thread pools address two different problems: they usually provide - # > improved performance when executing large numbers of asynchronous tasks, - # > due to reduced per-task invocation overhead, and they provide a means - # > of bounding and managing the resources, including threads, consumed - # > when executing a collection of tasks. Each ThreadPoolExecutor also - # > maintains some basic statistics, such as the number of completed tasks. - # > - # > To be useful across a wide range of contexts, this class provides many - # > adjustable parameters and extensibility hooks. However, programmers are - # > urged to use the more convenient Executors factory methods - # > [CachedThreadPool] (unbounded thread pool, with automatic thread reclamation), - # > [FixedThreadPool] (fixed size thread pool) and [SingleThreadExecutor] (single - # > background thread), that preconfigure settings for the most common usage - # > scenarios. - # - # @!macro thread_pool_options - # - # @!macro thread_pool_executor_public_api - class ThreadPoolExecutor < ThreadPoolExecutorImplementation - - # @!macro thread_pool_executor_method_initialize - # - # Create a new thread pool. - # - # @param [Hash] opts the options which configure the thread pool. - # - # @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum - # number of threads to be created - # @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted - # and fewer than `min_threads` are running, a new thread is created - # @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum - # number of seconds a thread may be idle before being reclaimed - # @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum - # number of tasks allowed in the work queue at any one time; a value of - # zero means the queue may grow without bound - # @option opts [Symbol] :fallback_policy (:abort) the policy for handling new - # tasks that are received when the queue size has reached - # `max_queue` or the executor has shut down - # @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0 - # for :max_queue means the queue must perform direct hand-off rather than unbounded. - # @raise [ArgumentError] if `:max_threads` is less than one - # @raise [ArgumentError] if `:min_threads` is less than zero - # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified - # in `FALLBACK_POLICIES` - # - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html - - # @!method initialize(opts = {}) - # @!macro thread_pool_executor_method_initialize - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/timer_set.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/timer_set.rb deleted file mode 100644 index 759dce0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executor/timer_set.rb +++ /dev/null @@ -1,176 +0,0 @@ -require 'concurrent/scheduled_task' -require 'concurrent/atomic/event' -require 'concurrent/collection/non_concurrent_priority_queue' -require 'concurrent/executor/executor_service' -require 'concurrent/executor/single_thread_executor' -require 'concurrent/errors' -require 'concurrent/options' - -module Concurrent - - # Executes a collection of tasks, each after a given delay. A master task - # monitors the set and schedules each task for execution at the appropriate - # time. Tasks are run on the global thread pool or on the supplied executor. - # Each task is represented as a `ScheduledTask`. - # - # @see Concurrent::ScheduledTask - # - # @!macro monotonic_clock_warning - class TimerSet < RubyExecutorService - - # Create a new set of timed tasks. - # - # @!macro executor_options - # - # @param [Hash] opts the options used to specify the executor on which to perform actions - # @option opts [Executor] :executor when set use the given `Executor` instance. - # Three special values are also supported: `:task` returns the global task pool, - # `:operation` returns the global operation pool, and `:immediate` returns a new - # `ImmediateExecutor` object. - def initialize(opts = {}) - super(opts) - end - - # Post a task to be execute run after a given delay (in seconds). If the - # delay is less than 1/100th of a second the task will be immediately post - # to the executor. - # - # @param [Float] delay the number of seconds to wait for before executing the task. - # @param [Array] args the arguments passed to the task on execution. - # - # @yield the task to be performed. - # - # @return [Concurrent::ScheduledTask, false] IVar representing the task if the post - # is successful; false after shutdown. - # - # @raise [ArgumentError] if the intended execution time is not in the future. - # @raise [ArgumentError] if no block is given. - def post(delay, *args, &task) - raise ArgumentError.new('no block given') unless block_given? - return false unless running? - opts = { executor: @task_executor, - args: args, - timer_set: self } - task = ScheduledTask.execute(delay, opts, &task) # may raise exception - task.unscheduled? ? false : task - end - - # Begin an immediate shutdown. In-progress tasks will be allowed to - # complete but enqueued tasks will be dismissed and no new tasks - # will be accepted. Has no additional effect if the thread pool is - # not running. - def kill - shutdown - end - - private :<< - - private - - # Initialize the object. - # - # @param [Hash] opts the options to create the object with. - # @!visibility private - def ns_initialize(opts) - @queue = Collection::NonConcurrentPriorityQueue.new(order: :min) - @task_executor = Options.executor_from_options(opts) || Concurrent.global_io_executor - @timer_executor = SingleThreadExecutor.new - @condition = Event.new - @ruby_pid = $$ # detects if Ruby has forked - end - - # Post the task to the internal queue. - # - # @note This is intended as a callback method from ScheduledTask - # only. It is not intended to be used directly. Post a task - # by using the `SchedulesTask#execute` method. - # - # @!visibility private - def post_task(task) - synchronize { ns_post_task(task) } - end - - # @!visibility private - def ns_post_task(task) - return false unless ns_running? - ns_reset_if_forked - if (task.initial_delay) <= 0.01 - task.executor.post { task.process_task } - else - @queue.push(task) - # only post the process method when the queue is empty - @timer_executor.post(&method(:process_tasks)) if @queue.length == 1 - @condition.set - end - true - end - - # Remove the given task from the queue. - # - # @note This is intended as a callback method from `ScheduledTask` - # only. It is not intended to be used directly. Cancel a task - # by using the `ScheduledTask#cancel` method. - # - # @!visibility private - def remove_task(task) - synchronize { @queue.delete(task) } - end - - # `ExecutorService` callback called during shutdown. - # - # @!visibility private - def ns_shutdown_execution - ns_reset_if_forked - @queue.clear - @timer_executor.kill - stopped_event.set - end - - def ns_reset_if_forked - if $$ != @ruby_pid - @queue.clear - @condition.reset - @ruby_pid = $$ - end - end - - # Run a loop and execute tasks in the scheduled order and at the approximate - # scheduled time. If no tasks remain the thread will exit gracefully so that - # garbage collection can occur. If there are no ready tasks it will sleep - # for up to 60 seconds waiting for the next scheduled task. - # - # @!visibility private - def process_tasks - loop do - task = synchronize { @condition.reset; @queue.peek } - break unless task - - now = Concurrent.monotonic_time - diff = task.schedule_time - now - - if diff <= 0 - # We need to remove the task from the queue before passing - # it to the executor, to avoid race conditions where we pass - # the peek'ed task to the executor and then pop a different - # one that's been added in the meantime. - # - # Note that there's no race condition between the peek and - # this pop - this pop could retrieve a different task from - # the peek, but that task would be due to fire now anyway - # (because @queue is a priority queue, and this thread is - # the only reader, so whatever timer is at the head of the - # queue now must have the same pop time, or a closer one, as - # when we peeked). - task = synchronize { @queue.pop } - begin - task.executor.post { task.process_task } - rescue RejectedExecutionError - # ignore and continue - end - else - @condition.wait([diff, 60].min) - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executors.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executors.rb deleted file mode 100644 index eb1972c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/executors.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'concurrent/executor/abstract_executor_service' -require 'concurrent/executor/cached_thread_pool' -require 'concurrent/executor/executor_service' -require 'concurrent/executor/fixed_thread_pool' -require 'concurrent/executor/immediate_executor' -require 'concurrent/executor/indirect_immediate_executor' -require 'concurrent/executor/java_executor_service' -require 'concurrent/executor/java_single_thread_executor' -require 'concurrent/executor/java_thread_pool_executor' -require 'concurrent/executor/ruby_executor_service' -require 'concurrent/executor/ruby_single_thread_executor' -require 'concurrent/executor/ruby_thread_pool_executor' -require 'concurrent/executor/cached_thread_pool' -require 'concurrent/executor/safe_task_executor' -require 'concurrent/executor/serial_executor_service' -require 'concurrent/executor/serialized_execution' -require 'concurrent/executor/serialized_execution_delegator' -require 'concurrent/executor/single_thread_executor' -require 'concurrent/executor/thread_pool_executor' -require 'concurrent/executor/timer_set' diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/future.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/future.rb deleted file mode 100644 index 1af182e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/future.rb +++ /dev/null @@ -1,141 +0,0 @@ -require 'thread' -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/ivar' -require 'concurrent/executor/safe_task_executor' - -require 'concurrent/options' - -# TODO (pitr-ch 14-Mar-2017): deprecate, Future, Promise, etc. - - -module Concurrent - - # {include:file:docs-source/future.md} - # - # @!macro copy_options - # - # @see http://ruby-doc.org/stdlib-2.1.1/libdoc/observer/rdoc/Observable.html Ruby Observable module - # @see http://clojuredocs.org/clojure_core/clojure.core/future Clojure's future function - # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html java.util.concurrent.Future - class Future < IVar - - # Create a new `Future` in the `:unscheduled` state. - # - # @yield the asynchronous operation to perform - # - # @!macro executor_and_deref_options - # - # @option opts [object, Array] :args zero or more arguments to be passed the task - # block on execution - # - # @raise [ArgumentError] if no block is given - def initialize(opts = {}, &block) - raise ArgumentError.new('no block given') unless block_given? - super(NULL, opts.merge(__task_from_block__: block), &nil) - end - - # Execute an `:unscheduled` `Future`. Immediately sets the state to `:pending` and - # passes the block to a new thread/thread pool for eventual execution. - # Does nothing if the `Future` is in any state other than `:unscheduled`. - # - # @return [Future] a reference to `self` - # - # @example Instance and execute in separate steps - # future = Concurrent::Future.new{ sleep(1); 42 } - # future.state #=> :unscheduled - # future.execute - # future.state #=> :pending - # - # @example Instance and execute in one line - # future = Concurrent::Future.new{ sleep(1); 42 }.execute - # future.state #=> :pending - def execute - if compare_and_set_state(:pending, :unscheduled) - @executor.post{ safe_execute(@task, @args) } - self - end - end - - # Create a new `Future` object with the given block, execute it, and return the - # `:pending` object. - # - # @yield the asynchronous operation to perform - # - # @!macro executor_and_deref_options - # - # @option opts [object, Array] :args zero or more arguments to be passed the task - # block on execution - # - # @raise [ArgumentError] if no block is given - # - # @return [Future] the newly created `Future` in the `:pending` state - # - # @example - # future = Concurrent::Future.execute{ sleep(1); 42 } - # future.state #=> :pending - def self.execute(opts = {}, &block) - Future.new(opts, &block).execute - end - - # @!macro ivar_set_method - def set(value = NULL, &block) - check_for_block_or_value!(block_given?, value) - synchronize do - if @state != :unscheduled - raise MultipleAssignmentError - else - @task = block || Proc.new { value } - end - end - execute - end - - # Attempt to cancel the operation if it has not already processed. - # The operation can only be cancelled while still `pending`. It cannot - # be cancelled once it has begun processing or has completed. - # - # @return [Boolean] was the operation successfully cancelled. - def cancel - if compare_and_set_state(:cancelled, :pending) - complete(false, nil, CancelledOperationError.new) - true - else - false - end - end - - # Has the operation been successfully cancelled? - # - # @return [Boolean] - def cancelled? - state == :cancelled - end - - # Wait the given number of seconds for the operation to complete. - # On timeout attempt to cancel the operation. - # - # @param [Numeric] timeout the maximum time in seconds to wait. - # @return [Boolean] true if the operation completed before the timeout - # else false - def wait_or_cancel(timeout) - wait(timeout) - if complete? - true - else - cancel - false - end - end - - protected - - def ns_initialize(value, opts) - super - @state = :unscheduled - @task = opts[:__task_from_block__] - @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor - @args = get_arguments_from(opts) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/hash.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/hash.rb deleted file mode 100644 index db0208e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/hash.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/thread_safe/util' - -module Concurrent - - # @!macro concurrent_hash - # - # A thread-safe subclass of Hash. This version locks against the object - # itself for every method call, ensuring only one thread can be reading - # or writing at a time. This includes iteration methods like `#each`, - # which takes the lock repeatedly when reading an item. - # - # @see http://ruby-doc.org/core/Hash.html Ruby standard library `Hash` - - # @!macro internal_implementation_note - HashImplementation = case - when Concurrent.on_cruby? - # Hash is not fully thread-safe on CRuby, see - # https://bugs.ruby-lang.org/issues/19237 - # https://github.com/ruby/ruby/commit/ffd52412ab - # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 - # So we will need to add synchronization here (similar to Concurrent::Map). - ::Hash - - when Concurrent.on_jruby? - require 'jruby/synchronized' - - class JRubyHash < ::Hash - include JRuby::Synchronized - end - JRubyHash - - when Concurrent.on_truffleruby? - require 'concurrent/thread_safe/util/data_structures' - - class TruffleRubyHash < ::Hash - end - - ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyHash - TruffleRubyHash - - else - warn 'Possibly unsupported Ruby implementation' - ::Hash - end - private_constant :HashImplementation - - # @!macro concurrent_hash - class Hash < HashImplementation - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/immutable_struct.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/immutable_struct.rb deleted file mode 100644 index 48462e8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/immutable_struct.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'concurrent/synchronization/abstract_struct' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # A thread-safe, immutable variation of Ruby's standard `Struct`. - # - # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` - module ImmutableStruct - include Synchronization::AbstractStruct - - def self.included(base) - base.safe_initialization! - end - - # @!macro struct_values - def values - ns_values - end - - alias_method :to_a, :values - - # @!macro struct_values_at - def values_at(*indexes) - ns_values_at(indexes) - end - - # @!macro struct_inspect - def inspect - ns_inspect - end - - alias_method :to_s, :inspect - - # @!macro struct_merge - def merge(other, &block) - ns_merge(other, &block) - end - - # @!macro struct_to_h - def to_h - ns_to_h - end - - # @!macro struct_get - def [](member) - ns_get(member) - end - - # @!macro struct_equality - def ==(other) - ns_equality(other) - end - - # @!macro struct_each - def each(&block) - return enum_for(:each) unless block_given? - ns_each(&block) - end - - # @!macro struct_each_pair - def each_pair(&block) - return enum_for(:each_pair) unless block_given? - ns_each_pair(&block) - end - - # @!macro struct_select - def select(&block) - return enum_for(:select) unless block_given? - ns_select(&block) - end - - private - - # @!visibility private - def initialize_copy(original) - super(original) - ns_initialize_copy - end - - # @!macro struct_new - def self.new(*args, &block) - clazz_name = nil - if args.length == 0 - raise ArgumentError.new('wrong number of arguments (0 for 1+)') - elsif args.length > 0 && args.first.is_a?(String) - clazz_name = args.shift - end - FACTORY.define_struct(clazz_name, args, &block) - end - - FACTORY = Class.new(Synchronization::LockableObject) do - def define_struct(name, members, &block) - synchronize do - Synchronization::AbstractStruct.define_struct_class(ImmutableStruct, Synchronization::Object, name, members, &block) - end - end - end.new - private_constant :FACTORY - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/ivar.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/ivar.rb deleted file mode 100644 index 4165038..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/ivar.rb +++ /dev/null @@ -1,208 +0,0 @@ -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/collection/copy_on_write_observer_set' -require 'concurrent/concern/obligation' -require 'concurrent/concern/observable' -require 'concurrent/executor/safe_task_executor' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # An `IVar` is like a future that you can assign. As a future is a value that - # is being computed that you can wait on, an `IVar` is a value that is waiting - # to be assigned, that you can wait on. `IVars` are single assignment and - # deterministic. - # - # Then, express futures as an asynchronous computation that assigns an `IVar`. - # The `IVar` becomes the primitive on which [futures](Future) and - # [dataflow](Dataflow) are built. - # - # An `IVar` is a single-element container that is normally created empty, and - # can only be set once. The I in `IVar` stands for immutable. Reading an - # `IVar` normally blocks until it is set. It is safe to set and read an `IVar` - # from different threads. - # - # If you want to have some parallel task set the value in an `IVar`, you want - # a `Future`. If you want to create a graph of parallel tasks all executed - # when the values they depend on are ready you want `dataflow`. `IVar` is - # generally a low-level primitive. - # - # ## Examples - # - # Create, set and get an `IVar` - # - # ```ruby - # ivar = Concurrent::IVar.new - # ivar.set 14 - # ivar.value #=> 14 - # ivar.set 2 # would now be an error - # ``` - # - # ## See Also - # - # 1. For the theory: Arvind, R. Nikhil, and K. Pingali. - # [I-Structures: Data structures for parallel computing](http://dl.acm.org/citation.cfm?id=69562). - # In Proceedings of Workshop on Graph Reduction, 1986. - # 2. For recent application: - # [DataDrivenFuture in Habanero Java from Rice](http://www.cs.rice.edu/~vs3/hjlib/doc/edu/rice/hj/api/HjDataDrivenFuture.html). - class IVar < Synchronization::LockableObject - include Concern::Obligation - include Concern::Observable - - # Create a new `IVar` in the `:pending` state with the (optional) initial value. - # - # @param [Object] value the initial value - # @param [Hash] opts the options to create a message with - # @option opts [String] :dup_on_deref (false) call `#dup` before returning - # the data - # @option opts [String] :freeze_on_deref (false) call `#freeze` before - # returning the data - # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing - # the internal value and returning the value returned from the proc - def initialize(value = NULL, opts = {}, &block) - if value != NULL && block_given? - raise ArgumentError.new('provide only a value or a block') - end - super(&nil) - synchronize { ns_initialize(value, opts, &block) } - end - - # Add an observer on this object that will receive notification on update. - # - # Upon completion the `IVar` will notify all observers in a thread-safe way. - # The `func` method of the observer will be called with three arguments: the - # `Time` at which the `Future` completed the asynchronous operation, the - # final `value` (or `nil` on rejection), and the final `reason` (or `nil` on - # fulfillment). - # - # @param [Object] observer the object that will be notified of changes - # @param [Symbol] func symbol naming the method to call when this - # `Observable` has changes` - def add_observer(observer = nil, func = :update, &block) - raise ArgumentError.new('cannot provide both an observer and a block') if observer && block - direct_notification = false - - if block - observer = block - func = :call - end - - synchronize do - if event.set? - direct_notification = true - else - observers.add_observer(observer, func) - end - end - - observer.send(func, Time.now, self.value, reason) if direct_notification - observer - end - - # @!macro ivar_set_method - # Set the `IVar` to a value and wake or notify all threads waiting on it. - # - # @!macro ivar_set_parameters_and_exceptions - # @param [Object] value the value to store in the `IVar` - # @yield A block operation to use for setting the value - # @raise [ArgumentError] if both a value and a block are given - # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already - # been set or otherwise completed - # - # @return [IVar] self - def set(value = NULL) - check_for_block_or_value!(block_given?, value) - raise MultipleAssignmentError unless compare_and_set_state(:processing, :pending) - - begin - value = yield if block_given? - complete_without_notification(true, value, nil) - rescue => ex - complete_without_notification(false, nil, ex) - end - - notify_observers(self.value, reason) - self - end - - # @!macro ivar_fail_method - # Set the `IVar` to failed due to some error and wake or notify all threads waiting on it. - # - # @param [Object] reason for the failure - # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already - # been set or otherwise completed - # @return [IVar] self - def fail(reason = StandardError.new) - complete(false, nil, reason) - end - - # Attempt to set the `IVar` with the given value or block. Return a - # boolean indicating the success or failure of the set operation. - # - # @!macro ivar_set_parameters_and_exceptions - # - # @return [Boolean] true if the value was set else false - def try_set(value = NULL, &block) - set(value, &block) - true - rescue MultipleAssignmentError - false - end - - protected - - # @!visibility private - def ns_initialize(value, opts) - value = yield if block_given? - init_obligation - self.observers = Collection::CopyOnWriteObserverSet.new - set_deref_options(opts) - - @state = :pending - if value != NULL - ns_complete_without_notification(true, value, nil) - end - end - - # @!visibility private - def safe_execute(task, args = []) - if compare_and_set_state(:processing, :pending) - success, val, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) - complete(success, val, reason) - yield(success, val, reason) if block_given? - end - end - - # @!visibility private - def complete(success, value, reason) - complete_without_notification(success, value, reason) - notify_observers(self.value, reason) - self - end - - # @!visibility private - def complete_without_notification(success, value, reason) - synchronize { ns_complete_without_notification(success, value, reason) } - self - end - - # @!visibility private - def notify_observers(value, reason) - observers.notify_and_delete_observers{ [Time.now, value, reason] } - end - - # @!visibility private - def ns_complete_without_notification(success, value, reason) - raise MultipleAssignmentError if [:fulfilled, :rejected].include? @state - set_state(success, value, reason) - event.set - end - - # @!visibility private - def check_for_block_or_value!(block_given, value) # :nodoc: - if (block_given && value != NULL) || (! block_given && value == NULL) - raise ArgumentError.new('must set with either a value or a block') - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/map.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/map.rb deleted file mode 100644 index 601e365..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/map.rb +++ /dev/null @@ -1,350 +0,0 @@ -require 'thread' -require 'concurrent/constants' -require 'concurrent/utility/engine' - -module Concurrent - # @!visibility private - module Collection - - # @!visibility private - MapImplementation = case - when Concurrent.on_jruby? - require 'concurrent/utility/native_extension_loader' - # noinspection RubyResolve - JRubyMapBackend - when Concurrent.on_cruby? - require 'concurrent/collection/map/mri_map_backend' - MriMapBackend - when Concurrent.on_truffleruby? - if defined?(::TruffleRuby::ConcurrentMap) - require 'concurrent/collection/map/truffleruby_map_backend' - TruffleRubyMapBackend - else - require 'concurrent/collection/map/synchronized_map_backend' - SynchronizedMapBackend - end - else - warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' - require 'concurrent/collection/map/synchronized_map_backend' - SynchronizedMapBackend - end - end - - # `Concurrent::Map` is a hash-like object and should have much better performance - # characteristics, especially under high concurrency, than `Concurrent::Hash`. - # However, `Concurrent::Map `is not strictly semantically equivalent to a ruby `Hash` - # -- for instance, it does not necessarily retain ordering by insertion time as `Hash` - # does. For most uses it should do fine though, and we recommend you consider - # `Concurrent::Map` instead of `Concurrent::Hash` for your concurrency-safe hash needs. - class Map < Collection::MapImplementation - - # @!macro map.atomic_method - # This method is atomic. - - # @!macro map.atomic_method_with_block - # This method is atomic. - # @note Atomic methods taking a block do not allow the `self` instance - # to be used within the block. Doing so will cause a deadlock. - - # @!method []=(key, value) - # Set a value with key - # @param [Object] key - # @param [Object] value - # @return [Object] the new value - - # @!method compute_if_absent(key) - # Compute and store new value for key if the key is absent. - # @param [Object] key - # @yield new value - # @yieldreturn [Object] new value - # @return [Object] new value or current value - # @!macro map.atomic_method_with_block - - # @!method compute_if_present(key) - # Compute and store new value for key if the key is present. - # @param [Object] key - # @yield new value - # @yieldparam old_value [Object] - # @yieldreturn [Object, nil] new value, when nil the key is removed - # @return [Object, nil] new value or nil - # @!macro map.atomic_method_with_block - - # @!method compute(key) - # Compute and store new value for key. - # @param [Object] key - # @yield compute new value from old one - # @yieldparam old_value [Object, nil] old_value, or nil when key is absent - # @yieldreturn [Object, nil] new value, when nil the key is removed - # @return [Object, nil] new value or nil - # @!macro map.atomic_method_with_block - - # @!method merge_pair(key, value) - # If the key is absent, the value is stored, otherwise new value is - # computed with a block. - # @param [Object] key - # @param [Object] value - # @yield compute new value from old one - # @yieldparam old_value [Object] old value - # @yieldreturn [Object, nil] new value, when nil the key is removed - # @return [Object, nil] new value or nil - # @!macro map.atomic_method_with_block - - # @!method replace_pair(key, old_value, new_value) - # Replaces old_value with new_value if key exists and current value - # matches old_value - # @param [Object] key - # @param [Object] old_value - # @param [Object] new_value - # @return [true, false] true if replaced - # @!macro map.atomic_method - - # @!method replace_if_exists(key, new_value) - # Replaces current value with new_value if key exists - # @param [Object] key - # @param [Object] new_value - # @return [Object, nil] old value or nil - # @!macro map.atomic_method - - # @!method get_and_set(key, value) - # Get the current value under key and set new value. - # @param [Object] key - # @param [Object] value - # @return [Object, nil] old value or nil when the key was absent - # @!macro map.atomic_method - - # @!method delete(key) - # Delete key and its value. - # @param [Object] key - # @return [Object, nil] old value or nil when the key was absent - # @!macro map.atomic_method - - # @!method delete_pair(key, value) - # Delete pair and its value if current value equals the provided value. - # @param [Object] key - # @param [Object] value - # @return [true, false] true if deleted - # @!macro map.atomic_method - - # NonConcurrentMapBackend handles default_proc natively - unless defined?(Collection::NonConcurrentMapBackend) and self < Collection::NonConcurrentMapBackend - - # @param [Hash, nil] options options to set the :initial_capacity or :load_factor. Ignored on some Rubies. - # @param [Proc] default_proc Optional block to compute the default value if the key is not set, like `Hash#default_proc` - def initialize(options = nil, &default_proc) - if options.kind_of?(::Hash) - validate_options_hash!(options) - else - options = nil - end - - super(options) - @default_proc = default_proc - end - - # Get a value with key - # @param [Object] key - # @return [Object] the value - def [](key) - if value = super # non-falsy value is an existing mapping, return it right away - value - # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call - # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrent +nil+ value - # would be returned) - # note: nil == value check is not technically necessary - elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL)) - @default_proc.call(self, key) - else - value - end - end - end - - alias_method :get, :[] - alias_method :put, :[]= - - # Get a value with key, or default_value when key is absent, - # or fail when no default_value is given. - # @param [Object] key - # @param [Object] default_value - # @yield default value for a key - # @yieldparam key [Object] - # @yieldreturn [Object] default value - # @return [Object] the value or default value - # @raise [KeyError] when key is missing and no default_value is provided - # @!macro map_method_not_atomic - # @note The "fetch-then-act" methods of `Map` are not atomic. `Map` is intended - # to be use as a concurrency primitive with strong happens-before - # guarantees. It is not intended to be used as a high-level abstraction - # supporting complex operations. All read and write operations are - # thread safe, but no guarantees are made regarding race conditions - # between the fetch operation and yielding to the block. Additionally, - # this method does not support recursion. This is due to internal - # constraints that are very unlikely to change in the near future. - def fetch(key, default_value = NULL) - if NULL != (value = get_or_default(key, NULL)) - value - elsif block_given? - yield key - elsif NULL != default_value - default_value - else - raise_fetch_no_key - end - end - - # Fetch value with key, or store default value when key is absent, - # or fail when no default_value is given. This is a two step operation, - # therefore not atomic. The store can overwrite other concurrently - # stored value. - # @param [Object] key - # @param [Object] default_value - # @yield default value for a key - # @yieldparam key [Object] - # @yieldreturn [Object] default value - # @return [Object] the value or default value - def fetch_or_store(key, default_value = NULL) - fetch(key) do - put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value)) - end - end - - # Insert value into map with key if key is absent in one atomic step. - # @param [Object] key - # @param [Object] value - # @return [Object, nil] the previous value when key was present or nil when there was no key - def put_if_absent(key, value) - computed = false - result = compute_if_absent(key) do - computed = true - value - end - computed ? nil : result - end unless method_defined?(:put_if_absent) - - # Is the value stored in the map. Iterates over all values. - # @param [Object] value - # @return [true, false] - def value?(value) - each_value do |v| - return true if value.equal?(v) - end - false - end - - # All keys - # @return [::Array] keys - def keys - arr = [] - each_pair { |k, v| arr << k } - arr - end unless method_defined?(:keys) - - # All values - # @return [::Array] values - def values - arr = [] - each_pair { |k, v| arr << v } - arr - end unless method_defined?(:values) - - # Iterates over each key. - # @yield for each key in the map - # @yieldparam key [Object] - # @return [self] - # @!macro map.atomic_method_with_block - def each_key - each_pair { |k, v| yield k } - end unless method_defined?(:each_key) - - # Iterates over each value. - # @yield for each value in the map - # @yieldparam value [Object] - # @return [self] - # @!macro map.atomic_method_with_block - def each_value - each_pair { |k, v| yield v } - end unless method_defined?(:each_value) - - # Iterates over each key value pair. - # @yield for each key value pair in the map - # @yieldparam key [Object] - # @yieldparam value [Object] - # @return [self] - # @!macro map.atomic_method_with_block - def each_pair - return enum_for :each_pair unless block_given? - super - end - - alias_method :each, :each_pair unless method_defined?(:each) - - # Find key of a value. - # @param [Object] value - # @return [Object, nil] key or nil when not found - def key(value) - each_pair { |k, v| return k if v == value } - nil - end unless method_defined?(:key) - - # Is map empty? - # @return [true, false] - def empty? - each_pair { |k, v| return false } - true - end unless method_defined?(:empty?) - - # The size of map. - # @return [Integer] size - def size - count = 0 - each_pair { |k, v| count += 1 } - count - end unless method_defined?(:size) - - # @!visibility private - def marshal_dump - raise TypeError, "can't dump hash with default proc" if @default_proc - h = {} - each_pair { |k, v| h[k] = v } - h - end - - # @!visibility private - def marshal_load(hash) - initialize - populate_from(hash) - end - - undef :freeze - - # @!visibility private - def inspect - format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect - end - - private - - def raise_fetch_no_key - raise KeyError, 'key not found' - end - - def initialize_copy(other) - super - populate_from(other) - end - - def populate_from(hash) - hash.each_pair { |k, v| self[k] = v } - self - end - - def validate_options_hash!(options) - if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Integer) || initial_capacity < 0) - raise ArgumentError, ":initial_capacity must be a positive Integer" - end - if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1) - raise ArgumentError, ":load_factor must be a number between 0 and 1" - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/maybe.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/maybe.rb deleted file mode 100644 index 317c82b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/maybe.rb +++ /dev/null @@ -1,229 +0,0 @@ -require 'concurrent/synchronization/object' - -module Concurrent - - # A `Maybe` encapsulates an optional value. A `Maybe` either contains a value - # of (represented as `Just`), or it is empty (represented as `Nothing`). Using - # `Maybe` is a good way to deal with errors or exceptional cases without - # resorting to drastic measures such as exceptions. - # - # `Maybe` is a replacement for the use of `nil` with better type checking. - # - # For compatibility with {Concurrent::Concern::Obligation} the predicate and - # accessor methods are aliased as `fulfilled?`, `rejected?`, `value`, and - # `reason`. - # - # ## Motivation - # - # A common pattern in languages with pattern matching, such as Erlang and - # Haskell, is to return *either* a value *or* an error from a function - # Consider this Erlang code: - # - # ```erlang - # case file:consult("data.dat") of - # {ok, Terms} -> do_something_useful(Terms); - # {error, Reason} -> lager:error(Reason) - # end. - # ``` - # - # In this example the standard library function `file:consult` returns a - # [tuple](http://erlang.org/doc/reference_manual/data_types.html#id69044) - # with two elements: an [atom](http://erlang.org/doc/reference_manual/data_types.html#id64134) - # (similar to a ruby symbol) and a variable containing ancillary data. On - # success it returns the atom `ok` and the data from the file. On failure it - # returns `error` and a string with an explanation of the problem. With this - # pattern there is no ambiguity regarding success or failure. If the file is - # empty the return value cannot be misinterpreted as an error. And when an - # error occurs the return value provides useful information. - # - # In Ruby we tend to return `nil` when an error occurs or else we raise an - # exception. Both of these idioms are problematic. Returning `nil` is - # ambiguous because `nil` may also be a valid value. It also lacks - # information pertaining to the nature of the error. Raising an exception - # is both expensive and usurps the normal flow of control. All of these - # problems can be solved with the use of a `Maybe`. - # - # A `Maybe` is unambiguous with regard to whether or not it contains a value. - # When `Just` it contains a value, when `Nothing` it does not. When `Just` - # the value it contains may be `nil`, which is perfectly valid. When - # `Nothing` the reason for the lack of a value is contained as well. The - # previous Erlang example can be duplicated in Ruby in a principled way by - # having functions return `Maybe` objects: - # - # ```ruby - # result = MyFileUtils.consult("data.dat") # returns a Maybe - # if result.just? - # do_something_useful(result.value) # or result.just - # else - # logger.error(result.reason) # or result.nothing - # end - # ``` - # - # @example Returning a Maybe from a Function - # module MyFileUtils - # def self.consult(path) - # file = File.open(path, 'r') - # Concurrent::Maybe.just(file.read) - # rescue => ex - # return Concurrent::Maybe.nothing(ex) - # ensure - # file.close if file - # end - # end - # - # maybe = MyFileUtils.consult('bogus.file') - # maybe.just? #=> false - # maybe.nothing? #=> true - # maybe.reason #=> # - # - # maybe = MyFileUtils.consult('README.md') - # maybe.just? #=> true - # maybe.nothing? #=> false - # maybe.value #=> "# Concurrent Ruby\n[![Gem Version..." - # - # @example Using Maybe with a Block - # result = Concurrent::Maybe.from do - # Client.find(10) # Client is an ActiveRecord model - # end - # - # # -- if the record was found - # result.just? #=> true - # result.value #=> # - # - # # -- if the record was not found - # result.just? #=> false - # result.reason #=> ActiveRecord::RecordNotFound - # - # @example Using Maybe with the Null Object Pattern - # # In a Rails controller... - # result = ClientService.new(10).find # returns a Maybe - # render json: result.or(NullClient.new) - # - # @see https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html Haskell Data.Maybe - # @see https://github.com/purescript/purescript-maybe/blob/master/docs/Data.Maybe.md PureScript Data.Maybe - class Maybe < Synchronization::Object - include Comparable - safe_initialization! - - # Indicates that the given attribute has not been set. - # When `Just` the {#nothing} getter will return `NONE`. - # When `Nothing` the {#just} getter will return `NONE`. - NONE = ::Object.new.freeze - - # The value of a `Maybe` when `Just`. Will be `NONE` when `Nothing`. - attr_reader :just - - # The reason for the `Maybe` when `Nothing`. Will be `NONE` when `Just`. - attr_reader :nothing - - private_class_method :new - - # Create a new `Maybe` using the given block. - # - # Runs the given block passing all function arguments to the block as block - # arguments. If the block runs to completion without raising an exception - # a new `Just` is created with the value set to the return value of the - # block. If the block raises an exception a new `Nothing` is created with - # the reason being set to the raised exception. - # - # @param [Array] args Zero or more arguments to pass to the block. - # @yield The block from which to create a new `Maybe`. - # @yieldparam [Array] args Zero or more block arguments passed as - # arguments to the function. - # - # @return [Maybe] The newly created object. - # - # @raise [ArgumentError] when no block given. - def self.from(*args) - raise ArgumentError.new('no block given') unless block_given? - begin - value = yield(*args) - return new(value, NONE) - rescue => ex - return new(NONE, ex) - end - end - - # Create a new `Just` with the given value. - # - # @param [Object] value The value to set for the new `Maybe` object. - # - # @return [Maybe] The newly created object. - def self.just(value) - return new(value, NONE) - end - - # Create a new `Nothing` with the given (optional) reason. - # - # @param [Exception] error The reason to set for the new `Maybe` object. - # When given a string a new `StandardError` will be created with the - # argument as the message. When no argument is given a new - # `StandardError` with an empty message will be created. - # - # @return [Maybe] The newly created object. - def self.nothing(error = '') - if error.is_a?(Exception) - nothing = error - else - nothing = StandardError.new(error.to_s) - end - return new(NONE, nothing) - end - - # Is this `Maybe` a `Just` (successfully fulfilled with a value)? - # - # @return [Boolean] True if `Just` or false if `Nothing`. - def just? - ! nothing? - end - alias :fulfilled? :just? - - # Is this `Maybe` a `nothing` (rejected with an exception upon fulfillment)? - # - # @return [Boolean] True if `Nothing` or false if `Just`. - def nothing? - @nothing != NONE - end - alias :rejected? :nothing? - - alias :value :just - - alias :reason :nothing - - # Comparison operator. - # - # @return [Integer] 0 if self and other are both `Nothing`; - # -1 if self is `Nothing` and other is `Just`; - # 1 if self is `Just` and other is nothing; - # `self.just <=> other.just` if both self and other are `Just`. - def <=>(other) - if nothing? - other.nothing? ? 0 : -1 - else - other.nothing? ? 1 : just <=> other.just - end - end - - # Return either the value of self or the given default value. - # - # @return [Object] The value of self when `Just`; else the given default. - def or(other) - just? ? just : other - end - - private - - # Create a new `Maybe` with the given attributes. - # - # @param [Object] just The value when `Just` else `NONE`. - # @param [Exception, Object] nothing The exception when `Nothing` else `NONE`. - # - # @return [Maybe] The new `Maybe`. - # - # @!visibility private - def initialize(just, nothing) - @just = just - @nothing = nothing - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mutable_struct.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mutable_struct.rb deleted file mode 100644 index 5d0e9b9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mutable_struct.rb +++ /dev/null @@ -1,239 +0,0 @@ -require 'concurrent/synchronization/abstract_struct' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # An thread-safe variation of Ruby's standard `Struct`. Values can be set at - # construction or safely changed at any time during the object's lifecycle. - # - # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` - module MutableStruct - include Synchronization::AbstractStruct - - # @!macro struct_new - # - # Factory for creating new struct classes. - # - # ``` - # new([class_name] [, member_name]+>) -> StructClass click to toggle source - # new([class_name] [, member_name]+>) {|StructClass| block } -> StructClass - # new(value, ...) -> obj - # StructClass[value, ...] -> obj - # ``` - # - # The first two forms are used to create a new struct subclass `class_name` - # that can contain a value for each member_name . This subclass can be - # used to create instances of the structure like any other Class . - # - # If the `class_name` is omitted an anonymous struct class will be created. - # Otherwise, the name of this struct will appear as a constant in the struct class, - # so it must be unique for all structs under this base class and must start with a - # capital letter. Assigning a struct class to a constant also gives the class - # the name of the constant. - # - # If a block is given it will be evaluated in the context of `StructClass`, passing - # the created class as a parameter. This is the recommended way to customize a struct. - # Subclassing an anonymous struct creates an extra anonymous class that will never be used. - # - # The last two forms create a new instance of a struct subclass. The number of value - # parameters must be less than or equal to the number of attributes defined for the - # struct. Unset parameters default to nil. Passing more parameters than number of attributes - # will raise an `ArgumentError`. - # - # @see http://ruby-doc.org/core/Struct.html#method-c-new Ruby standard library `Struct#new` - - # @!macro struct_values - # - # Returns the values for this struct as an Array. - # - # @return [Array] the values for this struct - # - def values - synchronize { ns_values } - end - alias_method :to_a, :values - - # @!macro struct_values_at - # - # Returns the struct member values for each selector as an Array. - # - # A selector may be either an Integer offset or a Range of offsets (as in `Array#values_at`). - # - # @param [Fixnum, Range] indexes the index(es) from which to obatin the values (in order) - def values_at(*indexes) - synchronize { ns_values_at(indexes) } - end - - # @!macro struct_inspect - # - # Describe the contents of this struct in a string. - # - # @return [String] the contents of this struct in a string - def inspect - synchronize { ns_inspect } - end - alias_method :to_s, :inspect - - # @!macro struct_merge - # - # Returns a new struct containing the contents of `other` and the contents - # of `self`. If no block is specified, the value for entries with duplicate - # keys will be that of `other`. Otherwise the value for each duplicate key - # is determined by calling the block with the key, its value in `self` and - # its value in `other`. - # - # @param [Hash] other the hash from which to set the new values - # @yield an options block for resolving duplicate keys - # @yieldparam [String, Symbol] member the name of the member which is duplicated - # @yieldparam [Object] selfvalue the value of the member in `self` - # @yieldparam [Object] othervalue the value of the member in `other` - # - # @return [Synchronization::AbstractStruct] a new struct with the new values - # - # @raise [ArgumentError] of given a member that is not defined in the struct - def merge(other, &block) - synchronize { ns_merge(other, &block) } - end - - # @!macro struct_to_h - # - # Returns a hash containing the names and values for the struct’s members. - # - # @return [Hash] the names and values for the struct’s members - def to_h - synchronize { ns_to_h } - end - - # @!macro struct_get - # - # Attribute Reference - # - # @param [Symbol, String, Integer] member the string or symbol name of the member - # for which to obtain the value or the member's index - # - # @return [Object] the value of the given struct member or the member at the given index. - # - # @raise [NameError] if the member does not exist - # @raise [IndexError] if the index is out of range. - def [](member) - synchronize { ns_get(member) } - end - - # @!macro struct_equality - # - # Equality - # - # @return [Boolean] true if other has the same struct subclass and has - # equal member values (according to `Object#==`) - def ==(other) - synchronize { ns_equality(other) } - end - - # @!macro struct_each - # - # Yields the value of each struct member in order. If no block is given - # an enumerator is returned. - # - # @yield the operation to be performed on each struct member - # @yieldparam [Object] value each struct value (in order) - def each(&block) - return enum_for(:each) unless block_given? - synchronize { ns_each(&block) } - end - - # @!macro struct_each_pair - # - # Yields the name and value of each struct member in order. If no block is - # given an enumerator is returned. - # - # @yield the operation to be performed on each struct member/value pair - # @yieldparam [Object] member each struct member (in order) - # @yieldparam [Object] value each struct value (in order) - def each_pair(&block) - return enum_for(:each_pair) unless block_given? - synchronize { ns_each_pair(&block) } - end - - # @!macro struct_select - # - # Yields each member value from the struct to the block and returns an Array - # containing the member values from the struct for which the given block - # returns a true value (equivalent to `Enumerable#select`). - # - # @yield the operation to be performed on each struct member - # @yieldparam [Object] value each struct value (in order) - # - # @return [Array] an array containing each value for which the block returns true - def select(&block) - return enum_for(:select) unless block_given? - synchronize { ns_select(&block) } - end - - # @!macro struct_set - # - # Attribute Assignment - # - # Sets the value of the given struct member or the member at the given index. - # - # @param [Symbol, String, Integer] member the string or symbol name of the member - # for which to obtain the value or the member's index - # - # @return [Object] the value of the given struct member or the member at the given index. - # - # @raise [NameError] if the name does not exist - # @raise [IndexError] if the index is out of range. - def []=(member, value) - if member.is_a? Integer - length = synchronize { @values.length } - if member >= length - raise IndexError.new("offset #{member} too large for struct(size:#{length})") - end - synchronize { @values[member] = value } - else - send("#{member}=", value) - end - rescue NoMethodError - raise NameError.new("no member '#{member}' in struct") - end - - private - - # @!visibility private - def initialize_copy(original) - synchronize do - super(original) - ns_initialize_copy - end - end - - # @!macro struct_new - def self.new(*args, &block) - clazz_name = nil - if args.length == 0 - raise ArgumentError.new('wrong number of arguments (0 for 1+)') - elsif args.length > 0 && args.first.is_a?(String) - clazz_name = args.shift - end - FACTORY.define_struct(clazz_name, args, &block) - end - - FACTORY = Class.new(Synchronization::LockableObject) do - def define_struct(name, members, &block) - synchronize do - clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block) - members.each_with_index do |member, index| - clazz.send :remove_method, member - clazz.send(:define_method, member) do - synchronize { @values[index] } - end - clazz.send(:define_method, "#{member}=") do |value| - synchronize { @values[index] = value } - end - end - clazz - end - end - end.new - private_constant :FACTORY - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mvar.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mvar.rb deleted file mode 100644 index dfc4195..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/mvar.rb +++ /dev/null @@ -1,242 +0,0 @@ -require 'concurrent/concern/dereferenceable' -require 'concurrent/synchronization/object' - -module Concurrent - - # An `MVar` is a synchronized single element container. They are empty or - # contain one item. Taking a value from an empty `MVar` blocks, as does - # putting a value into a full one. You can either think of them as blocking - # queue of length one, or a special kind of mutable variable. - # - # On top of the fundamental `#put` and `#take` operations, we also provide a - # `#mutate` that is atomic with respect to operations on the same instance. - # These operations all support timeouts. - # - # We also support non-blocking operations `#try_put!` and `#try_take!`, a - # `#set!` that ignores existing values, a `#value` that returns the value - # without removing it or returns `MVar::EMPTY`, and a `#modify!` that yields - # `MVar::EMPTY` if the `MVar` is empty and can be used to set `MVar::EMPTY`. - # You shouldn't use these operations in the first instance. - # - # `MVar` is a [Dereferenceable](Dereferenceable). - # - # `MVar` is related to M-structures in Id, `MVar` in Haskell and `SyncVar` in Scala. - # - # Note that unlike the original Haskell paper, our `#take` is blocking. This is how - # Haskell and Scala do it today. - # - # @!macro copy_options - # - # ## See Also - # - # 1. P. Barth, R. Nikhil, and Arvind. [M-Structures: Extending a parallel, non- strict, functional language with state](http://dl.acm.org/citation.cfm?id=652538). In Proceedings of the 5th - # ACM Conference on Functional Programming Languages and Computer Architecture (FPCA), 1991. - # - # 2. S. Peyton Jones, A. Gordon, and S. Finne. [Concurrent Haskell](http://dl.acm.org/citation.cfm?id=237794). - # In Proceedings of the 23rd Symposium on Principles of Programming Languages - # (PoPL), 1996. - class MVar < Synchronization::Object - include Concern::Dereferenceable - safe_initialization! - - # Unique value that represents that an `MVar` was empty - EMPTY = ::Object.new - - # Unique value that represents that an `MVar` timed out before it was able - # to produce a value. - TIMEOUT = ::Object.new - - # Create a new `MVar`, either empty or with an initial value. - # - # @param [Hash] opts the options controlling how the future will be processed - # - # @!macro deref_options - def initialize(value = EMPTY, opts = {}) - @value = value - @mutex = Mutex.new - @empty_condition = ConditionVariable.new - @full_condition = ConditionVariable.new - set_deref_options(opts) - end - - # Remove the value from an `MVar`, leaving it empty, and blocking if there - # isn't a value. A timeout can be set to limit the time spent blocked, in - # which case it returns `TIMEOUT` if the time is exceeded. - # @return [Object] the value that was taken, or `TIMEOUT` - def take(timeout = nil) - @mutex.synchronize do - wait_for_full(timeout) - - # If we timed out we'll still be empty - if unlocked_full? - value = @value - @value = EMPTY - @empty_condition.signal - apply_deref_options(value) - else - TIMEOUT - end - end - end - - # acquires lock on the from an `MVAR`, yields the value to provided block, - # and release lock. A timeout can be set to limit the time spent blocked, - # in which case it returns `TIMEOUT` if the time is exceeded. - # @return [Object] the value returned by the block, or `TIMEOUT` - def borrow(timeout = nil) - @mutex.synchronize do - wait_for_full(timeout) - - # if we timeoud out we'll still be empty - if unlocked_full? - yield @value - else - TIMEOUT - end - end - end - - # Put a value into an `MVar`, blocking if there is already a value until - # it is empty. A timeout can be set to limit the time spent blocked, in - # which case it returns `TIMEOUT` if the time is exceeded. - # @return [Object] the value that was put, or `TIMEOUT` - def put(value, timeout = nil) - @mutex.synchronize do - wait_for_empty(timeout) - - # If we timed out we won't be empty - if unlocked_empty? - @value = value - @full_condition.signal - apply_deref_options(value) - else - TIMEOUT - end - end - end - - # Atomically `take`, yield the value to a block for transformation, and then - # `put` the transformed value. Returns the transformed value. A timeout can - # be set to limit the time spent blocked, in which case it returns `TIMEOUT` - # if the time is exceeded. - # @return [Object] the transformed value, or `TIMEOUT` - def modify(timeout = nil) - raise ArgumentError.new('no block given') unless block_given? - - @mutex.synchronize do - wait_for_full(timeout) - - # If we timed out we'll still be empty - if unlocked_full? - value = @value - @value = yield value - @full_condition.signal - apply_deref_options(value) - else - TIMEOUT - end - end - end - - # Non-blocking version of `take`, that returns `EMPTY` instead of blocking. - def try_take! - @mutex.synchronize do - if unlocked_full? - value = @value - @value = EMPTY - @empty_condition.signal - apply_deref_options(value) - else - EMPTY - end - end - end - - # Non-blocking version of `put`, that returns whether or not it was successful. - def try_put!(value) - @mutex.synchronize do - if unlocked_empty? - @value = value - @full_condition.signal - true - else - false - end - end - end - - # Non-blocking version of `put` that will overwrite an existing value. - def set!(value) - @mutex.synchronize do - old_value = @value - @value = value - @full_condition.signal - apply_deref_options(old_value) - end - end - - # Non-blocking version of `modify` that will yield with `EMPTY` if there is no value yet. - def modify! - raise ArgumentError.new('no block given') unless block_given? - - @mutex.synchronize do - value = @value - @value = yield value - if unlocked_empty? - @empty_condition.signal - else - @full_condition.signal - end - apply_deref_options(value) - end - end - - # Returns if the `MVar` is currently empty. - def empty? - @mutex.synchronize { @value == EMPTY } - end - - # Returns if the `MVar` currently contains a value. - def full? - !empty? - end - - protected - - def synchronize(&block) - @mutex.synchronize(&block) - end - - private - - def unlocked_empty? - @value == EMPTY - end - - def unlocked_full? - ! unlocked_empty? - end - - def wait_for_full(timeout) - wait_while(@full_condition, timeout) { unlocked_empty? } - end - - def wait_for_empty(timeout) - wait_while(@empty_condition, timeout) { unlocked_full? } - end - - def wait_while(condition, timeout) - if timeout.nil? - while yield - condition.wait(@mutex) - end - else - stop = Concurrent.monotonic_time + timeout - while yield && timeout > 0.0 - condition.wait(@mutex, timeout) - timeout = stop - Concurrent.monotonic_time - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/options.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/options.rb deleted file mode 100644 index bdd22a9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/options.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'concurrent/configuration' - -module Concurrent - - # @!visibility private - module Options - - # Get the requested `Executor` based on the values set in the options hash. - # - # @param [Hash] opts the options defining the requested executor - # @option opts [Executor] :executor when set use the given `Executor` instance. - # Three special values are also supported: `:fast` returns the global fast executor, - # `:io` returns the global io executor, and `:immediate` returns a new - # `ImmediateExecutor` object. - # - # @return [Executor, nil] the requested thread pool, or nil when no option specified - # - # @!visibility private - def self.executor_from_options(opts = {}) # :nodoc: - if identifier = opts.fetch(:executor, nil) - executor(identifier) - else - nil - end - end - - def self.executor(executor_identifier) - case executor_identifier - when :fast - Concurrent.global_fast_executor - when :io - Concurrent.global_io_executor - when :immediate - Concurrent.global_immediate_executor - when Concurrent::ExecutorService - executor_identifier - else - raise ArgumentError, "executor not recognized by '#{executor_identifier}'" - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promise.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promise.rb deleted file mode 100644 index ccc47dd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promise.rb +++ /dev/null @@ -1,580 +0,0 @@ -require 'thread' -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/ivar' -require 'concurrent/executor/safe_task_executor' - -require 'concurrent/options' - -module Concurrent - - PromiseExecutionError = Class.new(StandardError) - - # Promises are inspired by the JavaScript [Promises/A](http://wiki.commonjs.org/wiki/Promises/A) - # and [Promises/A+](http://promises-aplus.github.io/promises-spec/) specifications. - # - # > A promise represents the eventual value returned from the single - # > completion of an operation. - # - # Promises are similar to futures and share many of the same behaviours. - # Promises are far more robust, however. Promises can be chained in a tree - # structure where each promise may have zero or more children. Promises are - # chained using the `then` method. The result of a call to `then` is always - # another promise. Promises are resolved asynchronously (with respect to the - # main thread) but in a strict order: parents are guaranteed to be resolved - # before their children, children before their younger siblings. The `then` - # method takes two parameters: an optional block to be executed upon parent - # resolution and an optional callable to be executed upon parent failure. The - # result of each promise is passed to each of its children upon resolution. - # When a promise is rejected all its children will be summarily rejected and - # will receive the reason. - # - # Promises have several possible states: *:unscheduled*, *:pending*, - # *:processing*, *:rejected*, or *:fulfilled*. These are also aggregated as - # `#incomplete?` and `#complete?`. When a Promise is created it is set to - # *:unscheduled*. Once the `#execute` method is called the state becomes - # *:pending*. Once a job is pulled from the thread pool's queue and is given - # to a thread for processing (often immediately upon `#post`) the state - # becomes *:processing*. The future will remain in this state until processing - # is complete. A future that is in the *:unscheduled*, *:pending*, or - # *:processing* is considered `#incomplete?`. A `#complete?` Promise is either - # *:rejected*, indicating that an exception was thrown during processing, or - # *:fulfilled*, indicating success. If a Promise is *:fulfilled* its `#value` - # will be updated to reflect the result of the operation. If *:rejected* the - # `reason` will be updated with a reference to the thrown exception. The - # predicate methods `#unscheduled?`, `#pending?`, `#rejected?`, and - # `#fulfilled?` can be called at any time to obtain the state of the Promise, - # as can the `#state` method, which returns a symbol. - # - # Retrieving the value of a promise is done through the `value` (alias: - # `deref`) method. Obtaining the value of a promise is a potentially blocking - # operation. When a promise is *rejected* a call to `value` will return `nil` - # immediately. When a promise is *fulfilled* a call to `value` will - # immediately return the current value. When a promise is *pending* a call to - # `value` will block until the promise is either *rejected* or *fulfilled*. A - # *timeout* value can be passed to `value` to limit how long the call will - # block. If `nil` the call will block indefinitely. If `0` the call will not - # block. Any other integer or float value will indicate the maximum number of - # seconds to block. - # - # Promises run on the global thread pool. - # - # @!macro copy_options - # - # ### Examples - # - # Start by requiring promises - # - # ```ruby - # require 'concurrent/promise' - # ``` - # - # Then create one - # - # ```ruby - # p = Concurrent::Promise.execute do - # # do something - # 42 - # end - # ``` - # - # Promises can be chained using the `then` method. The `then` method accepts a - # block and an executor, to be executed on fulfillment, and a callable argument to be executed - # on rejection. The result of the each promise is passed as the block argument - # to chained promises. - # - # ```ruby - # p = Concurrent::Promise.new{10}.then{|x| x * 2}.then{|result| result - 10 }.execute - # ``` - # - # And so on, and so on, and so on... - # - # ```ruby - # p = Concurrent::Promise.fulfill(20). - # then{|result| result - 10 }. - # then{|result| result * 3 }. - # then(executor: different_executor){|result| result % 5 }.execute - # ``` - # - # The initial state of a newly created Promise depends on the state of its parent: - # - if parent is *unscheduled* the child will be *unscheduled* - # - if parent is *pending* the child will be *pending* - # - if parent is *fulfilled* the child will be *pending* - # - if parent is *rejected* the child will be *pending* (but will ultimately be *rejected*) - # - # Promises are executed asynchronously from the main thread. By the time a - # child Promise finishes intialization it may be in a different state than its - # parent (by the time a child is created its parent may have completed - # execution and changed state). Despite being asynchronous, however, the order - # of execution of Promise objects in a chain (or tree) is strictly defined. - # - # There are multiple ways to create and execute a new `Promise`. Both ways - # provide identical behavior: - # - # ```ruby - # # create, operate, then execute - # p1 = Concurrent::Promise.new{ "Hello World!" } - # p1.state #=> :unscheduled - # p1.execute - # - # # create and immediately execute - # p2 = Concurrent::Promise.new{ "Hello World!" }.execute - # - # # execute during creation - # p3 = Concurrent::Promise.execute{ "Hello World!" } - # ``` - # - # Once the `execute` method is called a `Promise` becomes `pending`: - # - # ```ruby - # p = Concurrent::Promise.execute{ "Hello, world!" } - # p.state #=> :pending - # p.pending? #=> true - # ``` - # - # Wait a little bit, and the promise will resolve and provide a value: - # - # ```ruby - # p = Concurrent::Promise.execute{ "Hello, world!" } - # sleep(0.1) - # - # p.state #=> :fulfilled - # p.fulfilled? #=> true - # p.value #=> "Hello, world!" - # ``` - # - # If an exception occurs, the promise will be rejected and will provide - # a reason for the rejection: - # - # ```ruby - # p = Concurrent::Promise.execute{ raise StandardError.new("Here comes the Boom!") } - # sleep(0.1) - # - # p.state #=> :rejected - # p.rejected? #=> true - # p.reason #=> "#" - # ``` - # - # #### Rejection - # - # When a promise is rejected all its children will be rejected and will - # receive the rejection `reason` as the rejection callable parameter: - # - # ```ruby - # p = Concurrent::Promise.execute { Thread.pass; raise StandardError } - # - # c1 = p.then(-> reason { 42 }) - # c2 = p.then(-> reason { raise 'Boom!' }) - # - # c1.wait.state #=> :fulfilled - # c1.value #=> 45 - # c2.wait.state #=> :rejected - # c2.reason #=> # - # ``` - # - # Once a promise is rejected it will continue to accept children that will - # receive immediately rejection (they will be executed asynchronously). - # - # #### Aliases - # - # The `then` method is the most generic alias: it accepts a block to be - # executed upon parent fulfillment and a callable to be executed upon parent - # rejection. At least one of them should be passed. The default block is `{ - # |result| result }` that fulfills the child with the parent value. The - # default callable is `{ |reason| raise reason }` that rejects the child with - # the parent reason. - # - # - `on_success { |result| ... }` is the same as `then {|result| ... }` - # - `rescue { |reason| ... }` is the same as `then(Proc.new { |reason| ... } )` - # - `rescue` is aliased by `catch` and `on_error` - class Promise < IVar - - # Initialize a new Promise with the provided options. - # - # @!macro executor_and_deref_options - # - # @!macro promise_init_options - # - # @option opts [Promise] :parent the parent `Promise` when building a chain/tree - # @option opts [Proc] :on_fulfill fulfillment handler - # @option opts [Proc] :on_reject rejection handler - # @option opts [object, Array] :args zero or more arguments to be passed - # the task block on execution - # - # @yield The block operation to be performed asynchronously. - # - # @raise [ArgumentError] if no block is given - # - # @see http://wiki.commonjs.org/wiki/Promises/A - # @see http://promises-aplus.github.io/promises-spec/ - def initialize(opts = {}, &block) - opts.delete_if { |k, v| v.nil? } - super(NULL, opts.merge(__promise_body_from_block__: block), &nil) - end - - # Create a new `Promise` and fulfill it immediately. - # - # @!macro executor_and_deref_options - # - # @!macro promise_init_options - # - # @raise [ArgumentError] if no block is given - # - # @return [Promise] the newly created `Promise` - def self.fulfill(value, opts = {}) - Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, true, value, nil) } - end - - # Create a new `Promise` and reject it immediately. - # - # @!macro executor_and_deref_options - # - # @!macro promise_init_options - # - # @raise [ArgumentError] if no block is given - # - # @return [Promise] the newly created `Promise` - def self.reject(reason, opts = {}) - Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, false, nil, reason) } - end - - # Execute an `:unscheduled` `Promise`. Immediately sets the state to `:pending` and - # passes the block to a new thread/thread pool for eventual execution. - # Does nothing if the `Promise` is in any state other than `:unscheduled`. - # - # @return [Promise] a reference to `self` - def execute - if root? - if compare_and_set_state(:pending, :unscheduled) - set_pending - realize(@promise_body) - end - else - compare_and_set_state(:pending, :unscheduled) - @parent.execute - end - self - end - - # @!macro ivar_set_method - # - # @raise [Concurrent::PromiseExecutionError] if not the root promise - def set(value = NULL, &block) - raise PromiseExecutionError.new('supported only on root promise') unless root? - check_for_block_or_value!(block_given?, value) - synchronize do - if @state != :unscheduled - raise MultipleAssignmentError - else - @promise_body = block || Proc.new { |result| value } - end - end - execute - end - - # @!macro ivar_fail_method - # - # @raise [Concurrent::PromiseExecutionError] if not the root promise - def fail(reason = StandardError.new) - set { raise reason } - end - - # Create a new `Promise` object with the given block, execute it, and return the - # `:pending` object. - # - # @!macro executor_and_deref_options - # - # @!macro promise_init_options - # - # @return [Promise] the newly created `Promise` in the `:pending` state - # - # @raise [ArgumentError] if no block is given - # - # @example - # promise = Concurrent::Promise.execute{ sleep(1); 42 } - # promise.state #=> :pending - def self.execute(opts = {}, &block) - new(opts, &block).execute - end - - # Chain a new promise off the current promise. - # - # @return [Promise] the new promise - # @yield The block operation to be performed asynchronously. - # @overload then(rescuer, executor, &block) - # @param [Proc] rescuer An optional rescue block to be executed if the - # promise is rejected. - # @param [ThreadPool] executor An optional thread pool executor to be used - # in the new Promise - # @overload then(rescuer, executor: executor, &block) - # @param [Proc] rescuer An optional rescue block to be executed if the - # promise is rejected. - # @param [ThreadPool] executor An optional thread pool executor to be used - # in the new Promise - def then(*args, &block) - if args.last.is_a?(::Hash) - executor = args.pop[:executor] - rescuer = args.first - else - rescuer, executor = args - end - - executor ||= @executor - - raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given? - block = Proc.new { |result| result } unless block_given? - child = Promise.new( - parent: self, - executor: executor, - on_fulfill: block, - on_reject: rescuer - ) - - synchronize do - child.state = :pending if @state == :pending - child.on_fulfill(apply_deref_options(@value)) if @state == :fulfilled - child.on_reject(@reason) if @state == :rejected - @children << child - end - - child - end - - # Chain onto this promise an action to be undertaken on success - # (fulfillment). - # - # @yield The block to execute - # - # @return [Promise] self - def on_success(&block) - raise ArgumentError.new('no block given') unless block_given? - self.then(&block) - end - - # Chain onto this promise an action to be undertaken on failure - # (rejection). - # - # @yield The block to execute - # - # @return [Promise] self - def rescue(&block) - self.then(block) - end - - alias_method :catch, :rescue - alias_method :on_error, :rescue - - # Yield the successful result to the block that returns a promise. If that - # promise is also successful the result is the result of the yielded promise. - # If either part fails the whole also fails. - # - # @example - # Promise.execute { 1 }.flat_map { |v| Promise.execute { v + 2 } }.value! #=> 3 - # - # @return [Promise] - def flat_map(&block) - child = Promise.new( - parent: self, - executor: ImmediateExecutor.new, - ) - - on_error { |e| child.on_reject(e) } - on_success do |result1| - begin - inner = block.call(result1) - inner.execute - inner.on_success { |result2| child.on_fulfill(result2) } - inner.on_error { |e| child.on_reject(e) } - rescue => e - child.on_reject(e) - end - end - - child - end - - # Builds a promise that produces the result of promises in an Array - # and fails if any of them fails. - # - # @overload zip(*promises) - # @param [Array] promises - # - # @overload zip(*promises, opts) - # @param [Array] promises - # @param [Hash] opts the configuration options - # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. - # @option opts [Boolean] :execute (true) execute promise before returning - # - # @return [Promise] - def self.zip(*promises) - opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {} - opts[:executor] ||= ImmediateExecutor.new - zero = if !opts.key?(:execute) || opts.delete(:execute) - fulfill([], opts) - else - Promise.new(opts) { [] } - end - - promises.reduce(zero) do |p1, p2| - p1.flat_map do |results| - p2.then do |next_result| - results << next_result - end - end - end - end - - # Builds a promise that produces the result of self and others in an Array - # and fails if any of them fails. - # - # @overload zip(*promises) - # @param [Array] others - # - # @overload zip(*promises, opts) - # @param [Array] others - # @param [Hash] opts the configuration options - # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. - # @option opts [Boolean] :execute (true) execute promise before returning - # - # @return [Promise] - def zip(*others) - self.class.zip(self, *others) - end - - # Aggregates a collection of promises and executes the `then` condition - # if all aggregated promises succeed. Executes the `rescue` handler with - # a `Concurrent::PromiseExecutionError` if any of the aggregated promises - # fail. Upon execution will execute any of the aggregate promises that - # were not already executed. - # - # @!macro promise_self_aggregate - # - # The returned promise will not yet have been executed. Additional `#then` - # and `#rescue` handlers may still be provided. Once the returned promise - # is execute the aggregate promises will be also be executed (if they have - # not been executed already). The results of the aggregate promises will - # be checked upon completion. The necessary `#then` and `#rescue` blocks - # on the aggregating promise will then be executed as appropriate. If the - # `#rescue` handlers are executed the raises exception will be - # `Concurrent::PromiseExecutionError`. - # - # @param [Array] promises Zero or more promises to aggregate - # @return [Promise] an unscheduled (not executed) promise that aggregates - # the promises given as arguments - def self.all?(*promises) - aggregate(:all?, *promises) - end - - # Aggregates a collection of promises and executes the `then` condition - # if any aggregated promises succeed. Executes the `rescue` handler with - # a `Concurrent::PromiseExecutionError` if any of the aggregated promises - # fail. Upon execution will execute any of the aggregate promises that - # were not already executed. - # - # @!macro promise_self_aggregate - def self.any?(*promises) - aggregate(:any?, *promises) - end - - protected - - def ns_initialize(value, opts) - super - - @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor - @args = get_arguments_from(opts) - - @parent = opts.fetch(:parent) { nil } - @on_fulfill = opts.fetch(:on_fulfill) { Proc.new { |result| result } } - @on_reject = opts.fetch(:on_reject) { Proc.new { |reason| raise reason } } - - @promise_body = opts[:__promise_body_from_block__] || Proc.new { |result| result } - @state = :unscheduled - @children = [] - end - - # Aggregate a collection of zero or more promises under a composite promise, - # execute the aggregated promises and collect them into a standard Ruby array, - # call the given Ruby `Ennnumerable` predicate (such as `any?`, `all?`, `none?`, - # or `one?`) on the collection checking for the success or failure of each, - # then executing the composite's `#then` handlers if the predicate returns - # `true` or executing the composite's `#rescue` handlers if the predicate - # returns false. - # - # @!macro promise_self_aggregate - def self.aggregate(method, *promises) - composite = Promise.new do - completed = promises.collect do |promise| - promise.execute if promise.unscheduled? - promise.wait - promise - end - unless completed.empty? || completed.send(method){|promise| promise.fulfilled? } - raise PromiseExecutionError - end - end - composite - end - - # @!visibility private - def set_pending - synchronize do - @state = :pending - @children.each { |c| c.set_pending } - end - end - - # @!visibility private - def root? # :nodoc: - @parent.nil? - end - - # @!visibility private - def on_fulfill(result) - realize Proc.new { @on_fulfill.call(result) } - nil - end - - # @!visibility private - def on_reject(reason) - realize Proc.new { @on_reject.call(reason) } - nil - end - - # @!visibility private - def notify_child(child) - if_state(:fulfilled) { child.on_fulfill(apply_deref_options(@value)) } - if_state(:rejected) { child.on_reject(@reason) } - end - - # @!visibility private - def complete(success, value, reason) - children_to_notify = synchronize do - set_state!(success, value, reason) - @children.dup - end - - children_to_notify.each { |child| notify_child(child) } - observers.notify_and_delete_observers{ [Time.now, self.value, reason] } - end - - # @!visibility private - def realize(task) - @executor.post do - success, value, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) - complete(success, value, reason) - end - end - - # @!visibility private - def set_state!(success, value, reason) - set_state(success, value, reason) - event.set - end - - # @!visibility private - def synchronized_set_state!(success, value, reason) - synchronize { set_state!(success, value, reason) } - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promises.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promises.rb deleted file mode 100644 index c5df8fe..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/promises.rb +++ /dev/null @@ -1,2178 +0,0 @@ -require 'concurrent/synchronization/object' -require 'concurrent/atomic/atomic_boolean' -require 'concurrent/atomic/atomic_fixnum' -require 'concurrent/collection/lock_free_stack' -require 'concurrent/configuration' -require 'concurrent/errors' -require 'concurrent/re_include' -require 'concurrent/utility/monotonic_time' - -module Concurrent - - # {include:file:docs-source/promises-main.md} - module Promises - - # @!macro promises.param.default_executor - # @param [Executor, :io, :fast] default_executor Instance of an executor or a name of the - # global executor. Default executor propagates to chained futures unless overridden with - # executor parameter or changed with {AbstractEventFuture#with_default_executor}. - # - # @!macro promises.param.executor - # @param [Executor, :io, :fast] executor Instance of an executor or a name of the - # global executor. The task is executed on it, default executor remains unchanged. - # - # @!macro promises.param.args - # @param [Object] args arguments which are passed to the task when it's executed. - # (It might be prepended with other arguments, see the @yield section). - # - # @!macro promises.shortcut.on - # Shortcut of {#$0_on} with default `:io` executor supplied. - # @see #$0_on - # - # @!macro promises.shortcut.using - # Shortcut of {#$0_using} with default `:io` executor supplied. - # @see #$0_using - # - # @!macro promise.param.task-future - # @yieldreturn will become result of the returned Future. - # Its returned value becomes {Future#value} fulfilling it, - # raised exception becomes {Future#reason} rejecting it. - # - # @!macro promise.param.callback - # @yieldreturn is forgotten. - - # Container of all {Future}, {Event} factory methods. They are never constructed directly with - # new. - module FactoryMethods - extend ReInclude - extend self - - module Configuration - # @return [Executor, :io, :fast] the executor which is used when none is supplied - # to a factory method. The method can be overridden in the receivers of - # `include FactoryMethod` - def default_executor - :io - end - end - - include Configuration - - # @!macro promises.shortcut.on - # @return [ResolvableEvent] - def resolvable_event - resolvable_event_on default_executor - end - - # Creates a resolvable event, user is responsible for resolving the event once - # by calling {Promises::ResolvableEvent#resolve}. - # - # @!macro promises.param.default_executor - # @return [ResolvableEvent] - def resolvable_event_on(default_executor = self.default_executor) - ResolvableEventPromise.new(default_executor).future - end - - # @!macro promises.shortcut.on - # @return [ResolvableFuture] - def resolvable_future - resolvable_future_on default_executor - end - - # Creates resolvable future, user is responsible for resolving the future once by - # {Promises::ResolvableFuture#resolve}, {Promises::ResolvableFuture#fulfill}, - # or {Promises::ResolvableFuture#reject} - # - # @!macro promises.param.default_executor - # @return [ResolvableFuture] - def resolvable_future_on(default_executor = self.default_executor) - ResolvableFuturePromise.new(default_executor).future - end - - # @!macro promises.shortcut.on - # @return [Future] - def future(*args, &task) - future_on(default_executor, *args, &task) - end - - # Constructs a new Future which will be resolved after block is evaluated on default executor. - # Evaluation begins immediately. - # - # @!macro promises.param.default_executor - # @!macro promises.param.args - # @yield [*args] to the task. - # @!macro promise.param.task-future - # @return [Future] - def future_on(default_executor, *args, &task) - ImmediateEventPromise.new(default_executor).future.then(*args, &task) - end - - # Creates a resolved future with will be either fulfilled with the given value or rejected with - # the given reason. - # - # @param [true, false] fulfilled - # @param [Object] value - # @param [Object] reason - # @!macro promises.param.default_executor - # @return [Future] - def resolved_future(fulfilled, value, reason, default_executor = self.default_executor) - ImmediateFuturePromise.new(default_executor, fulfilled, value, reason).future - end - - # Creates a resolved future which will be fulfilled with the given value. - # - # @!macro promises.param.default_executor - # @param [Object] value - # @return [Future] - def fulfilled_future(value, default_executor = self.default_executor) - resolved_future true, value, nil, default_executor - end - - # Creates a resolved future which will be rejected with the given reason. - # - # @!macro promises.param.default_executor - # @param [Object] reason - # @return [Future] - def rejected_future(reason, default_executor = self.default_executor) - resolved_future false, nil, reason, default_executor - end - - # Creates resolved event. - # - # @!macro promises.param.default_executor - # @return [Event] - def resolved_event(default_executor = self.default_executor) - ImmediateEventPromise.new(default_executor).event - end - - # General constructor. Behaves differently based on the argument's type. It's provided for convenience - # but it's better to be explicit. - # - # @see rejected_future, resolved_event, fulfilled_future - # @!macro promises.param.default_executor - # @return [Event, Future] - # - # @overload make_future(nil, default_executor = self.default_executor) - # @param [nil] nil - # @return [Event] resolved event. - # - # @overload make_future(a_future, default_executor = self.default_executor) - # @param [Future] a_future - # @return [Future] a future which will be resolved when a_future is. - # - # @overload make_future(an_event, default_executor = self.default_executor) - # @param [Event] an_event - # @return [Event] an event which will be resolved when an_event is. - # - # @overload make_future(exception, default_executor = self.default_executor) - # @param [Exception] exception - # @return [Future] a rejected future with the exception as its reason. - # - # @overload make_future(value, default_executor = self.default_executor) - # @param [Object] value when none of the above overloads fits - # @return [Future] a fulfilled future with the value. - def make_future(argument = nil, default_executor = self.default_executor) - case argument - when AbstractEventFuture - # returning wrapper would change nothing - argument - when Exception - rejected_future argument, default_executor - when nil - resolved_event default_executor - else - fulfilled_future argument, default_executor - end - end - - # @!macro promises.shortcut.on - # @return [Future, Event] - def delay(*args, &task) - delay_on default_executor, *args, &task - end - - # Creates a new event or future which is resolved only after it is touched, - # see {Concurrent::AbstractEventFuture#touch}. - # - # @!macro promises.param.default_executor - # @overload delay_on(default_executor, *args, &task) - # If task is provided it returns a {Future} representing the result of the task. - # @!macro promises.param.args - # @yield [*args] to the task. - # @!macro promise.param.task-future - # @return [Future] - # @overload delay_on(default_executor) - # If no task is provided, it returns an {Event} - # @return [Event] - def delay_on(default_executor, *args, &task) - event = DelayPromise.new(default_executor).event - task ? event.chain(*args, &task) : event - end - - # @!macro promises.shortcut.on - # @return [Future, Event] - def schedule(intended_time, *args, &task) - schedule_on default_executor, intended_time, *args, &task - end - - # Creates a new event or future which is resolved in intended_time. - # - # @!macro promises.param.default_executor - # @!macro promises.param.intended_time - # @param [Numeric, Time] intended_time `Numeric` means to run in `intended_time` seconds. - # `Time` means to run on `intended_time`. - # @overload schedule_on(default_executor, intended_time, *args, &task) - # If task is provided it returns a {Future} representing the result of the task. - # @!macro promises.param.args - # @yield [*args] to the task. - # @!macro promise.param.task-future - # @return [Future] - # @overload schedule_on(default_executor, intended_time) - # If no task is provided, it returns an {Event} - # @return [Event] - def schedule_on(default_executor, intended_time, *args, &task) - event = ScheduledPromise.new(default_executor, intended_time).event - task ? event.chain(*args, &task) : event - end - - # @!macro promises.shortcut.on - # @return [Future] - def zip_futures(*futures_and_or_events) - zip_futures_on default_executor, *futures_and_or_events - end - - # Creates a new future which is resolved after all futures_and_or_events are resolved. - # Its value is an array of zipped future values. Its reason is an array of reasons for rejection. - # If there is an error it rejects. - # @!macro promises.event-conversion - # If event is supplied, which does not have value and can be only resolved, it's - # represented as `:fulfilled` with value `nil`. - # - # @!macro promises.param.default_executor - # @param [AbstractEventFuture] futures_and_or_events - # @return [Future] - def zip_futures_on(default_executor, *futures_and_or_events) - ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future - end - - alias_method :zip, :zip_futures - - # @!macro promises.shortcut.on - # @return [Event] - def zip_events(*futures_and_or_events) - zip_events_on default_executor, *futures_and_or_events - end - - # Creates a new event which is resolved after all futures_and_or_events are resolved. - # (Future is resolved when fulfilled or rejected.) - # - # @!macro promises.param.default_executor - # @param [AbstractEventFuture] futures_and_or_events - # @return [Event] - def zip_events_on(default_executor, *futures_and_or_events) - ZipEventsPromise.new_blocked_by(futures_and_or_events, default_executor).event - end - - # @!macro promises.shortcut.on - # @return [Future] - def any_resolved_future(*futures_and_or_events) - any_resolved_future_on default_executor, *futures_and_or_events - end - - alias_method :any, :any_resolved_future - - # Creates a new future which is resolved after the first futures_and_or_events is resolved. - # Its result equals the result of the first resolved future. - # @!macro promises.any-touch - # If resolved it does not propagate {Concurrent::AbstractEventFuture#touch}, leaving delayed - # futures un-executed if they are not required any more. - # @!macro promises.event-conversion - # - # @!macro promises.param.default_executor - # @param [AbstractEventFuture] futures_and_or_events - # @return [Future] - def any_resolved_future_on(default_executor, *futures_and_or_events) - AnyResolvedFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future - end - - # @!macro promises.shortcut.on - # @return [Future] - def any_fulfilled_future(*futures_and_or_events) - any_fulfilled_future_on default_executor, *futures_and_or_events - end - - # Creates a new future which is resolved after the first futures_and_or_events is fulfilled. - # Its result equals the result of the first resolved future or if all futures_and_or_events reject, - # it has reason of the last rejected future. - # @!macro promises.any-touch - # @!macro promises.event-conversion - # - # @!macro promises.param.default_executor - # @param [AbstractEventFuture] futures_and_or_events - # @return [Future] - def any_fulfilled_future_on(default_executor, *futures_and_or_events) - AnyFulfilledFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future - end - - # @!macro promises.shortcut.on - # @return [Event] - def any_event(*futures_and_or_events) - any_event_on default_executor, *futures_and_or_events - end - - # Creates a new event which becomes resolved after the first futures_and_or_events resolves. - # @!macro promises.any-touch - # - # @!macro promises.param.default_executor - # @param [AbstractEventFuture] futures_and_or_events - # @return [Event] - def any_event_on(default_executor, *futures_and_or_events) - AnyResolvedEventPromise.new_blocked_by(futures_and_or_events, default_executor).event - end - - # TODO consider adding first(count, *futures) - # TODO consider adding zip_by(slice, *futures) processing futures in slices - # TODO or rather a generic aggregator taking a function - end - - module InternalStates - # @!visibility private - class State - def resolved? - raise NotImplementedError - end - - def to_sym - raise NotImplementedError - end - end - - # @!visibility private - class Pending < State - def resolved? - false - end - - def to_sym - :pending - end - end - - # @!visibility private - class Reserved < Pending - end - - # @!visibility private - class ResolvedWithResult < State - def resolved? - true - end - - def to_sym - :resolved - end - - def result - [fulfilled?, value, reason] - end - - def fulfilled? - raise NotImplementedError - end - - def value - raise NotImplementedError - end - - def reason - raise NotImplementedError - end - - def apply - raise NotImplementedError - end - end - - # @!visibility private - class Fulfilled < ResolvedWithResult - - def initialize(value) - @Value = value - end - - def fulfilled? - true - end - - def apply(args, block) - block.call value, *args - end - - def value - @Value - end - - def reason - nil - end - - def to_sym - :fulfilled - end - end - - # @!visibility private - class FulfilledArray < Fulfilled - def apply(args, block) - block.call(*value, *args) - end - end - - # @!visibility private - class Rejected < ResolvedWithResult - def initialize(reason) - @Reason = reason - end - - def fulfilled? - false - end - - def value - nil - end - - def reason - @Reason - end - - def to_sym - :rejected - end - - def apply(args, block) - block.call reason, *args - end - end - - # @!visibility private - class PartiallyRejected < ResolvedWithResult - def initialize(value, reason) - super() - @Value = value - @Reason = reason - end - - def fulfilled? - false - end - - def to_sym - :rejected - end - - def value - @Value - end - - def reason - @Reason - end - - def apply(args, block) - block.call(*reason, *args) - end - end - - # @!visibility private - PENDING = Pending.new - # @!visibility private - RESERVED = Reserved.new - # @!visibility private - RESOLVED = Fulfilled.new(nil) - - def RESOLVED.to_sym - :resolved - end - end - - private_constant :InternalStates - - # @!macro promises.shortcut.event-future - # @see Event#$0 - # @see Future#$0 - - # @!macro promises.param.timeout - # @param [Numeric] timeout the maximum time in second to wait. - - # @!macro promises.warn.blocks - # @note This function potentially blocks current thread until the Future is resolved. - # Be careful it can deadlock. Try to chain instead. - - # Common ancestor of {Event} and {Future} classes, many shared methods are defined here. - class AbstractEventFuture < Synchronization::Object - safe_initialization! - attr_atomic(:internal_state) - private :internal_state=, :swap_internal_state, :compare_and_set_internal_state, :update_internal_state - # @!method internal_state - # @!visibility private - - include InternalStates - - def initialize(promise, default_executor) - super() - @Lock = Mutex.new - @Condition = ConditionVariable.new - @Promise = promise - @DefaultExecutor = default_executor - @Callbacks = LockFreeStack.new - @Waiters = AtomicFixnum.new 0 - self.internal_state = PENDING - end - - private :initialize - - # Returns its state. - # @return [Symbol] - # - # @overload an_event.state - # @return [:pending, :resolved] - # @overload a_future.state - # Both :fulfilled, :rejected implies :resolved. - # @return [:pending, :fulfilled, :rejected] - def state - internal_state.to_sym - end - - # Is it in pending state? - # @return [Boolean] - def pending? - !internal_state.resolved? - end - - # Is it in resolved state? - # @return [Boolean] - def resolved? - internal_state.resolved? - end - - # Propagates touch. Requests all the delayed futures, which it depends on, to be - # executed. This method is called by any other method requiring resolved state, like {#wait}. - # @return [self] - def touch - @Promise.touch - self - end - - # @!macro promises.touches - # Calls {Concurrent::AbstractEventFuture#touch}. - - # @!macro promises.method.wait - # Wait (block the Thread) until receiver is {#resolved?}. - # @!macro promises.touches - # - # @!macro promises.warn.blocks - # @!macro promises.param.timeout - # @return [self, true, false] self implies timeout was not used, true implies timeout was used - # and it was resolved, false implies it was not resolved within timeout. - def wait(timeout = nil) - result = wait_until_resolved(timeout) - timeout ? result : self - end - - # Returns default executor. - # @return [Executor] default executor - # @see #with_default_executor - # @see FactoryMethods#future_on - # @see FactoryMethods#resolvable_future - # @see FactoryMethods#any_fulfilled_future_on - # @see similar - def default_executor - @DefaultExecutor - end - - # @!macro promises.shortcut.on - # @return [Future] - def chain(*args, &task) - chain_on @DefaultExecutor, *args, &task - end - - # Chains the task to be executed asynchronously on executor after it is resolved. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @return [Future] - # @!macro promise.param.task-future - # - # @overload an_event.chain_on(executor, *args, &task) - # @yield [*args] to the task. - # @overload a_future.chain_on(executor, *args, &task) - # @yield [fulfilled, value, reason, *args] to the task. - # @yieldparam [true, false] fulfilled - # @yieldparam [Object] value - # @yieldparam [Object] reason - def chain_on(executor, *args, &task) - ChainPromise.new_blocked_by1(self, executor, executor, args, &task).future - end - - # @return [String] Short string representation. - def to_s - format '%s %s>', super[0..-2], state - end - - alias_method :inspect, :to_s - - # Resolves the resolvable when receiver is resolved. - # - # @param [Resolvable] resolvable - # @return [self] - def chain_resolvable(resolvable) - on_resolution! { resolvable.resolve_with internal_state } - end - - alias_method :tangle, :chain_resolvable - - # @!macro promises.shortcut.using - # @return [self] - def on_resolution(*args, &callback) - on_resolution_using @DefaultExecutor, *args, &callback - end - - # Stores the callback to be executed synchronously on resolving thread after it is - # resolved. - # - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # - # @overload an_event.on_resolution!(*args, &callback) - # @yield [*args] to the callback. - # @overload a_future.on_resolution!(*args, &callback) - # @yield [fulfilled, value, reason, *args] to the callback. - # @yieldparam [true, false] fulfilled - # @yieldparam [Object] value - # @yieldparam [Object] reason - def on_resolution!(*args, &callback) - add_callback :callback_on_resolution, args, callback - end - - # Stores the callback to be executed asynchronously on executor after it is resolved. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # - # @overload an_event.on_resolution_using(executor, *args, &callback) - # @yield [*args] to the callback. - # @overload a_future.on_resolution_using(executor, *args, &callback) - # @yield [fulfilled, value, reason, *args] to the callback. - # @yieldparam [true, false] fulfilled - # @yieldparam [Object] value - # @yieldparam [Object] reason - def on_resolution_using(executor, *args, &callback) - add_callback :async_callback_on_resolution, executor, args, callback - end - - # @!macro promises.method.with_default_executor - # Crates new object with same class with the executor set as its new default executor. - # Any futures depending on it will use the new default executor. - # @!macro promises.shortcut.event-future - # @abstract - # @return [AbstractEventFuture] - def with_default_executor(executor) - raise NotImplementedError - end - - # @!visibility private - def resolve_with(state, raise_on_reassign = true, reserved = false) - if compare_and_set_internal_state(reserved ? RESERVED : PENDING, state) - # go to synchronized block only if there were waiting threads - @Lock.synchronize { @Condition.broadcast } unless @Waiters.value == 0 - call_callbacks state - else - return rejected_resolution(raise_on_reassign, state) - end - self - end - - # For inspection. - # @!visibility private - # @return [Array] - def blocks - @Callbacks.each_with_object([]) do |(method, args), promises| - promises.push(args[0]) if method == :callback_notify_blocked - end - end - - # For inspection. - # @!visibility private - def callbacks - @Callbacks.each.to_a - end - - # For inspection. - # @!visibility private - def promise - @Promise - end - - # For inspection. - # @!visibility private - def touched? - promise.touched? - end - - # For inspection. - # @!visibility private - def waiting_threads - @Waiters.each.to_a - end - - # @!visibility private - def add_callback_notify_blocked(promise, index) - add_callback :callback_notify_blocked, promise, index - end - - # @!visibility private - def add_callback_clear_delayed_node(node) - add_callback(:callback_clear_delayed_node, node) - end - - # @!visibility private - def with_hidden_resolvable - # TODO (pitr-ch 10-Dec-2018): documentation, better name if in edge - self - end - - private - - def add_callback(method, *args) - state = internal_state - if state.resolved? - call_callback method, state, args - else - @Callbacks.push [method, args] - state = internal_state - # take back if it was resolved in the meanwhile - call_callbacks state if state.resolved? - end - self - end - - def callback_clear_delayed_node(state, node) - node.value = nil - end - - # @return [Boolean] - def wait_until_resolved(timeout) - return true if resolved? - - touch - - @Lock.synchronize do - @Waiters.increment - begin - if timeout - start = Concurrent.monotonic_time - until resolved? - break if @Condition.wait(@Lock, timeout) == nil # nil means timeout - timeout -= (Concurrent.monotonic_time - start) - break if timeout <= 0 - end - else - until resolved? - @Condition.wait(@Lock, timeout) - end - end - ensure - # JRuby may raise ConcurrencyError - @Waiters.decrement - end - end - resolved? - end - - def call_callback(method, state, args) - self.send method, state, *args - end - - def call_callbacks(state) - method, args = @Callbacks.pop - while method - call_callback method, state, args - method, args = @Callbacks.pop - end - end - - def with_async(executor, *args, &block) - Concurrent.executor(executor).post(*args, &block) - end - - def async_callback_on_resolution(state, executor, args, callback) - with_async(executor, state, args, callback) do |st, ar, cb| - callback_on_resolution st, ar, cb - end - end - - def callback_notify_blocked(state, promise, index) - promise.on_blocker_resolution self, index - end - end - - # Represents an event which will happen in future (will be resolved). The event is either - # pending or resolved. It should be always resolved. Use {Future} to communicate rejections and - # cancellation. - class Event < AbstractEventFuture - - alias_method :then, :chain - - - # @!macro promises.method.zip - # Creates a new event or a future which will be resolved when receiver and other are. - # Returns an event if receiver and other are events, otherwise returns a future. - # If just one of the parties is Future then the result - # of the returned future is equal to the result of the supplied future. If both are futures - # then the result is as described in {FactoryMethods#zip_futures_on}. - # - # @return [Future, Event] - def zip(other) - if other.is_a?(Future) - ZipFutureEventPromise.new_blocked_by2(other, self, @DefaultExecutor).future - else - ZipEventEventPromise.new_blocked_by2(self, other, @DefaultExecutor).event - end - end - - alias_method :&, :zip - - # Creates a new event which will be resolved when the first of receiver, `event_or_future` - # resolves. - # - # @return [Event] - def any(event_or_future) - AnyResolvedEventPromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).event - end - - alias_method :|, :any - - # Creates new event dependent on receiver which will not evaluate until touched, see {#touch}. - # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. - # - # @return [Event] - def delay - event = DelayPromise.new(@DefaultExecutor).event - ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event - end - - # @!macro promise.method.schedule - # Creates new event dependent on receiver scheduled to execute on/in intended_time. - # In time is interpreted from the moment the receiver is resolved, therefore it inserts - # delay into the chain. - # - # @!macro promises.param.intended_time - # @return [Event] - def schedule(intended_time) - chain do - event = ScheduledPromise.new(@DefaultExecutor, intended_time).event - ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event - end.flat_event - end - - # Converts event to a future. The future is fulfilled when the event is resolved, the future may never fail. - # - # @return [Future] - def to_future - future = Promises.resolvable_future - ensure - chain_resolvable(future) - end - - # Returns self, since this is event - # @return [Event] - def to_event - self - end - - # @!macro promises.method.with_default_executor - # @return [Event] - def with_default_executor(executor) - EventWrapperPromise.new_blocked_by1(self, executor).event - end - - private - - def rejected_resolution(raise_on_reassign, state) - raise Concurrent::MultipleAssignmentError.new('Event can be resolved only once') if raise_on_reassign - return false - end - - def callback_on_resolution(state, args, callback) - callback.call(*args) - end - end - - # Represents a value which will become available in future. May reject with a reason instead, - # e.g. when the tasks raises an exception. - class Future < AbstractEventFuture - - # Is it in fulfilled state? - # @return [Boolean] - def fulfilled? - state = internal_state - state.resolved? && state.fulfilled? - end - - # Is it in rejected state? - # @return [Boolean] - def rejected? - state = internal_state - state.resolved? && !state.fulfilled? - end - - # @!macro promises.warn.nil - # @note Make sure returned `nil` is not confused with timeout, no value when rejected, - # no reason when fulfilled, etc. - # Use more exact methods if needed, like {#wait}, {#value!}, {#result}, etc. - - # @!macro promises.method.value - # Return value of the future. - # @!macro promises.touches - # - # @!macro promises.warn.blocks - # @!macro promises.warn.nil - # @!macro promises.param.timeout - # @!macro promises.param.timeout_value - # @param [Object] timeout_value a value returned by the method when it times out - # @return [Object, nil, timeout_value] the value of the Future when fulfilled, - # timeout_value on timeout, - # nil on rejection. - def value(timeout = nil, timeout_value = nil) - if wait_until_resolved timeout - internal_state.value - else - timeout_value - end - end - - # Returns reason of future's rejection. - # @!macro promises.touches - # - # @!macro promises.warn.blocks - # @!macro promises.warn.nil - # @!macro promises.param.timeout - # @!macro promises.param.timeout_value - # @return [Object, timeout_value] the reason, or timeout_value on timeout, or nil on fulfillment. - def reason(timeout = nil, timeout_value = nil) - if wait_until_resolved timeout - internal_state.reason - else - timeout_value - end - end - - # Returns triplet fulfilled?, value, reason. - # @!macro promises.touches - # - # @!macro promises.warn.blocks - # @!macro promises.param.timeout - # @return [Array(Boolean, Object, Object), nil] triplet of fulfilled?, value, reason, or nil - # on timeout. - def result(timeout = nil) - internal_state.result if wait_until_resolved timeout - end - - # @!macro promises.method.wait - # @raise [Exception] {#reason} on rejection - def wait!(timeout = nil) - result = wait_until_resolved!(timeout) - timeout ? result : self - end - - # @!macro promises.method.value - # @return [Object, nil, timeout_value] the value of the Future when fulfilled, - # or nil on rejection, - # or timeout_value on timeout. - # @raise [Exception] {#reason} on rejection - def value!(timeout = nil, timeout_value = nil) - if wait_until_resolved! timeout - internal_state.value - else - timeout_value - end - end - - # Allows rejected Future to be risen with `raise` method. - # If the reason is not an exception `Runtime.new(reason)` is returned. - # - # @example - # raise Promises.rejected_future(StandardError.new("boom")) - # raise Promises.rejected_future("or just boom") - # @raise [Concurrent::Error] when raising not rejected future - # @return [Exception] - def exception(*args) - raise Concurrent::Error, 'it is not rejected' unless rejected? - raise ArgumentError unless args.size <= 1 - reason = Array(internal_state.reason).flatten.compact - if reason.size > 1 - ex = Concurrent::MultipleErrors.new reason - ex.set_backtrace(caller) - ex - else - ex = if reason[0].respond_to? :exception - reason[0].exception(*args) - else - RuntimeError.new(reason[0]).exception(*args) - end - ex.set_backtrace Array(ex.backtrace) + caller - ex - end - end - - # @!macro promises.shortcut.on - # @return [Future] - def then(*args, &task) - then_on @DefaultExecutor, *args, &task - end - - # Chains the task to be executed asynchronously on executor after it fulfills. Does not run - # the task if it rejects. It will resolve though, triggering any dependent futures. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @!macro promise.param.task-future - # @return [Future] - # @yield [value, *args] to the task. - def then_on(executor, *args, &task) - ThenPromise.new_blocked_by1(self, executor, executor, args, &task).future - end - - # @!macro promises.shortcut.on - # @return [Future] - def rescue(*args, &task) - rescue_on @DefaultExecutor, *args, &task - end - - # Chains the task to be executed asynchronously on executor after it rejects. Does not run - # the task if it fulfills. It will resolve though, triggering any dependent futures. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @!macro promise.param.task-future - # @return [Future] - # @yield [reason, *args] to the task. - def rescue_on(executor, *args, &task) - RescuePromise.new_blocked_by1(self, executor, executor, args, &task).future - end - - # @!macro promises.method.zip - # @return [Future] - def zip(other) - if other.is_a?(Future) - ZipFuturesPromise.new_blocked_by2(self, other, @DefaultExecutor).future - else - ZipFutureEventPromise.new_blocked_by2(self, other, @DefaultExecutor).future - end - end - - alias_method :&, :zip - - # Creates a new event which will be resolved when the first of receiver, `event_or_future` - # resolves. Returning future will have value nil if event_or_future is event and resolves - # first. - # - # @return [Future] - def any(event_or_future) - AnyResolvedFuturePromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).future - end - - alias_method :|, :any - - # Creates new future dependent on receiver which will not evaluate until touched, see {#touch}. - # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. - # - # @return [Future] - def delay - event = DelayPromise.new(@DefaultExecutor).event - ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future - end - - # @!macro promise.method.schedule - # @return [Future] - def schedule(intended_time) - chain do - event = ScheduledPromise.new(@DefaultExecutor, intended_time).event - ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future - end.flat - end - - # @!macro promises.method.with_default_executor - # @return [Future] - def with_default_executor(executor) - FutureWrapperPromise.new_blocked_by1(self, executor).future - end - - # Creates new future which will have result of the future returned by receiver. If receiver - # rejects it will have its rejection. - # - # @param [Integer] level how many levels of futures should flatten - # @return [Future] - def flat_future(level = 1) - FlatFuturePromise.new_blocked_by1(self, level, @DefaultExecutor).future - end - - alias_method :flat, :flat_future - - # Creates new event which will be resolved when the returned event by receiver is. - # Be careful if the receiver rejects it will just resolve since Event does not hold reason. - # - # @return [Event] - def flat_event - FlatEventPromise.new_blocked_by1(self, @DefaultExecutor).event - end - - # @!macro promises.shortcut.using - # @return [self] - def on_fulfillment(*args, &callback) - on_fulfillment_using @DefaultExecutor, *args, &callback - end - - # Stores the callback to be executed synchronously on resolving thread after it is - # fulfilled. Does nothing on rejection. - # - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # @yield [value, *args] to the callback. - def on_fulfillment!(*args, &callback) - add_callback :callback_on_fulfillment, args, callback - end - - # Stores the callback to be executed asynchronously on executor after it is - # fulfilled. Does nothing on rejection. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # @yield [value, *args] to the callback. - def on_fulfillment_using(executor, *args, &callback) - add_callback :async_callback_on_fulfillment, executor, args, callback - end - - # @!macro promises.shortcut.using - # @return [self] - def on_rejection(*args, &callback) - on_rejection_using @DefaultExecutor, *args, &callback - end - - # Stores the callback to be executed synchronously on resolving thread after it is - # rejected. Does nothing on fulfillment. - # - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # @yield [reason, *args] to the callback. - def on_rejection!(*args, &callback) - add_callback :callback_on_rejection, args, callback - end - - # Stores the callback to be executed asynchronously on executor after it is - # rejected. Does nothing on fulfillment. - # - # @!macro promises.param.executor - # @!macro promises.param.args - # @!macro promise.param.callback - # @return [self] - # @yield [reason, *args] to the callback. - def on_rejection_using(executor, *args, &callback) - add_callback :async_callback_on_rejection, executor, args, callback - end - - # Allows to use futures as green threads. The receiver has to evaluate to a future which - # represents what should be done next. It basically flattens indefinitely until non Future - # values is returned which becomes result of the returned future. Any encountered exception - # will become reason of the returned future. - # - # @return [Future] - # @param [#call(value)] run_test - # an object which when called returns either Future to keep running with - # or nil, then the run completes with the value. - # The run_test can be used to extract the Future from deeper structure, - # or to distinguish Future which is a resulting value from a future - # which is suppose to continue running. - # @example - # body = lambda do |v| - # v += 1 - # v < 5 ? Promises.future(v, &body) : v - # end - # Promises.future(0, &body).run.value! # => 5 - def run(run_test = method(:run_test)) - RunFuturePromise.new_blocked_by1(self, @DefaultExecutor, run_test).future - end - - # @!visibility private - def apply(args, block) - internal_state.apply args, block - end - - # Converts future to event which is resolved when future is resolved by fulfillment or rejection. - # - # @return [Event] - def to_event - event = Promises.resolvable_event - ensure - chain_resolvable(event) - end - - # Returns self, since this is a future - # @return [Future] - def to_future - self - end - - # @return [String] Short string representation. - def to_s - if resolved? - format '%s with %s>', super[0..-2], (fulfilled? ? value : reason).inspect - else - super - end - end - - alias_method :inspect, :to_s - - private - - def run_test(v) - v if v.is_a?(Future) - end - - def rejected_resolution(raise_on_reassign, state) - if raise_on_reassign - if internal_state == RESERVED - raise Concurrent::MultipleAssignmentError.new( - "Future can be resolved only once. It is already reserved.") - else - raise Concurrent::MultipleAssignmentError.new( - "Future can be resolved only once. It's #{result}, trying to set #{state.result}.", - current_result: result, - new_result: state.result) - end - end - return false - end - - def wait_until_resolved!(timeout = nil) - result = wait_until_resolved(timeout) - raise self if rejected? - result - end - - def async_callback_on_fulfillment(state, executor, args, callback) - with_async(executor, state, args, callback) do |st, ar, cb| - callback_on_fulfillment st, ar, cb - end - end - - def async_callback_on_rejection(state, executor, args, callback) - with_async(executor, state, args, callback) do |st, ar, cb| - callback_on_rejection st, ar, cb - end - end - - def callback_on_fulfillment(state, args, callback) - state.apply args, callback if state.fulfilled? - end - - def callback_on_rejection(state, args, callback) - state.apply args, callback unless state.fulfilled? - end - - def callback_on_resolution(state, args, callback) - callback.call(*state.result, *args) - end - - end - - # Marker module of Future, Event resolved manually. - module Resolvable - include InternalStates - end - - # A Event which can be resolved by user. - class ResolvableEvent < Event - include Resolvable - - # @!macro raise_on_reassign - # @raise [MultipleAssignmentError] when already resolved and raise_on_reassign is true. - - # @!macro promise.param.raise_on_reassign - # @param [Boolean] raise_on_reassign should method raise exception if already resolved - # @return [self, false] false is returned when raise_on_reassign is false and the receiver - # is already resolved. - # - - # Makes the event resolved, which triggers all dependent futures. - # - # @!macro promise.param.raise_on_reassign - # @!macro promise.param.reserved - # @param [true, false] reserved - # Set to true if the resolvable is {#reserve}d by you, - # marks resolution of reserved resolvable events and futures explicitly. - # Advanced feature, ignore unless you use {Resolvable#reserve} from edge. - def resolve(raise_on_reassign = true, reserved = false) - resolve_with RESOLVED, raise_on_reassign, reserved - end - - # Creates new event wrapping receiver, effectively hiding the resolve method. - # - # @return [Event] - def with_hidden_resolvable - @with_hidden_resolvable ||= EventWrapperPromise.new_blocked_by1(self, @DefaultExecutor).event - end - - # Behaves as {AbstractEventFuture#wait} but has one additional optional argument - # resolve_on_timeout. - # - # @param [true, false] resolve_on_timeout - # If it times out and the argument is true it will also resolve the event. - # @return [self, true, false] - # @see AbstractEventFuture#wait - def wait(timeout = nil, resolve_on_timeout = false) - super(timeout) or if resolve_on_timeout - # if it fails to resolve it was resolved in the meantime - # so return true as if there was no timeout - !resolve(false) - else - false - end - end - end - - # A Future which can be resolved by user. - class ResolvableFuture < Future - include Resolvable - - # Makes the future resolved with result of triplet `fulfilled?`, `value`, `reason`, - # which triggers all dependent futures. - # - # @param [true, false] fulfilled - # @param [Object] value - # @param [Object] reason - # @!macro promise.param.raise_on_reassign - # @!macro promise.param.reserved - def resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) - resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason), raise_on_reassign, reserved) - end - - # Makes the future fulfilled with `value`, - # which triggers all dependent futures. - # - # @param [Object] value - # @!macro promise.param.raise_on_reassign - # @!macro promise.param.reserved - def fulfill(value, raise_on_reassign = true, reserved = false) - resolve_with Fulfilled.new(value), raise_on_reassign, reserved - end - - # Makes the future rejected with `reason`, - # which triggers all dependent futures. - # - # @param [Object] reason - # @!macro promise.param.raise_on_reassign - # @!macro promise.param.reserved - def reject(reason, raise_on_reassign = true, reserved = false) - resolve_with Rejected.new(reason), raise_on_reassign, reserved - end - - # Evaluates the block and sets its result as future's value fulfilling, if the block raises - # an exception the future rejects with it. - # - # @yield [*args] to the block. - # @yieldreturn [Object] value - # @return [self] - def evaluate_to(*args, &block) - promise.evaluate_to(*args, block) - end - - # Evaluates the block and sets its result as future's value fulfilling, if the block raises - # an exception the future rejects with it. - # - # @yield [*args] to the block. - # @yieldreturn [Object] value - # @return [self] - # @raise [Exception] also raise reason on rejection. - def evaluate_to!(*args, &block) - promise.evaluate_to(*args, block).wait! - end - - # @!macro promises.resolvable.resolve_on_timeout - # @param [::Array(true, Object, nil), ::Array(false, nil, Exception), nil] resolve_on_timeout - # If it times out and the argument is not nil it will also resolve the future - # to the provided resolution. - - # Behaves as {AbstractEventFuture#wait} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [self, true, false] - # @see AbstractEventFuture#wait - def wait(timeout = nil, resolve_on_timeout = nil) - super(timeout) or if resolve_on_timeout - # if it fails to resolve it was resolved in the meantime - # so return true as if there was no timeout - !resolve(*resolve_on_timeout, false) - else - false - end - end - - # Behaves as {Future#wait!} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [self, true, false] - # @raise [Exception] {#reason} on rejection - # @see Future#wait! - def wait!(timeout = nil, resolve_on_timeout = nil) - super(timeout) or if resolve_on_timeout - if resolve(*resolve_on_timeout, false) - false - else - # if it fails to resolve it was resolved in the meantime - # so return true as if there was no timeout - raise self if rejected? - true - end - else - false - end - end - - # Behaves as {Future#value} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [Object, timeout_value, nil] - # @see Future#value - def value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) - if wait_until_resolved timeout - internal_state.value - else - if resolve_on_timeout - unless resolve(*resolve_on_timeout, false) - # if it fails to resolve it was resolved in the meantime - # so return value as if there was no timeout - return internal_state.value - end - end - timeout_value - end - end - - # Behaves as {Future#value!} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [Object, timeout_value, nil] - # @raise [Exception] {#reason} on rejection - # @see Future#value! - def value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) - if wait_until_resolved! timeout - internal_state.value - else - if resolve_on_timeout - unless resolve(*resolve_on_timeout, false) - # if it fails to resolve it was resolved in the meantime - # so return value as if there was no timeout - raise self if rejected? - return internal_state.value - end - end - timeout_value - end - end - - # Behaves as {Future#reason} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [Exception, timeout_value, nil] - # @see Future#reason - def reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) - if wait_until_resolved timeout - internal_state.reason - else - if resolve_on_timeout - unless resolve(*resolve_on_timeout, false) - # if it fails to resolve it was resolved in the meantime - # so return value as if there was no timeout - return internal_state.reason - end - end - timeout_value - end - end - - # Behaves as {Future#result} but has one additional optional argument - # resolve_on_timeout. - # - # @!macro promises.resolvable.resolve_on_timeout - # @return [::Array(Boolean, Object, Exception), nil] - # @see Future#result - def result(timeout = nil, resolve_on_timeout = nil) - if wait_until_resolved timeout - internal_state.result - else - if resolve_on_timeout - unless resolve(*resolve_on_timeout, false) - # if it fails to resolve it was resolved in the meantime - # so return value as if there was no timeout - internal_state.result - end - end - # otherwise returns nil - end - end - - # Creates new future wrapping receiver, effectively hiding the resolve method and similar. - # - # @return [Future] - def with_hidden_resolvable - @with_hidden_resolvable ||= FutureWrapperPromise.new_blocked_by1(self, @DefaultExecutor).future - end - end - - # @abstract - # @private - class AbstractPromise < Synchronization::Object - safe_initialization! - include InternalStates - - def initialize(future) - super() - @Future = future - end - - def future - @Future - end - - alias_method :event, :future - - def default_executor - future.default_executor - end - - def state - future.state - end - - def touch - end - - def to_s - format '%s %s>', super[0..-2], @Future - end - - alias_method :inspect, :to_s - - def delayed_because - nil - end - - private - - def resolve_with(new_state, raise_on_reassign = true) - @Future.resolve_with(new_state, raise_on_reassign) - end - - # @return [Future] - def evaluate_to(*args, block) - resolve_with Fulfilled.new(block.call(*args)) - rescue Exception => error - resolve_with Rejected.new(error) - raise error unless error.is_a?(StandardError) - end - end - - class ResolvableEventPromise < AbstractPromise - def initialize(default_executor) - super ResolvableEvent.new(self, default_executor) - end - end - - class ResolvableFuturePromise < AbstractPromise - def initialize(default_executor) - super ResolvableFuture.new(self, default_executor) - end - - public :evaluate_to - end - - # @abstract - class InnerPromise < AbstractPromise - end - - # @abstract - class BlockedPromise < InnerPromise - - private_class_method :new - - def self.new_blocked_by1(blocker, *args, &block) - blocker_delayed = blocker.promise.delayed_because - promise = new(blocker_delayed, 1, *args, &block) - blocker.add_callback_notify_blocked promise, 0 - promise - end - - def self.new_blocked_by2(blocker1, blocker2, *args, &block) - blocker_delayed1 = blocker1.promise.delayed_because - blocker_delayed2 = blocker2.promise.delayed_because - delayed = if blocker_delayed1 && blocker_delayed2 - # TODO (pitr-ch 23-Dec-2016): use arrays when we know it will not grow (only flat adds delay) - LockFreeStack.of2(blocker_delayed1, blocker_delayed2) - else - blocker_delayed1 || blocker_delayed2 - end - promise = new(delayed, 2, *args, &block) - blocker1.add_callback_notify_blocked promise, 0 - blocker2.add_callback_notify_blocked promise, 1 - promise - end - - def self.new_blocked_by(blockers, *args, &block) - delayed = blockers.reduce(nil) { |d, f| add_delayed d, f.promise.delayed_because } - promise = new(delayed, blockers.size, *args, &block) - blockers.each_with_index { |f, i| f.add_callback_notify_blocked promise, i } - promise - end - - def self.add_delayed(delayed1, delayed2) - if delayed1 && delayed2 - delayed1.push delayed2 - delayed1 - else - delayed1 || delayed2 - end - end - - def initialize(delayed, blockers_count, future) - super(future) - @Delayed = delayed - @Countdown = AtomicFixnum.new blockers_count - end - - def on_blocker_resolution(future, index) - countdown = process_on_blocker_resolution(future, index) - resolvable = resolvable?(countdown, future, index) - - on_resolvable(future, index) if resolvable - end - - def delayed_because - @Delayed - end - - def touch - clear_and_propagate_touch - end - - # for inspection only - def blocked_by - blocked_by = [] - ObjectSpace.each_object(AbstractEventFuture) { |o| blocked_by.push o if o.blocks.include? self } - blocked_by - end - - private - - def clear_and_propagate_touch(stack_or_element = @Delayed) - return if stack_or_element.nil? - - if stack_or_element.is_a? LockFreeStack - stack_or_element.clear_each { |element| clear_and_propagate_touch element } - else - stack_or_element.touch unless stack_or_element.nil? # if still present - end - end - - # @return [true,false] if resolvable - def resolvable?(countdown, future, index) - countdown.zero? - end - - def process_on_blocker_resolution(future, index) - @Countdown.decrement - end - - def on_resolvable(resolved_future, index) - raise NotImplementedError - end - end - - # @abstract - class BlockedTaskPromise < BlockedPromise - def initialize(delayed, blockers_count, default_executor, executor, args, &task) - raise ArgumentError, 'no block given' unless block_given? - super delayed, 1, Future.new(self, default_executor) - @Executor = executor - @Task = task - @Args = args - end - - def executor - @Executor - end - end - - class ThenPromise < BlockedTaskPromise - private - - def initialize(delayed, blockers_count, default_executor, executor, args, &task) - super delayed, blockers_count, default_executor, executor, args, &task - end - - def on_resolvable(resolved_future, index) - if resolved_future.fulfilled? - Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| - evaluate_to lambda { future.apply args, task } - end - else - resolve_with resolved_future.internal_state - end - end - end - - class RescuePromise < BlockedTaskPromise - private - - def initialize(delayed, blockers_count, default_executor, executor, args, &task) - super delayed, blockers_count, default_executor, executor, args, &task - end - - def on_resolvable(resolved_future, index) - if resolved_future.rejected? - Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| - evaluate_to lambda { future.apply args, task } - end - else - resolve_with resolved_future.internal_state - end - end - end - - class ChainPromise < BlockedTaskPromise - private - - def on_resolvable(resolved_future, index) - if Future === resolved_future - Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| - evaluate_to(*future.result, *args, task) - end - else - Concurrent.executor(@Executor).post(@Args, @Task) do |args, task| - evaluate_to(*args, task) - end - end - end - end - - # will be immediately resolved - class ImmediateEventPromise < InnerPromise - def initialize(default_executor) - super Event.new(self, default_executor).resolve_with(RESOLVED) - end - end - - class ImmediateFuturePromise < InnerPromise - def initialize(default_executor, fulfilled, value, reason) - super Future.new(self, default_executor). - resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason)) - end - end - - class AbstractFlatPromise < BlockedPromise - - def initialize(delayed_because, blockers_count, event_or_future) - delayed = LockFreeStack.of1(self) - super(delayed, blockers_count, event_or_future) - # noinspection RubyArgCount - @Touched = AtomicBoolean.new false - @DelayedBecause = delayed_because || LockFreeStack.new - - event_or_future.add_callback_clear_delayed_node delayed.peek - end - - def touch - if @Touched.make_true - clear_and_propagate_touch @DelayedBecause - end - end - - private - - def touched? - @Touched.value - end - - def on_resolvable(resolved_future, index) - resolve_with resolved_future.internal_state - end - - def resolvable?(countdown, future, index) - !@Future.internal_state.resolved? && super(countdown, future, index) - end - - def add_delayed_of(future) - delayed = future.promise.delayed_because - if touched? - clear_and_propagate_touch delayed - else - BlockedPromise.add_delayed @DelayedBecause, delayed - clear_and_propagate_touch @DelayedBecause if touched? - end - end - - end - - class FlatEventPromise < AbstractFlatPromise - - private - - def initialize(delayed, blockers_count, default_executor) - super delayed, 2, Event.new(self, default_executor) - end - - def process_on_blocker_resolution(future, index) - countdown = super(future, index) - if countdown.nonzero? - internal_state = future.internal_state - - unless internal_state.fulfilled? - resolve_with RESOLVED - return countdown - end - - value = internal_state.value - case value - when AbstractEventFuture - add_delayed_of value - value.add_callback_notify_blocked self, nil - countdown - else - resolve_with RESOLVED - end - end - countdown - end - - end - - class FlatFuturePromise < AbstractFlatPromise - - private - - def initialize(delayed, blockers_count, levels, default_executor) - raise ArgumentError, 'levels has to be higher than 0' if levels < 1 - # flat promise may result to a future having delayed futures, therefore we have to have empty stack - # to be able to add new delayed futures - super delayed || LockFreeStack.new, 1 + levels, Future.new(self, default_executor) - end - - def process_on_blocker_resolution(future, index) - countdown = super(future, index) - if countdown.nonzero? - internal_state = future.internal_state - - unless internal_state.fulfilled? - resolve_with internal_state - return countdown - end - - value = internal_state.value - case value - when AbstractEventFuture - add_delayed_of value - value.add_callback_notify_blocked self, nil - countdown - else - evaluate_to(lambda { raise TypeError, "returned value #{value.inspect} is not a Future" }) - end - end - countdown - end - - end - - class RunFuturePromise < AbstractFlatPromise - - private - - def initialize(delayed, blockers_count, default_executor, run_test) - super delayed, 1, Future.new(self, default_executor) - @RunTest = run_test - end - - def process_on_blocker_resolution(future, index) - internal_state = future.internal_state - - unless internal_state.fulfilled? - resolve_with internal_state - return 0 - end - - value = internal_state.value - continuation_future = @RunTest.call value - - if continuation_future - add_delayed_of continuation_future - continuation_future.add_callback_notify_blocked self, nil - else - resolve_with internal_state - end - - 1 - end - end - - class ZipEventEventPromise < BlockedPromise - def initialize(delayed, blockers_count, default_executor) - super delayed, 2, Event.new(self, default_executor) - end - - private - - def on_resolvable(resolved_future, index) - resolve_with RESOLVED - end - end - - class ZipFutureEventPromise < BlockedPromise - def initialize(delayed, blockers_count, default_executor) - super delayed, 2, Future.new(self, default_executor) - @result = nil - end - - private - - def process_on_blocker_resolution(future, index) - # first blocking is future, take its result - @result = future.internal_state if index == 0 - # super has to be called after above to piggyback on volatile @Countdown - super future, index - end - - def on_resolvable(resolved_future, index) - resolve_with @result - end - end - - class EventWrapperPromise < BlockedPromise - def initialize(delayed, blockers_count, default_executor) - super delayed, 1, Event.new(self, default_executor) - end - - private - - def on_resolvable(resolved_future, index) - resolve_with RESOLVED - end - end - - class FutureWrapperPromise < BlockedPromise - def initialize(delayed, blockers_count, default_executor) - super delayed, 1, Future.new(self, default_executor) - end - - private - - def on_resolvable(resolved_future, index) - resolve_with resolved_future.internal_state - end - end - - class ZipFuturesPromise < BlockedPromise - - private - - def initialize(delayed, blockers_count, default_executor) - super(delayed, blockers_count, Future.new(self, default_executor)) - @Resolutions = ::Array.new(blockers_count, nil) - - on_resolvable nil, nil if blockers_count == 0 - end - - def process_on_blocker_resolution(future, index) - # TODO (pitr-ch 18-Dec-2016): Can we assume that array will never break under parallel access when never re-sized? - @Resolutions[index] = future.internal_state # has to be set before countdown in super - super future, index - end - - def on_resolvable(resolved_future, index) - all_fulfilled = true - values = ::Array.new(@Resolutions.size) - reasons = ::Array.new(@Resolutions.size) - - @Resolutions.each_with_index do |internal_state, i| - fulfilled, values[i], reasons[i] = internal_state.result - all_fulfilled &&= fulfilled - end - - if all_fulfilled - resolve_with FulfilledArray.new(values) - else - resolve_with PartiallyRejected.new(values, reasons) - end - end - end - - class ZipEventsPromise < BlockedPromise - - private - - def initialize(delayed, blockers_count, default_executor) - super delayed, blockers_count, Event.new(self, default_executor) - - on_resolvable nil, nil if blockers_count == 0 - end - - def on_resolvable(resolved_future, index) - resolve_with RESOLVED - end - end - - # @abstract - class AbstractAnyPromise < BlockedPromise - end - - class AnyResolvedEventPromise < AbstractAnyPromise - - private - - def initialize(delayed, blockers_count, default_executor) - super delayed, blockers_count, Event.new(self, default_executor) - end - - def resolvable?(countdown, future, index) - true - end - - def on_resolvable(resolved_future, index) - resolve_with RESOLVED, false - end - end - - class AnyResolvedFuturePromise < AbstractAnyPromise - - private - - def initialize(delayed, blockers_count, default_executor) - super delayed, blockers_count, Future.new(self, default_executor) - end - - def resolvable?(countdown, future, index) - true - end - - def on_resolvable(resolved_future, index) - resolve_with resolved_future.internal_state, false - end - end - - class AnyFulfilledFuturePromise < AnyResolvedFuturePromise - - private - - def resolvable?(countdown, event_or_future, index) - (event_or_future.is_a?(Event) ? event_or_future.resolved? : event_or_future.fulfilled?) || - # inlined super from BlockedPromise - countdown.zero? - end - end - - class DelayPromise < InnerPromise - - def initialize(default_executor) - event = Event.new(self, default_executor) - @Delayed = LockFreeStack.of1(self) - super event - event.add_callback_clear_delayed_node @Delayed.peek - end - - def touch - @Future.resolve_with RESOLVED - end - - def delayed_because - @Delayed - end - - end - - class ScheduledPromise < InnerPromise - def intended_time - @IntendedTime - end - - def inspect - "#{to_s[0..-2]} intended_time: #{@IntendedTime}>" - end - - private - - def initialize(default_executor, intended_time) - super Event.new(self, default_executor) - - @IntendedTime = intended_time - - in_seconds = begin - now = Time.now - schedule_time = if @IntendedTime.is_a? Time - @IntendedTime - else - now + @IntendedTime - end - [0, schedule_time.to_f - now.to_f].max - end - - Concurrent.global_timer_set.post(in_seconds) do - @Future.resolve_with RESOLVED - end - end - end - - extend FactoryMethods - - private_constant :AbstractPromise, - :ResolvableEventPromise, - :ResolvableFuturePromise, - :InnerPromise, - :BlockedPromise, - :BlockedTaskPromise, - :ThenPromise, - :RescuePromise, - :ChainPromise, - :ImmediateEventPromise, - :ImmediateFuturePromise, - :AbstractFlatPromise, - :FlatFuturePromise, - :FlatEventPromise, - :RunFuturePromise, - :ZipEventEventPromise, - :ZipFutureEventPromise, - :EventWrapperPromise, - :FutureWrapperPromise, - :ZipFuturesPromise, - :ZipEventsPromise, - :AbstractAnyPromise, - :AnyResolvedFuturePromise, - :AnyFulfilledFuturePromise, - :AnyResolvedEventPromise, - :DelayPromise, - :ScheduledPromise - - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/re_include.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/re_include.rb deleted file mode 100644 index 600bc6a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/re_include.rb +++ /dev/null @@ -1,60 +0,0 @@ -module Concurrent - - # Methods form module A included to a module B, which is already included into class C, - # will not be visible in the C class. If this module is extended to B then A's methods - # are correctly made visible to C. - # - # @example - # module A - # def a - # :a - # end - # end - # - # module B1 - # end - # - # class C1 - # include B1 - # end - # - # module B2 - # extend Concurrent::ReInclude - # end - # - # class C2 - # include B2 - # end - # - # B1.send :include, A - # B2.send :include, A - # - # C1.new.respond_to? :a # => false - # C2.new.respond_to? :a # => true - # - # @!visibility private - module ReInclude - # @!visibility private - def included(base) - (@re_include_to_bases ||= []) << [:include, base] - super(base) - end - - # @!visibility private - def extended(base) - (@re_include_to_bases ||= []) << [:extend, base] - super(base) - end - - # @!visibility private - def include(*modules) - result = super(*modules) - modules.reverse.each do |module_being_included| - (@re_include_to_bases ||= []).each do |method, mod| - mod.send method, module_being_included - end - end - result - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/scheduled_task.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/scheduled_task.rb deleted file mode 100644 index 429fc06..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/scheduled_task.rb +++ /dev/null @@ -1,331 +0,0 @@ -require 'concurrent/constants' -require 'concurrent/errors' -require 'concurrent/configuration' -require 'concurrent/ivar' -require 'concurrent/collection/copy_on_notify_observer_set' -require 'concurrent/utility/monotonic_time' - -require 'concurrent/options' - -module Concurrent - - # `ScheduledTask` is a close relative of `Concurrent::Future` but with one - # important difference: A `Future` is set to execute as soon as possible - # whereas a `ScheduledTask` is set to execute after a specified delay. This - # implementation is loosely based on Java's - # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html). - # It is a more feature-rich variant of {Concurrent.timer}. - # - # The *intended* schedule time of task execution is set on object construction - # with the `delay` argument. The delay is a numeric (floating point or integer) - # representing a number of seconds in the future. Any other value or a numeric - # equal to or less than zero will result in an exception. The *actual* schedule - # time of task execution is set when the `execute` method is called. - # - # The constructor can also be given zero or more processing options. Currently - # the only supported options are those recognized by the - # [Dereferenceable](Dereferenceable) module. - # - # The final constructor argument is a block representing the task to be performed. - # If no block is given an `ArgumentError` will be raised. - # - # **States** - # - # `ScheduledTask` mixes in the [Obligation](Obligation) module thus giving it - # "future" behavior. This includes the expected lifecycle states. `ScheduledTask` - # has one additional state, however. While the task (block) is being executed the - # state of the object will be `:processing`. This additional state is necessary - # because it has implications for task cancellation. - # - # **Cancellation** - # - # A `:pending` task can be cancelled using the `#cancel` method. A task in any - # other state, including `:processing`, cannot be cancelled. The `#cancel` - # method returns a boolean indicating the success of the cancellation attempt. - # A cancelled `ScheduledTask` cannot be restarted. It is immutable. - # - # **Obligation and Observation** - # - # The result of a `ScheduledTask` can be obtained either synchronously or - # asynchronously. `ScheduledTask` mixes in both the [Obligation](Obligation) - # module and the - # [Observable](http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html) - # module from the Ruby standard library. With one exception `ScheduledTask` - # behaves identically to [Future](Observable) with regard to these modules. - # - # @!macro copy_options - # - # @example Basic usage - # - # require 'concurrent/scheduled_task' - # require 'csv' - # require 'open-uri' - # - # class Ticker - # def get_year_end_closing(symbol, year, api_key) - # uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv" - # data = [] - # csv = URI.parse(uri).read - # if csv.include?('call frequency') - # return :rate_limit_exceeded - # end - # CSV.parse(csv, headers: true) do |row| - # data << row['close'].to_f if row['timestamp'].include?(year.to_s) - # end - # year_end = data.first - # year_end - # rescue => e - # p e - # end - # end - # - # api_key = ENV['ALPHAVANTAGE_KEY'] - # abort(error_message) unless api_key - # - # # Future - # price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) } - # price.state #=> :pending - # price.pending? #=> true - # price.value(0) #=> nil (does not block) - # - # sleep(1) # do other stuff - # - # price.value #=> 63.65 (after blocking if necessary) - # price.state #=> :fulfilled - # price.fulfilled? #=> true - # price.value #=> 63.65 - # - # @example Successful task execution - # - # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } - # task.state #=> :unscheduled - # task.execute - # task.state #=> pending - # - # # wait for it... - # sleep(3) - # - # task.unscheduled? #=> false - # task.pending? #=> false - # task.fulfilled? #=> true - # task.rejected? #=> false - # task.value #=> 'What does the fox say?' - # - # @example One line creation and execution - # - # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute - # task.state #=> pending - # - # task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' } - # task.state #=> pending - # - # @example Failed task execution - # - # task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') } - # task.pending? #=> true - # - # # wait for it... - # sleep(3) - # - # task.unscheduled? #=> false - # task.pending? #=> false - # task.fulfilled? #=> false - # task.rejected? #=> true - # task.value #=> nil - # task.reason #=> # - # - # @example Task execution with observation - # - # observer = Class.new{ - # def update(time, value, reason) - # puts "The task completed at #{time} with value '#{value}'" - # end - # }.new - # - # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } - # task.add_observer(observer) - # task.execute - # task.pending? #=> true - # - # # wait for it... - # sleep(3) - # - # #>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?' - # - # @!macro monotonic_clock_warning - # - # @see Concurrent.timer - class ScheduledTask < IVar - include Comparable - - # The executor on which to execute the task. - # @!visibility private - attr_reader :executor - - # Schedule a task for execution at a specified future time. - # - # @param [Float] delay the number of seconds to wait for before executing the task - # - # @yield the task to be performed - # - # @!macro executor_and_deref_options - # - # @option opts [object, Array] :args zero or more arguments to be passed the task - # block on execution - # - # @raise [ArgumentError] When no block is given - # @raise [ArgumentError] When given a time that is in the past - def initialize(delay, opts = {}, &task) - raise ArgumentError.new('no block given') unless block_given? - raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0 - - super(NULL, opts, &nil) - - synchronize do - ns_set_state(:unscheduled) - @parent = opts.fetch(:timer_set, Concurrent.global_timer_set) - @args = get_arguments_from(opts) - @delay = delay.to_f - @task = task - @time = nil - @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor - self.observers = Collection::CopyOnNotifyObserverSet.new - end - end - - # The `delay` value given at instanciation. - # - # @return [Float] the initial delay. - def initial_delay - synchronize { @delay } - end - - # The monotonic time at which the the task is scheduled to be executed. - # - # @return [Float] the schedule time or nil if `unscheduled` - def schedule_time - synchronize { @time } - end - - # Comparator which orders by schedule time. - # - # @!visibility private - def <=>(other) - schedule_time <=> other.schedule_time - end - - # Has the task been cancelled? - # - # @return [Boolean] true if the task is in the given state else false - def cancelled? - synchronize { ns_check_state?(:cancelled) } - end - - # In the task execution in progress? - # - # @return [Boolean] true if the task is in the given state else false - def processing? - synchronize { ns_check_state?(:processing) } - end - - # Cancel this task and prevent it from executing. A task can only be - # cancelled if it is pending or unscheduled. - # - # @return [Boolean] true if successfully cancelled else false - def cancel - if compare_and_set_state(:cancelled, :pending, :unscheduled) - complete(false, nil, CancelledOperationError.new) - # To avoid deadlocks this call must occur outside of #synchronize - # Changing the state above should prevent redundant calls - @parent.send(:remove_task, self) - else - false - end - end - - # Reschedule the task using the original delay and the current time. - # A task can only be reset while it is `:pending`. - # - # @return [Boolean] true if successfully rescheduled else false - def reset - synchronize{ ns_reschedule(@delay) } - end - - # Reschedule the task using the given delay and the current time. - # A task can only be reset while it is `:pending`. - # - # @param [Float] delay the number of seconds to wait for before executing the task - # - # @return [Boolean] true if successfully rescheduled else false - # - # @raise [ArgumentError] When given a time that is in the past - def reschedule(delay) - delay = delay.to_f - raise ArgumentError.new('seconds must be greater than zero') if delay < 0.0 - synchronize{ ns_reschedule(delay) } - end - - # Execute an `:unscheduled` `ScheduledTask`. Immediately sets the state to `:pending` - # and starts counting down toward execution. Does nothing if the `ScheduledTask` is - # in any state other than `:unscheduled`. - # - # @return [ScheduledTask] a reference to `self` - def execute - if compare_and_set_state(:pending, :unscheduled) - synchronize{ ns_schedule(@delay) } - end - self - end - - # Create a new `ScheduledTask` object with the given block, execute it, and return the - # `:pending` object. - # - # @param [Float] delay the number of seconds to wait for before executing the task - # - # @!macro executor_and_deref_options - # - # @return [ScheduledTask] the newly created `ScheduledTask` in the `:pending` state - # - # @raise [ArgumentError] if no block is given - def self.execute(delay, opts = {}, &task) - new(delay, opts, &task).execute - end - - # Execute the task. - # - # @!visibility private - def process_task - safe_execute(@task, @args) - end - - protected :set, :try_set, :fail, :complete - - protected - - # Schedule the task using the given delay and the current time. - # - # @param [Float] delay the number of seconds to wait for before executing the task - # - # @return [Boolean] true if successfully rescheduled else false - # - # @!visibility private - def ns_schedule(delay) - @delay = delay - @time = Concurrent.monotonic_time + @delay - @parent.send(:post_task, self) - end - - # Reschedule the task using the given delay and the current time. - # A task can only be reset while it is `:pending`. - # - # @param [Float] delay the number of seconds to wait for before executing the task - # - # @return [Boolean] true if successfully rescheduled else false - # - # @!visibility private - def ns_reschedule(delay) - return false unless ns_check_state?(:pending) - @parent.send(:remove_task, self) && ns_schedule(delay) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/set.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/set.rb deleted file mode 100644 index eee4eff..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/set.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/thread_safe/util' -require 'set' - -module Concurrent - - # @!macro concurrent_set - # - # A thread-safe subclass of Set. This version locks against the object - # itself for every method call, ensuring only one thread can be reading - # or writing at a time. This includes iteration methods like `#each`. - # - # @note `a += b` is **not** a **thread-safe** operation on - # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set` - # which is union of `a` and `b`, then it writes the union to `a`. - # The read and write are independent operations they do not form a single atomic - # operation therefore when two `+=` operations are executed concurrently updates - # may be lost. Use `#merge` instead. - # - # @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set` - - # @!macro internal_implementation_note - SetImplementation = case - when Concurrent.on_cruby? - # The CRuby implementation of Set is written in Ruby itself and is - # not thread safe for certain methods. - require 'monitor' - require 'concurrent/thread_safe/util/data_structures' - - class CRubySet < ::Set - end - - ThreadSafe::Util.make_synchronized_on_cruby CRubySet - CRubySet - - when Concurrent.on_jruby? - require 'jruby/synchronized' - - class JRubySet < ::Set - include JRuby::Synchronized - end - - JRubySet - - when Concurrent.on_truffleruby? - require 'concurrent/thread_safe/util/data_structures' - - class TruffleRubySet < ::Set - end - - ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubySet - TruffleRubySet - - else - warn 'Possibly unsupported Ruby implementation' - ::Set - end - private_constant :SetImplementation - - # @!macro concurrent_set - class Set < SetImplementation - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/settable_struct.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/settable_struct.rb deleted file mode 100644 index 99b8561..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/settable_struct.rb +++ /dev/null @@ -1,139 +0,0 @@ -require 'concurrent/errors' -require 'concurrent/synchronization/abstract_struct' -require 'concurrent/synchronization/lockable_object' - -module Concurrent - - # An thread-safe, write-once variation of Ruby's standard `Struct`. - # Each member can have its value set at most once, either at construction - # or any time thereafter. Attempting to assign a value to a member - # that has already been set will result in a `Concurrent::ImmutabilityError`. - # - # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` - # @see http://en.wikipedia.org/wiki/Final_(Java) Java `final` keyword - module SettableStruct - include Synchronization::AbstractStruct - - # @!macro struct_values - def values - synchronize { ns_values } - end - alias_method :to_a, :values - - # @!macro struct_values_at - def values_at(*indexes) - synchronize { ns_values_at(indexes) } - end - - # @!macro struct_inspect - def inspect - synchronize { ns_inspect } - end - alias_method :to_s, :inspect - - # @!macro struct_merge - def merge(other, &block) - synchronize { ns_merge(other, &block) } - end - - # @!macro struct_to_h - def to_h - synchronize { ns_to_h } - end - - # @!macro struct_get - def [](member) - synchronize { ns_get(member) } - end - - # @!macro struct_equality - def ==(other) - synchronize { ns_equality(other) } - end - - # @!macro struct_each - def each(&block) - return enum_for(:each) unless block_given? - synchronize { ns_each(&block) } - end - - # @!macro struct_each_pair - def each_pair(&block) - return enum_for(:each_pair) unless block_given? - synchronize { ns_each_pair(&block) } - end - - # @!macro struct_select - def select(&block) - return enum_for(:select) unless block_given? - synchronize { ns_select(&block) } - end - - # @!macro struct_set - # - # @raise [Concurrent::ImmutabilityError] if the given member has already been set - def []=(member, value) - if member.is_a? Integer - length = synchronize { @values.length } - if member >= length - raise IndexError.new("offset #{member} too large for struct(size:#{length})") - end - synchronize do - unless @values[member].nil? - raise Concurrent::ImmutabilityError.new('struct member has already been set') - end - @values[member] = value - end - else - send("#{member}=", value) - end - rescue NoMethodError - raise NameError.new("no member '#{member}' in struct") - end - - private - - # @!visibility private - def initialize_copy(original) - synchronize do - super(original) - ns_initialize_copy - end - end - - # @!macro struct_new - def self.new(*args, &block) - clazz_name = nil - if args.length == 0 - raise ArgumentError.new('wrong number of arguments (0 for 1+)') - elsif args.length > 0 && args.first.is_a?(String) - clazz_name = args.shift - end - FACTORY.define_struct(clazz_name, args, &block) - end - - FACTORY = Class.new(Synchronization::LockableObject) do - def define_struct(name, members, &block) - synchronize do - clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block) - members.each_with_index do |member, index| - clazz.send :remove_method, member if clazz.instance_methods.include? member - clazz.send(:define_method, member) do - synchronize { @values[index] } - end - clazz.send(:define_method, "#{member}=") do |value| - synchronize do - unless @values[index].nil? - raise Concurrent::ImmutabilityError.new('struct member has already been set') - end - @values[index] = value - end - end - end - clazz - end - end - end.new - private_constant :FACTORY - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization.rb deleted file mode 100644 index 6d8cf4b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -require 'concurrent/synchronization/object' -require 'concurrent/synchronization/lockable_object' -require 'concurrent/synchronization/condition' -require 'concurrent/synchronization/lock' - -module Concurrent - # @!visibility private - module Synchronization - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb deleted file mode 100644 index d9050b3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first -require 'concurrent/utility/monotonic_time' -require 'concurrent/synchronization/object' - -module Concurrent - module Synchronization - - # @!visibility private - class AbstractLockableObject < Synchronization::Object - - protected - - # @!macro synchronization_object_method_synchronize - # - # @yield runs the block synchronized against this object, - # equivalent of java's `synchronize(this) {}` - # @note can by made public in descendants if required by `public :synchronize` - def synchronize - raise NotImplementedError - end - - # @!macro synchronization_object_method_ns_wait_until - # - # Wait until condition is met or timeout passes, - # protects against spurious wake-ups. - # @param [Numeric, nil] timeout in seconds, `nil` means no timeout - # @yield condition to be met - # @yieldreturn [true, false] - # @return [true, false] if condition met - # @note only to be used inside synchronized block - # @note to provide direct access to this method in a descendant add method - # ``` - # def wait_until(timeout = nil, &condition) - # synchronize { ns_wait_until(timeout, &condition) } - # end - # ``` - def ns_wait_until(timeout = nil, &condition) - if timeout - wait_until = Concurrent.monotonic_time + timeout - loop do - now = Concurrent.monotonic_time - condition_result = condition.call - return condition_result if now >= wait_until || condition_result - ns_wait wait_until - now - end - else - ns_wait timeout until condition.call - true - end - end - - # @!macro synchronization_object_method_ns_wait - # - # Wait until another thread calls #signal or #broadcast, - # spurious wake-ups can happen. - # - # @param [Numeric, nil] timeout in seconds, `nil` means no timeout - # @return [self] - # @note only to be used inside synchronized block - # @note to provide direct access to this method in a descendant add method - # ``` - # def wait(timeout = nil) - # synchronize { ns_wait(timeout) } - # end - # ``` - def ns_wait(timeout = nil) - raise NotImplementedError - end - - # @!macro synchronization_object_method_ns_signal - # - # Signal one waiting thread. - # @return [self] - # @note only to be used inside synchronized block - # @note to provide direct access to this method in a descendant add method - # ``` - # def signal - # synchronize { ns_signal } - # end - # ``` - def ns_signal - raise NotImplementedError - end - - # @!macro synchronization_object_method_ns_broadcast - # - # Broadcast to all waiting threads. - # @return [self] - # @note only to be used inside synchronized block - # @note to provide direct access to this method in a descendant add method - # ``` - # def broadcast - # synchronize { ns_broadcast } - # end - # ``` - def ns_broadcast - raise NotImplementedError - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb deleted file mode 100644 index 7cd2dec..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Concurrent - module Synchronization - - # @!visibility private - # @!macro internal_implementation_note - class AbstractObject - def initialize - # nothing to do - end - - # @!visibility private - # @abstract - def full_memory_barrier - raise NotImplementedError - end - - def self.attr_volatile(*names) - raise NotImplementedError - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb deleted file mode 100644 index 1fe90c1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +++ /dev/null @@ -1,171 +0,0 @@ -module Concurrent - module Synchronization - - # @!visibility private - # @!macro internal_implementation_note - module AbstractStruct - - # @!visibility private - def initialize(*values) - super() - ns_initialize(*values) - end - - # @!macro struct_length - # - # Returns the number of struct members. - # - # @return [Fixnum] the number of struct members - def length - self.class::MEMBERS.length - end - alias_method :size, :length - - # @!macro struct_members - # - # Returns the struct members as an array of symbols. - # - # @return [Array] the struct members as an array of symbols - def members - self.class::MEMBERS.dup - end - - protected - - # @!macro struct_values - # - # @!visibility private - def ns_values - @values.dup - end - - # @!macro struct_values_at - # - # @!visibility private - def ns_values_at(indexes) - @values.values_at(*indexes) - end - - # @!macro struct_to_h - # - # @!visibility private - def ns_to_h - length.times.reduce({}){|memo, i| memo[self.class::MEMBERS[i]] = @values[i]; memo} - end - - # @!macro struct_get - # - # @!visibility private - def ns_get(member) - if member.is_a? Integer - if member >= @values.length - raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})") - end - @values[member] - else - send(member) - end - rescue NoMethodError - raise NameError.new("no member '#{member}' in struct") - end - - # @!macro struct_equality - # - # @!visibility private - def ns_equality(other) - self.class == other.class && self.values == other.values - end - - # @!macro struct_each - # - # @!visibility private - def ns_each - values.each{|value| yield value } - end - - # @!macro struct_each_pair - # - # @!visibility private - def ns_each_pair - @values.length.times do |index| - yield self.class::MEMBERS[index], @values[index] - end - end - - # @!macro struct_select - # - # @!visibility private - def ns_select - values.select{|value| yield value } - end - - # @!macro struct_inspect - # - # @!visibility private - def ns_inspect - struct = pr_underscore(self.class.ancestors[1]) - clazz = ((self.class.to_s =~ /^#" - end - - # @!macro struct_merge - # - # @!visibility private - def ns_merge(other, &block) - self.class.new(*self.to_h.merge(other, &block).values) - end - - # @!visibility private - def ns_initialize_copy - @values = @values.map do |val| - begin - val.clone - rescue TypeError - val - end - end - end - - # @!visibility private - def pr_underscore(clazz) - word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229 - word.gsub!(/::/, '/') - word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') - word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') - word.tr!("-", "_") - word.downcase! - word - end - - # @!visibility private - def self.define_struct_class(parent, base, name, members, &block) - clazz = Class.new(base || Object) do - include parent - self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze) - def ns_initialize(*values) - raise ArgumentError.new('struct size differs') if values.length > length - @values = values.fill(nil, values.length..length-1) - end - end - unless name.nil? - begin - parent.send :remove_const, name if parent.const_defined?(name, false) - parent.const_set(name, clazz) - clazz - rescue NameError - raise NameError.new("identifier #{name} needs to be constant") - end - end - members.each_with_index do |member, index| - clazz.send :remove_method, member if clazz.instance_methods.include? member - clazz.send(:define_method, member) do - @values[index] - end - end - clazz.class_exec(&block) unless block.nil? - clazz.singleton_class.send :alias_method, :[], :new - clazz - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/condition.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/condition.rb deleted file mode 100644 index 5daa68b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/condition.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'concurrent/synchronization/lockable_object' - -module Concurrent - module Synchronization - - # @!visibility private - # TODO (pitr-ch 04-Dec-2016): should be in edge - class Condition < LockableObject - safe_initialization! - - # TODO (pitr 12-Sep-2015): locks two objects, improve - # TODO (pitr 26-Sep-2015): study - # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/concurrent/locks/AbstractQueuedSynchronizer.java#AbstractQueuedSynchronizer.Node - - singleton_class.send :alias_method, :private_new, :new - private_class_method :new - - def initialize(lock) - super() - @Lock = lock - end - - def wait(timeout = nil) - @Lock.synchronize { ns_wait(timeout) } - end - - def ns_wait(timeout = nil) - synchronize { super(timeout) } - end - - def wait_until(timeout = nil, &condition) - @Lock.synchronize { ns_wait_until(timeout, &condition) } - end - - def ns_wait_until(timeout = nil, &condition) - synchronize { super(timeout, &condition) } - end - - def signal - @Lock.synchronize { ns_signal } - end - - def ns_signal - synchronize { super } - end - - def broadcast - @Lock.synchronize { ns_broadcast } - end - - def ns_broadcast - synchronize { super } - end - end - - class LockableObject < LockableObjectImplementation - def new_condition - Condition.private_new(self) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb deleted file mode 100644 index 139e08d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -module Concurrent - module Synchronization - case - when Concurrent.on_cruby? - def self.full_memory_barrier - # relying on undocumented behavior of CRuby, GVL acquire has lock which ensures visibility of ivars - # https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L204-L211 - end - - when Concurrent.on_jruby? - require 'concurrent/utility/native_extension_loader' - def self.full_memory_barrier - JRubyAttrVolatile.full_memory_barrier - end - - when Concurrent.on_truffleruby? - def self.full_memory_barrier - TruffleRuby.full_memory_barrier - end - - else - warn 'Possibly unsupported Ruby implementation' - def self.full_memory_barrier - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb deleted file mode 100644 index 7693046..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -module Concurrent - module Synchronization - - if Concurrent.on_jruby? - - # @!visibility private - # @!macro internal_implementation_note - class JRubyLockableObject < AbstractLockableObject - - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lock.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lock.rb deleted file mode 100644 index f90e0b5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lock.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'concurrent/synchronization/lockable_object' - -module Concurrent - module Synchronization - - # @!visibility private - # TODO (pitr-ch 04-Dec-2016): should be in edge - class Lock < LockableObject - # TODO use JavaReentrantLock on JRuby - - public :synchronize - - def wait(timeout = nil) - synchronize { ns_wait(timeout) } - end - - public :ns_wait - - def wait_until(timeout = nil, &condition) - synchronize { ns_wait_until(timeout, &condition) } - end - - public :ns_wait_until - - def signal - synchronize { ns_signal } - end - - public :ns_signal - - def broadcast - synchronize { ns_broadcast } - end - - public :ns_broadcast - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb deleted file mode 100644 index 08d2ff6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'concurrent/utility/engine' -require 'concurrent/synchronization/abstract_lockable_object' -require 'concurrent/synchronization/mutex_lockable_object' -require 'concurrent/synchronization/jruby_lockable_object' - -module Concurrent - module Synchronization - - # @!visibility private - # @!macro internal_implementation_note - LockableObjectImplementation = case - when Concurrent.on_cruby? - MutexLockableObject - when Concurrent.on_jruby? - JRubyLockableObject - when Concurrent.on_truffleruby? - MutexLockableObject - else - warn 'Possibly unsupported Ruby implementation' - MonitorLockableObject - end - private_constant :LockableObjectImplementation - - # Safe synchronization under any Ruby implementation. - # It provides methods like {#synchronize}, {#wait}, {#signal} and {#broadcast}. - # Provides a single layer which can improve its implementation over time without changes needed to - # the classes using it. Use {Synchronization::Object} not this abstract class. - # - # @note this object does not support usage together with - # [`Thread#wakeup`](http://ruby-doc.org/core/Thread.html#method-i-wakeup) - # and [`Thread#raise`](http://ruby-doc.org/core/Thread.html#method-i-raise). - # `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and - # `Thread#wakeup` will not work on all platforms. - # - # @see Event implementation as an example of this class use - # - # @example simple - # class AnClass < Synchronization::Object - # def initialize - # super - # synchronize { @value = 'asd' } - # end - # - # def value - # synchronize { @value } - # end - # end - # - # @!visibility private - class LockableObject < LockableObjectImplementation - - # TODO (pitr 12-Sep-2015): make private for c-r, prohibit subclassing - # TODO (pitr 12-Sep-2015): we inherit too much ourselves :/ - - # @!method initialize(*args, &block) - # @!macro synchronization_object_method_initialize - - # @!method synchronize - # @!macro synchronization_object_method_synchronize - - # @!method wait_until(timeout = nil, &condition) - # @!macro synchronization_object_method_ns_wait_until - - # @!method wait(timeout = nil) - # @!macro synchronization_object_method_ns_wait - - # @!method signal - # @!macro synchronization_object_method_ns_signal - - # @!method broadcast - # @!macro synchronization_object_method_ns_broadcast - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb deleted file mode 100644 index acc9745..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'concurrent/synchronization/abstract_lockable_object' - -module Concurrent - module Synchronization - - # @!visibility private - # @!macro internal_implementation_note - module ConditionSignalling - protected - - def ns_signal - @__Condition__.signal - self - end - - def ns_broadcast - @__Condition__.broadcast - self - end - end - - - # @!visibility private - # @!macro internal_implementation_note - class MutexLockableObject < AbstractLockableObject - include ConditionSignalling - - safe_initialization! - - def initialize - super() - @__Lock__ = ::Mutex.new - @__Condition__ = ::ConditionVariable.new - end - - def initialize_copy(other) - super - @__Lock__ = ::Mutex.new - @__Condition__ = ::ConditionVariable.new - end - - protected - - def synchronize - if @__Lock__.owned? - yield - else - @__Lock__.synchronize { yield } - end - end - - def ns_wait(timeout = nil) - @__Condition__.wait @__Lock__, timeout - self - end - end - - # @!visibility private - # @!macro internal_implementation_note - class MonitorLockableObject < AbstractLockableObject - include ConditionSignalling - - safe_initialization! - - def initialize - super() - @__Lock__ = ::Monitor.new - @__Condition__ = @__Lock__.new_cond - end - - def initialize_copy(other) - super - @__Lock__ = ::Monitor.new - @__Condition__ = @__Lock__.new_cond - end - - protected - - def synchronize # TODO may be a problem with lock.synchronize { lock.wait } - @__Lock__.synchronize { yield } - end - - def ns_wait(timeout = nil) - @__Condition__.wait timeout - self - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/object.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/object.rb deleted file mode 100644 index e839c9f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/object.rb +++ /dev/null @@ -1,151 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first - -require 'concurrent/synchronization/safe_initialization' -require 'concurrent/synchronization/volatile' -require 'concurrent/atomic/atomic_reference' - -module Concurrent - module Synchronization - - # Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions. - # - final instance variables see {Object.safe_initialization!} - # - volatile instance variables see {Object.attr_volatile} - # - volatile instance variables see {Object.attr_atomic} - # @!visibility private - class Object < AbstractObject - include Volatile - - # TODO make it a module if possible - - # @!method self.attr_volatile(*names) - # Creates methods for reading and writing (as `attr_accessor` does) to a instance variable with - # volatile (Java) semantic. The instance variable should be accessed only through generated methods. - # - # @param [::Array] names of the instance variables to be volatile - # @return [::Array] names of defined method names - - # Has to be called by children. - def initialize - super - __initialize_atomic_fields__ - end - - def self.safe_initialization! - extend SafeInitialization unless safe_initialization? - end - - def self.safe_initialization? - self.singleton_class < SafeInitialization - end - - # For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains - # any instance variables with CamelCase names and isn't {.safe_initialization?}. - # @raise when offend found - # @return [true] - def self.ensure_safe_initialization_when_final_fields_are_present - Object.class_eval do - def self.new(*args, &block) - object = super(*args, &block) - ensure - has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ } - if has_final_field && !safe_initialization? - raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!" - end - end - end - true - end - - # Creates methods for reading and writing to a instance variable with - # volatile (Java) semantic as {.attr_volatile} does. - # The instance variable should be accessed oly through generated methods. - # This method generates following methods: `value`, `value=(new_value) #=> new_value`, - # `swap_value(new_value) #=> old_value`, - # `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`. - # @param [::Array] names of the instance variables to be volatile with CAS. - # @return [::Array] names of defined method names. - # @!macro attr_atomic - # @!method $1 - # @return [Object] The $1. - # @!method $1=(new_$1) - # Set the $1. - # @return [Object] new_$1. - # @!method swap_$1(new_$1) - # Set the $1 to new_$1 and return the old $1. - # @return [Object] old $1 - # @!method compare_and_set_$1(expected_$1, new_$1) - # Sets the $1 to new_$1 if the current $1 is expected_$1 - # @return [true, false] - # @!method update_$1(&block) - # Updates the $1 using the block. - # @yield [Object] Calculate a new $1 using given (old) $1 - # @yieldparam [Object] old $1 - # @return [Object] new $1 - def self.attr_atomic(*names) - @__atomic_fields__ ||= [] - @__atomic_fields__ += names - safe_initialization! - define_initialize_atomic_fields - - names.each do |name| - ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}" - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{name} - #{ivar}.get - end - - def #{name}=(value) - #{ivar}.set value - end - - def swap_#{name}(value) - #{ivar}.swap value - end - - def compare_and_set_#{name}(expected, value) - #{ivar}.compare_and_set expected, value - end - - def update_#{name}(&block) - #{ivar}.update(&block) - end - RUBY - end - names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] } - end - - # @param [true, false] inherited should inherited volatile with CAS fields be returned? - # @return [::Array] Returns defined volatile with CAS fields on this class. - def self.atomic_attributes(inherited = true) - @__atomic_fields__ ||= [] - ((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__ - end - - # @return [true, false] is the attribute with name atomic? - def self.atomic_attribute?(name) - atomic_attributes.include? name - end - - private - - def self.define_initialize_atomic_fields - assignments = @__atomic_fields__.map do |name| - "@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)" - end.join("\n") - - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def __initialize_atomic_fields__ - super - #{assignments} - end - RUBY - end - - private_class_method :define_initialize_atomic_fields - - def __initialize_atomic_fields__ - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb deleted file mode 100644 index f785e35..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'concurrent/synchronization/full_memory_barrier' - -module Concurrent - module Synchronization - - # @!visibility private - # @!macro internal_implementation_note - # - # By extending this module, a class and all its children are marked to be constructed safely. Meaning that - # all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures - # same behaviour as Java's final fields. - # - # Due to using Kernel#extend, the module is not included again if already present in the ancestors, - # which avoids extra overhead. - # - # @example - # class AClass < Concurrent::Synchronization::Object - # extend Concurrent::Synchronization::SafeInitialization - # - # def initialize - # @AFinalValue = 'value' # published safely, #foo will never return nil - # end - # - # def foo - # @AFinalValue - # end - # end - module SafeInitialization - def new(*args, &block) - super(*args, &block) - ensure - Concurrent::Synchronization.full_memory_barrier - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/volatile.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/volatile.rb deleted file mode 100644 index 46e8ba6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'concurrent/utility/native_extension_loader' # load native parts first -require 'concurrent/utility/engine' -require 'concurrent/synchronization/full_memory_barrier' - -module Concurrent - module Synchronization - - # Volatile adds the attr_volatile class method when included. - # - # @example - # class Foo - # include Concurrent::Synchronization::Volatile - # - # attr_volatile :bar - # - # def initialize - # self.bar = 1 - # end - # end - # - # foo = Foo.new - # foo.bar - # => 1 - # foo.bar = 2 - # => 2 - # - # @!visibility private - module Volatile - def self.included(base) - base.extend(ClassMethods) - end - - def full_memory_barrier - Synchronization.full_memory_barrier - end - - module ClassMethods - if Concurrent.on_cruby? - def attr_volatile(*names) - names.each do |name| - ivar = :"@volatile_#{name}" - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{name} - #{ivar} - end - - def #{name}=(value) - #{ivar} = value - end - RUBY - end - names.map { |n| [n, :"#{n}="] }.flatten - end - - elsif Concurrent.on_jruby? - def attr_volatile(*names) - names.each do |name| - ivar = :"@volatile_#{name}" - - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{name} - ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_get_volatile(self, :#{ivar}) - end - - def #{name}=(value) - ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_set_volatile(self, :#{ivar}, value) - end - RUBY - - end - names.map { |n| [n, :"#{n}="] }.flatten - end - - else - warn 'Possibly unsupported Ruby implementation' unless Concurrent.on_truffleruby? - - def attr_volatile(*names) - names.each do |name| - ivar = :"@volatile_#{name}" - - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{name} - ::Concurrent::Synchronization.full_memory_barrier - #{ivar} - end - - def #{name}=(value) - #{ivar} = value - ::Concurrent::Synchronization.full_memory_barrier - end - RUBY - end - - names.map { |n| [n, :"#{n}="] }.flatten - end - end - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb deleted file mode 100644 index 019d843..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'delegate' -require 'monitor' - -module Concurrent - # This class provides a trivial way to synchronize all calls to a given object - # by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls - # around the delegated `#send`. Example: - # - # array = [] # not thread-safe on many impls - # array = SynchronizedDelegator.new([]) # thread-safe - # - # A simple `Monitor` provides a very coarse-grained way to synchronize a given - # object, in that it will cause synchronization for methods that have no need - # for it, but this is a trivial way to get thread-safety where none may exist - # currently on some implementations. - # - # This class is currently being considered for inclusion into stdlib, via - # https://bugs.ruby-lang.org/issues/8556 - # - # @!visibility private - class SynchronizedDelegator < SimpleDelegator - def setup - @old_abort = Thread.abort_on_exception - Thread.abort_on_exception = true - end - - def teardown - Thread.abort_on_exception = @old_abort - end - - def initialize(obj) - __setobj__(obj) - @monitor = Monitor.new - end - - def method_missing(method, *args, &block) - monitor = @monitor - begin - monitor.enter - super - ensure - monitor.exit - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util.rb deleted file mode 100644 index c67084a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # TODO (pitr-ch 15-Oct-2016): migrate to Utility::NativeInteger - FIXNUM_BIT_SIZE = (0.size * 8) - 2 - MAX_INT = (2 ** FIXNUM_BIT_SIZE) - 1 - # TODO (pitr-ch 15-Oct-2016): migrate to Utility::ProcessorCounter - CPU_COUNT = 16 # is there a way to determine this? - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb deleted file mode 100644 index 7a6e8d5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'concurrent/thread_safe/util' -require 'concurrent/thread_safe/util/striped64' - -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # A Ruby port of the Doug Lea's jsr166e.LondAdder class version 1.8 - # available in public domain. - # - # Original source code available here: - # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8 - # - # One or more variables that together maintain an initially zero - # sum. When updates (method +add+) are contended across threads, - # the set of variables may grow dynamically to reduce contention. - # Method +sum+ returns the current total combined across the - # variables maintaining the sum. - # - # This class is usually preferable to single +Atomic+ reference when - # multiple threads update a common sum that is used for purposes such - # as collecting statistics, not for fine-grained synchronization - # control. Under low update contention, the two classes have similar - # characteristics. But under high contention, expected throughput of - # this class is significantly higher, at the expense of higher space - # consumption. - # - # @!visibility private - class Adder < Striped64 - # Adds the given value. - def add(x) - if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x} - was_uncontended = true - hash = hash_code - unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x}) - retry_update(x, hash, was_uncontended) {|current_value| current_value + x} - end - end - end - - def increment - add(1) - end - - def decrement - add(-1) - end - - # Returns the current sum. The returned value is _NOT_ an - # atomic snapshot: Invocation in the absence of concurrent - # updates returns an accurate result, but concurrent updates that - # occur while the sum is being calculated might not be - # incorporated. - def sum - x = base - if current_cells = cells - current_cells.each do |cell| - x += cell.value if cell - end - end - x - end - - def reset - internal_reset(0) - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb deleted file mode 100644 index 01eb98f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'concurrent/thread_safe/util' -require 'concurrent/utility/engine' - -# Shim for TruffleRuby.synchronized -if Concurrent.on_truffleruby? && !TruffleRuby.respond_to?(:synchronized) - module TruffleRuby - def self.synchronized(object, &block) - Truffle::System.synchronized(object, &block) - end - end -end - -module Concurrent - module ThreadSafe - module Util - def self.make_synchronized_on_cruby(klass) - klass.class_eval do - def initialize(*args, &block) - @_monitor = Monitor.new - super - end - - def initialize_copy(other) - # make sure a copy is not sharing a monitor with the original object! - @_monitor = Monitor.new - super - end - end - - klass.superclass.instance_methods(false).each do |method| - klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{method}(*args) - monitor = @_monitor - monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.") - monitor.synchronize { super } - end - RUBY - end - end - - def self.make_synchronized_on_truffleruby(klass) - klass.superclass.instance_methods(false).each do |method| - klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{method}(*args, &block) - TruffleRuby.synchronized(self) { super(*args, &block) } - end - RUBY - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb deleted file mode 100644 index b54be39..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'concurrent/thread_safe/util' -require 'concurrent/tuple' - -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # @!visibility private - class PowerOfTwoTuple < Concurrent::Tuple - - def initialize(size) - raise ArgumentError, "size must be a power of 2 (#{size.inspect} provided)" unless size > 0 && size & (size - 1) == 0 - super(size) - end - - def hash_to_index(hash) - (size - 1) & hash - end - - def volatile_get_by_hash(hash) - volatile_get(hash_to_index(hash)) - end - - def volatile_set_by_hash(hash, value) - volatile_set(hash_to_index(hash), value) - end - - def next_in_size_table - self.class.new(size << 1) - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb deleted file mode 100644 index 4169c3d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb +++ /dev/null @@ -1,246 +0,0 @@ -require 'concurrent/thread_safe/util' -require 'concurrent/thread_safe/util/power_of_two_tuple' -require 'concurrent/thread_safe/util/volatile' -require 'concurrent/thread_safe/util/xor_shift_random' - -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # A Ruby port of the Doug Lea's jsr166e.Striped64 class version 1.6 - # available in public domain. - # - # Original source code available here: - # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.6 - # - # Class holding common representation and mechanics for classes supporting - # dynamic striping on 64bit values. - # - # This class maintains a lazily-initialized table of atomically updated - # variables, plus an extra +base+ field. The table size is a power of two. - # Indexing uses masked per-thread hash codes. Nearly all methods on this - # class are private, accessed directly by subclasses. - # - # Table entries are of class +Cell+; a variant of AtomicLong padded to - # reduce cache contention on most processors. Padding is overkill for most - # Atomics because they are usually irregularly scattered in memory and thus - # don't interfere much with each other. But Atomic objects residing in - # arrays will tend to be placed adjacent to each other, and so will most - # often share cache lines (with a huge negative performance impact) without - # this precaution. - # - # In part because +Cell+s are relatively large, we avoid creating them until - # they are needed. When there is no contention, all updates are made to the - # +base+ field. Upon first contention (a failed CAS on +base+ update), the - # table is initialized to size 2. The table size is doubled upon further - # contention until reaching the nearest power of two greater than or equal - # to the number of CPUS. Table slots remain empty (+nil+) until they are - # needed. - # - # A single spinlock (+busy+) is used for initializing and resizing the - # table, as well as populating slots with new +Cell+s. There is no need for - # a blocking lock: When the lock is not available, threads try other slots - # (or the base). During these retries, there is increased contention and - # reduced locality, which is still better than alternatives. - # - # Per-thread hash codes are initialized to random values. Contention and/or - # table collisions are indicated by failed CASes when performing an update - # operation (see method +retry_update+). Upon a collision, if the table size - # is less than the capacity, it is doubled in size unless some other thread - # holds the lock. If a hashed slot is empty, and lock is available, a new - # +Cell+ is created. Otherwise, if the slot exists, a CAS is tried. Retries - # proceed by "double hashing", using a secondary hash (XorShift) to try to - # find a free slot. - # - # The table size is capped because, when there are more threads than CPUs, - # supposing that each thread were bound to a CPU, there would exist a - # perfect hash function mapping threads to slots that eliminates collisions. - # When we reach capacity, we search for this mapping by randomly varying the - # hash codes of colliding threads. Because search is random, and collisions - # only become known via CAS failures, convergence can be slow, and because - # threads are typically not bound to CPUS forever, may not occur at all. - # However, despite these limitations, observed contention rates are - # typically low in these cases. - # - # It is possible for a +Cell+ to become unused when threads that once hashed - # to it terminate, as well as in the case where doubling the table causes no - # thread to hash to it under expanded mask. We do not try to detect or - # remove such cells, under the assumption that for long-running instances, - # observed contention levels will recur, so the cells will eventually be - # needed again; and for short-lived ones, it does not matter. - # - # @!visibility private - class Striped64 - - # Padded variant of AtomicLong supporting only raw accesses plus CAS. - # The +value+ field is placed between pads, hoping that the JVM doesn't - # reorder them. - # - # Optimisation note: It would be possible to use a release-only - # form of CAS here, if it were provided. - # - # @!visibility private - class Cell < Concurrent::AtomicReference - - alias_method :cas, :compare_and_set - - def cas_computed - cas(current_value = value, yield(current_value)) - end - - # @!visibility private - def self.padding - # TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot - # TODO (pitr-ch 28-Jul-2018): the padding instance vars may not be created - # hide from yardoc in a method - attr_reader :padding_0, :padding_1, :padding_2, :padding_3, :padding_4, :padding_5, :padding_6, :padding_7, :padding_8, :padding_9, :padding_10, :padding_11 - end - padding - end - - extend Volatile - attr_volatile :cells, # Table of cells. When non-null, size is a power of 2. - :base, # Base value, used mainly when there is no contention, but also as a fallback during table initialization races. Updated via CAS. - :busy # Spinlock (locked via CAS) used when resizing and/or creating Cells. - - alias_method :busy?, :busy - - def initialize - super() - self.busy = false - self.base = 0 - end - - # Handles cases of updates involving initialization, resizing, - # creating new Cells, and/or contention. See above for - # explanation. This method suffers the usual non-modularity - # problems of optimistic retry code, relying on rechecked sets of - # reads. - # - # Arguments: - # [+x+] - # the value - # [+hash_code+] - # hash code used - # [+x+] - # false if CAS failed before call - def retry_update(x, hash_code, was_uncontended) # :yields: current_value - hash = hash_code - collided = false # True if last slot nonempty - while true - if current_cells = cells - if !(cell = current_cells.volatile_get_by_hash(hash)) - if busy? - collided = false - else # Try to attach new Cell - if try_to_install_new_cell(Cell.new(x), hash) # Optimistically create and try to insert new cell - break - else - redo # Slot is now non-empty - end - end - elsif !was_uncontended # CAS already known to fail - was_uncontended = true # Continue after rehash - elsif cell.cas_computed {|current_value| yield current_value} - break - elsif current_cells.size >= CPU_COUNT || cells != current_cells # At max size or stale - collided = false - elsif collided && expand_table_unless_stale(current_cells) - collided = false - redo # Retry with expanded table - else - collided = true - end - hash = XorShiftRandom.xorshift(hash) - - elsif try_initialize_cells(x, hash) || cas_base_computed {|current_base| yield current_base} - break - end - end - self.hash_code = hash - end - - private - # Static per-thread hash code key. Shared across all instances to - # reduce Thread locals pollution and because adjustments due to - # collisions in one table are likely to be appropriate for - # others. - THREAD_LOCAL_KEY = "#{name}.hash_code".to_sym - - # A thread-local hash code accessor. The code is initially - # random, but may be set to a different value upon collisions. - def hash_code - Thread.current[THREAD_LOCAL_KEY] ||= XorShiftRandom.get - end - - def hash_code=(hash) - Thread.current[THREAD_LOCAL_KEY] = hash - end - - # Sets base and all +cells+ to the given value. - def internal_reset(initial_value) - current_cells = cells - self.base = initial_value - if current_cells - current_cells.each do |cell| - cell.value = initial_value if cell - end - end - end - - def cas_base_computed - cas_base(current_base = base, yield(current_base)) - end - - def free? - !busy? - end - - def try_initialize_cells(x, hash) - if free? && !cells - try_in_busy do - unless cells # Recheck under lock - new_cells = PowerOfTwoTuple.new(2) - new_cells.volatile_set_by_hash(hash, Cell.new(x)) - self.cells = new_cells - end - end - end - end - - def expand_table_unless_stale(current_cells) - try_in_busy do - if current_cells == cells # Recheck under lock - new_cells = current_cells.next_in_size_table - current_cells.each_with_index {|x, i| new_cells.volatile_set(i, x)} - self.cells = new_cells - end - end - end - - def try_to_install_new_cell(new_cell, hash) - try_in_busy do - # Recheck under lock - if (current_cells = cells) && !current_cells.volatile_get(i = current_cells.hash_to_index(hash)) - current_cells.volatile_set(i, new_cell) - end - end - end - - def try_in_busy - if cas_busy(false, true) - begin - yield - ensure - self.busy = false - end - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb deleted file mode 100644 index cdac2a3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'concurrent/thread_safe/util' - -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # @!visibility private - module Volatile - - # Provides +volatile+ (in the JVM's sense) attribute accessors implemented - # atop of +Concurrent::AtomicReference+. - # - # Usage: - # class Foo - # extend Concurrent::ThreadSafe::Util::Volatile - # attr_volatile :foo, :bar - # - # def initialize(bar) - # super() # must super() into parent initializers before using the volatile attribute accessors - # self.bar = bar - # end - # - # def hello - # my_foo = foo # volatile read - # self.foo = 1 # volatile write - # cas_foo(1, 2) # => true | a strong CAS - # end - # end - def attr_volatile(*attr_names) - return if attr_names.empty? - include(Module.new do - atomic_ref_setup = attr_names.map {|attr_name| "@__#{attr_name} = Concurrent::AtomicReference.new"} - initialize_copy_setup = attr_names.zip(atomic_ref_setup).map do |attr_name, ref_setup| - "#{ref_setup}(other.instance_variable_get(:@__#{attr_name}).get)" - end - class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def initialize(*) - super - #{atomic_ref_setup.join('; ')} - end - - def initialize_copy(other) - super - #{initialize_copy_setup.join('; ')} - end - RUBY_EVAL - - attr_names.each do |attr_name| - class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{attr_name} - @__#{attr_name}.get - end - - def #{attr_name}=(value) - @__#{attr_name}.set(value) - end - - def compare_and_set_#{attr_name}(old_value, new_value) - @__#{attr_name}.compare_and_set(old_value, new_value) - end - RUBY_EVAL - - alias_method :"cas_#{attr_name}", :"compare_and_set_#{attr_name}" - alias_method :"lazy_set_#{attr_name}", :"#{attr_name}=" - end - end) - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb deleted file mode 100644 index bdde2dd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'concurrent/thread_safe/util' - -module Concurrent - - # @!visibility private - module ThreadSafe - - # @!visibility private - module Util - - # A xorshift random number (positive +Fixnum+s) generator, provides - # reasonably cheap way to generate thread local random numbers without - # contending for the global +Kernel.rand+. - # - # Usage: - # x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed - # while true - # if (x = XorShiftRandom.xorshift).odd? # thread-localy generate a next random number - # do_something_at_random - # end - # end - module XorShiftRandom - extend self - MAX_XOR_SHIFTABLE_INT = MAX_INT - 1 - - # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+. - def get - Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted - end - - # xorshift based on: http://www.jstatsoft.org/v08/i14/paper - if 0.size == 4 - # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (3,1,14) to minimise Bignum overflows - def xorshift(x) - x ^= x >> 3 - x ^= (x << 1) & MAX_INT # cut-off Bignum overflow - x ^= x >> 14 - end - else - # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows - def xorshift(x) - x ^= x >> 1 - x ^= (x << 1) & MAX_INT # cut-off Bignum overflow - x ^= x >> 54 - end - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/timer_task.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/timer_task.rb deleted file mode 100644 index dd2037f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/timer_task.rb +++ /dev/null @@ -1,361 +0,0 @@ -require 'concurrent/collection/copy_on_notify_observer_set' -require 'concurrent/concern/dereferenceable' -require 'concurrent/concern/observable' -require 'concurrent/atomic/atomic_boolean' -require 'concurrent/executor/executor_service' -require 'concurrent/executor/ruby_executor_service' -require 'concurrent/executor/safe_task_executor' -require 'concurrent/scheduled_task' - -module Concurrent - - # A very common concurrency pattern is to run a thread that performs a task at - # regular intervals. The thread that performs the task sleeps for the given - # interval then wakes up and performs the task. Lather, rinse, repeat... This - # pattern causes two problems. First, it is difficult to test the business - # logic of the task because the task itself is tightly coupled with the - # concurrency logic. Second, an exception raised while performing the task can - # cause the entire thread to abend. In a long-running application where the - # task thread is intended to run for days/weeks/years a crashed task thread - # can pose a significant problem. `TimerTask` alleviates both problems. - # - # When a `TimerTask` is launched it starts a thread for monitoring the - # execution interval. The `TimerTask` thread does not perform the task, - # however. Instead, the TimerTask launches the task on a separate thread. - # Should the task experience an unrecoverable crash only the task thread will - # crash. This makes the `TimerTask` very fault tolerant. Additionally, the - # `TimerTask` thread can respond to the success or failure of the task, - # performing logging or ancillary operations. - # - # One other advantage of `TimerTask` is that it forces the business logic to - # be completely decoupled from the concurrency logic. The business logic can - # be tested separately then passed to the `TimerTask` for scheduling and - # running. - # - # A `TimerTask` supports two different types of interval calculations. - # A fixed delay will always wait the same amount of time between the - # completion of one task and the start of the next. A fixed rate will - # attempt to maintain a constant rate of execution regardless of the - # duration of the task. For example, if a fixed rate task is scheduled - # to run every 60 seconds but the task itself takes 10 seconds to - # complete, the next task will be scheduled to run 50 seconds after - # the start of the previous task. If the task takes 70 seconds to - # complete, the next task will be start immediately after the previous - # task completes. Tasks will not be executed concurrently. - # - # In some cases it may be necessary for a `TimerTask` to affect its own - # execution cycle. To facilitate this, a reference to the TimerTask instance - # is passed as an argument to the provided block every time the task is - # executed. - # - # The `TimerTask` class includes the `Dereferenceable` mixin module so the - # result of the last execution is always available via the `#value` method. - # Dereferencing options can be passed to the `TimerTask` during construction or - # at any later time using the `#set_deref_options` method. - # - # `TimerTask` supports notification through the Ruby standard library - # {http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html - # Observable} module. On execution the `TimerTask` will notify the observers - # with three arguments: time of execution, the result of the block (or nil on - # failure), and any raised exceptions (or nil on success). - # - # @!macro copy_options - # - # @example Basic usage - # task = Concurrent::TimerTask.new{ puts 'Boom!' } - # task.execute - # - # task.execution_interval #=> 60 (default) - # - # # wait 60 seconds... - # #=> 'Boom!' - # - # task.shutdown #=> true - # - # @example Configuring `:execution_interval` - # task = Concurrent::TimerTask.new(execution_interval: 5) do - # puts 'Boom!' - # end - # - # task.execution_interval #=> 5 - # - # @example Immediate execution with `:run_now` - # task = Concurrent::TimerTask.new(run_now: true){ puts 'Boom!' } - # task.execute - # - # #=> 'Boom!' - # - # @example Configuring `:interval_type` with either :fixed_delay or :fixed_rate, default is :fixed_delay - # task = Concurrent::TimerTask.new(execution_interval: 5, interval_type: :fixed_rate) do - # puts 'Boom!' - # end - # task.interval_type #=> :fixed_rate - # - # @example Last `#value` and `Dereferenceable` mixin - # task = Concurrent::TimerTask.new( - # dup_on_deref: true, - # execution_interval: 5 - # ){ Time.now } - # - # task.execute - # Time.now #=> 2013-11-07 18:06:50 -0500 - # sleep(10) - # task.value #=> 2013-11-07 18:06:55 -0500 - # - # @example Controlling execution from within the block - # timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task| - # task.execution_interval.to_i.times{ print 'Boom! ' } - # print "\n" - # task.execution_interval += 1 - # if task.execution_interval > 5 - # puts 'Stopping...' - # task.shutdown - # end - # end - # - # timer_task.execute - # #=> Boom! - # #=> Boom! Boom! - # #=> Boom! Boom! Boom! - # #=> Boom! Boom! Boom! Boom! - # #=> Boom! Boom! Boom! Boom! Boom! - # #=> Stopping... - # - # @example Observation - # class TaskObserver - # def update(time, result, ex) - # if result - # print "(#{time}) Execution successfully returned #{result}\n" - # else - # print "(#{time}) Execution failed with error #{ex}\n" - # end - # end - # end - # - # task = Concurrent::TimerTask.new(execution_interval: 1){ 42 } - # task.add_observer(TaskObserver.new) - # task.execute - # sleep 4 - # - # #=> (2013-10-13 19:08:58 -0400) Execution successfully returned 42 - # #=> (2013-10-13 19:08:59 -0400) Execution successfully returned 42 - # #=> (2013-10-13 19:09:00 -0400) Execution successfully returned 42 - # task.shutdown - # - # task = Concurrent::TimerTask.new(execution_interval: 1){ sleep } - # task.add_observer(TaskObserver.new) - # task.execute - # - # #=> (2013-10-13 19:07:25 -0400) Execution timed out - # #=> (2013-10-13 19:07:27 -0400) Execution timed out - # #=> (2013-10-13 19:07:29 -0400) Execution timed out - # task.shutdown - # - # task = Concurrent::TimerTask.new(execution_interval: 1){ raise StandardError } - # task.add_observer(TaskObserver.new) - # task.execute - # - # #=> (2013-10-13 19:09:37 -0400) Execution failed with error StandardError - # #=> (2013-10-13 19:09:38 -0400) Execution failed with error StandardError - # #=> (2013-10-13 19:09:39 -0400) Execution failed with error StandardError - # task.shutdown - # - # @see http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html - # @see http://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html - class TimerTask < RubyExecutorService - include Concern::Dereferenceable - include Concern::Observable - - # Default `:execution_interval` in seconds. - EXECUTION_INTERVAL = 60 - - # Maintain the interval between the end of one execution and the start of the next execution. - FIXED_DELAY = :fixed_delay - - # Maintain the interval between the start of one execution and the start of the next. - # If execution time exceeds the interval, the next execution will start immediately - # after the previous execution finishes. Executions will not run concurrently. - FIXED_RATE = :fixed_rate - - # Default `:interval_type` - DEFAULT_INTERVAL_TYPE = FIXED_DELAY - - # Create a new TimerTask with the given task and configuration. - # - # @!macro timer_task_initialize - # @param [Hash] opts the options defining task execution. - # @option opts [Float] :execution_interval number of seconds between - # task executions (default: EXECUTION_INTERVAL) - # @option opts [Boolean] :run_now Whether to run the task immediately - # upon instantiation or to wait until the first # execution_interval - # has passed (default: false) - # @options opts [Symbol] :interval_type method to calculate the interval - # between executions, can be either :fixed_rate or :fixed_delay. - # (default: :fixed_delay) - # @option opts [Executor] executor, default is `global_io_executor` - # - # @!macro deref_options - # - # @raise ArgumentError when no block is given. - # - # @yield to the block after :execution_interval seconds have passed since - # the last yield - # @yieldparam task a reference to the `TimerTask` instance so that the - # block can control its own lifecycle. Necessary since `self` will - # refer to the execution context of the block rather than the running - # `TimerTask`. - # - # @return [TimerTask] the new `TimerTask` - def initialize(opts = {}, &task) - raise ArgumentError.new('no block given') unless block_given? - super - set_deref_options opts - end - - # Is the executor running? - # - # @return [Boolean] `true` when running, `false` when shutting down or shutdown - def running? - @running.true? - end - - # Execute a previously created `TimerTask`. - # - # @return [TimerTask] a reference to `self` - # - # @example Instance and execute in separate steps - # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" } - # task.running? #=> false - # task.execute - # task.running? #=> true - # - # @example Instance and execute in one line - # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" }.execute - # task.running? #=> true - def execute - synchronize do - if @running.false? - @running.make_true - schedule_next_task(@run_now ? 0 : @execution_interval) - end - end - self - end - - # Create and execute a new `TimerTask`. - # - # @!macro timer_task_initialize - # - # @example - # task = Concurrent::TimerTask.execute(execution_interval: 10){ print "Hello World\n" } - # task.running? #=> true - def self.execute(opts = {}, &task) - TimerTask.new(opts, &task).execute - end - - # @!attribute [rw] execution_interval - # @return [Fixnum] Number of seconds after the task completes before the - # task is performed again. - def execution_interval - synchronize { @execution_interval } - end - - # @!attribute [rw] execution_interval - # @return [Fixnum] Number of seconds after the task completes before the - # task is performed again. - def execution_interval=(value) - if (value = value.to_f) <= 0.0 - raise ArgumentError.new('must be greater than zero') - else - synchronize { @execution_interval = value } - end - end - - # @!attribute [r] interval_type - # @return [Symbol] method to calculate the interval between executions - attr_reader :interval_type - - # @!attribute [rw] timeout_interval - # @return [Fixnum] Number of seconds the task can run before it is - # considered to have failed. - def timeout_interval - warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' - end - - # @!attribute [rw] timeout_interval - # @return [Fixnum] Number of seconds the task can run before it is - # considered to have failed. - def timeout_interval=(value) - warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' - end - - private :post, :<< - - private - - def ns_initialize(opts, &task) - set_deref_options(opts) - - self.execution_interval = opts[:execution] || opts[:execution_interval] || EXECUTION_INTERVAL - if opts[:interval_type] && ![FIXED_DELAY, FIXED_RATE].include?(opts[:interval_type]) - raise ArgumentError.new('interval_type must be either :fixed_delay or :fixed_rate') - end - if opts[:timeout] || opts[:timeout_interval] - warn 'TimeTask timeouts are now ignored as these were not able to be implemented correctly' - end - - @run_now = opts[:now] || opts[:run_now] - @interval_type = opts[:interval_type] || DEFAULT_INTERVAL_TYPE - @task = Concurrent::SafeTaskExecutor.new(task) - @executor = opts[:executor] || Concurrent.global_io_executor - @running = Concurrent::AtomicBoolean.new(false) - @value = nil - - self.observers = Collection::CopyOnNotifyObserverSet.new - end - - # @!visibility private - def ns_shutdown_execution - @running.make_false - super - end - - # @!visibility private - def ns_kill_execution - @running.make_false - super - end - - # @!visibility private - def schedule_next_task(interval = execution_interval) - ScheduledTask.execute(interval, executor: @executor, args: [Concurrent::Event.new], &method(:execute_task)) - nil - end - - # @!visibility private - def execute_task(completion) - return nil unless @running.true? - start_time = Concurrent.monotonic_time - _success, value, reason = @task.execute(self) - if completion.try? - self.value = value - schedule_next_task(calculate_next_interval(start_time)) - time = Time.now - observers.notify_observers do - [time, self.value, reason] - end - end - nil - end - - # @!visibility private - def calculate_next_interval(start_time) - if @interval_type == FIXED_RATE - run_time = Concurrent.monotonic_time - start_time - [execution_interval - run_time, 0].max - else # FIXED_DELAY - execution_interval - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tuple.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tuple.rb deleted file mode 100644 index 56212cf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tuple.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'concurrent/atomic/atomic_reference' - -module Concurrent - - # A fixed size array with volatile (synchronized, thread safe) getters/setters. - # Mixes in Ruby's `Enumerable` module for enhanced search, sort, and traversal. - # - # @example - # tuple = Concurrent::Tuple.new(16) - # - # tuple.set(0, :foo) #=> :foo | volatile write - # tuple.get(0) #=> :foo | volatile read - # tuple.compare_and_set(0, :foo, :bar) #=> true | strong CAS - # tuple.cas(0, :foo, :baz) #=> false | strong CAS - # tuple.get(0) #=> :bar | volatile read - # - # @see https://en.wikipedia.org/wiki/Tuple Tuple entry at Wikipedia - # @see http://www.erlang.org/doc/reference_manual/data_types.html#id70396 Erlang Tuple - # @see http://ruby-doc.org/core-2.2.2/Enumerable.html Enumerable - class Tuple - include Enumerable - - # The (fixed) size of the tuple. - attr_reader :size - - # Create a new tuple of the given size. - # - # @param [Integer] size the number of elements in the tuple - def initialize(size) - @size = size - @tuple = tuple = ::Array.new(size) - i = 0 - while i < size - tuple[i] = Concurrent::AtomicReference.new - i += 1 - end - end - - # Get the value of the element at the given index. - # - # @param [Integer] i the index from which to retrieve the value - # @return [Object] the value at the given index or nil if the index is out of bounds - def get(i) - return nil if i >= @size || i < 0 - @tuple[i].get - end - alias_method :volatile_get, :get - - # Set the element at the given index to the given value - # - # @param [Integer] i the index for the element to set - # @param [Object] value the value to set at the given index - # - # @return [Object] the new value of the element at the given index or nil if the index is out of bounds - def set(i, value) - return nil if i >= @size || i < 0 - @tuple[i].set(value) - end - alias_method :volatile_set, :set - - # Set the value at the given index to the new value if and only if the current - # value matches the given old value. - # - # @param [Integer] i the index for the element to set - # @param [Object] old_value the value to compare against the current value - # @param [Object] new_value the value to set at the given index - # - # @return [Boolean] true if the value at the given element was set else false - def compare_and_set(i, old_value, new_value) - return false if i >= @size || i < 0 - @tuple[i].compare_and_set(old_value, new_value) - end - alias_method :cas, :compare_and_set - - # Calls the given block once for each element in self, passing that element as a parameter. - # - # @yieldparam [Object] ref the `Concurrent::AtomicReference` object at the current index - def each - @tuple.each {|ref| yield ref.get} - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tvar.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tvar.rb deleted file mode 100644 index 5d02ef0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/tvar.rb +++ /dev/null @@ -1,222 +0,0 @@ -require 'set' -require 'concurrent/synchronization/object' - -module Concurrent - - # A `TVar` is a transactional variable - a single-element container that - # is used as part of a transaction - see `Concurrent::atomically`. - # - # @!macro thread_safe_variable_comparison - # - # {include:file:docs-source/tvar.md} - class TVar < Synchronization::Object - safe_initialization! - - # Create a new `TVar` with an initial value. - def initialize(value) - @value = value - @lock = Mutex.new - end - - # Get the value of a `TVar`. - def value - Concurrent::atomically do - Transaction::current.read(self) - end - end - - # Set the value of a `TVar`. - def value=(value) - Concurrent::atomically do - Transaction::current.write(self, value) - end - end - - # @!visibility private - def unsafe_value # :nodoc: - @value - end - - # @!visibility private - def unsafe_value=(value) # :nodoc: - @value = value - end - - # @!visibility private - def unsafe_lock # :nodoc: - @lock - end - - end - - # Run a block that reads and writes `TVar`s as a single atomic transaction. - # With respect to the value of `TVar` objects, the transaction is atomic, in - # that it either happens or it does not, consistent, in that the `TVar` - # objects involved will never enter an illegal state, and isolated, in that - # transactions never interfere with each other. You may recognise these - # properties from database transactions. - # - # There are some very important and unusual semantics that you must be aware of: - # - # * Most importantly, the block that you pass to atomically may be executed - # more than once. In most cases your code should be free of - # side-effects, except for via TVar. - # - # * If an exception escapes an atomically block it will abort the transaction. - # - # * It is undefined behaviour to use callcc or Fiber with atomically. - # - # * If you create a new thread within an atomically, it will not be part of - # the transaction. Creating a thread counts as a side-effect. - # - # Transactions within transactions are flattened to a single transaction. - # - # @example - # a = new TVar(100_000) - # b = new TVar(100) - # - # Concurrent::atomically do - # a.value -= 10 - # b.value += 10 - # end - def atomically - raise ArgumentError.new('no block given') unless block_given? - - # Get the current transaction - - transaction = Transaction::current - - # Are we not already in a transaction (not nested)? - - if transaction.nil? - # New transaction - - begin - # Retry loop - - loop do - - # Create a new transaction - - transaction = Transaction.new - Transaction::current = transaction - - # Run the block, aborting on exceptions - - begin - result = yield - rescue Transaction::AbortError => e - transaction.abort - result = Transaction::ABORTED - rescue Transaction::LeaveError => e - transaction.abort - break result - rescue => e - transaction.abort - raise e - end - # If we can commit, break out of the loop - - if result != Transaction::ABORTED - if transaction.commit - break result - end - end - end - ensure - # Clear the current transaction - - Transaction::current = nil - end - else - # Nested transaction - flatten it and just run the block - - yield - end - end - - # Abort a currently running transaction - see `Concurrent::atomically`. - def abort_transaction - raise Transaction::AbortError.new - end - - # Leave a transaction without committing or aborting - see `Concurrent::atomically`. - def leave_transaction - raise Transaction::LeaveError.new - end - - module_function :atomically, :abort_transaction, :leave_transaction - - private - - # @!visibility private - class Transaction - - ABORTED = ::Object.new - - OpenEntry = Struct.new(:value, :modified) - - AbortError = Class.new(StandardError) - LeaveError = Class.new(StandardError) - - def initialize - @open_tvars = {} - end - - def read(tvar) - entry = open(tvar) - entry.value - end - - def write(tvar, value) - entry = open(tvar) - entry.modified = true - entry.value = value - end - - def open(tvar) - entry = @open_tvars[tvar] - - unless entry - unless tvar.unsafe_lock.try_lock - Concurrent::abort_transaction - end - - entry = OpenEntry.new(tvar.unsafe_value, false) - @open_tvars[tvar] = entry - end - - entry - end - - def abort - unlock - end - - def commit - @open_tvars.each do |tvar, entry| - if entry.modified - tvar.unsafe_value = entry.value - end - end - - unlock - end - - def unlock - @open_tvars.each_key do |tvar| - tvar.unsafe_lock.unlock - end - end - - def self.current - Thread.current[:current_tvar_transaction] - end - - def self.current=(transaction) - Thread.current[:current_tvar_transaction] = transaction - end - - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/engine.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/engine.rb deleted file mode 100644 index 0c574b2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/engine.rb +++ /dev/null @@ -1,45 +0,0 @@ -module Concurrent - # @!visibility private - module Utility - - # @!visibility private - module EngineDetector - def on_cruby? - RUBY_ENGINE == 'ruby' - end - - def on_jruby? - RUBY_ENGINE == 'jruby' - end - - def on_truffleruby? - RUBY_ENGINE == 'truffleruby' - end - - def on_windows? - !(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/).nil? - end - - def on_osx? - !(RbConfig::CONFIG['host_os'] =~ /darwin|mac os/).nil? - end - - def on_linux? - !(RbConfig::CONFIG['host_os'] =~ /linux/).nil? - end - - def ruby_version(version = RUBY_VERSION, comparison, major, minor, patch) - result = (version.split('.').map(&:to_i) <=> [major, minor, patch]) - comparisons = { :== => [0], - :>= => [1, 0], - :<= => [-1, 0], - :> => [1], - :< => [-1] } - comparisons.fetch(comparison).include? result - end - end - end - - # @!visibility private - extend Utility::EngineDetector -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb deleted file mode 100644 index 1c987d8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Concurrent - - # @!macro monotonic_get_time - # - # Returns the current time as tracked by the application monotonic clock. - # - # @param [Symbol] unit the time unit to be returned, can be either - # :float_second, :float_millisecond, :float_microsecond, :second, - # :millisecond, :microsecond, or :nanosecond default to :float_second. - # - # @return [Float] The current monotonic time since some unspecified - # starting point - # - # @!macro monotonic_clock_warning - def monotonic_time(unit = :float_second) - Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) - end - module_function :monotonic_time -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb deleted file mode 100644 index bf7bab3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'concurrent/utility/engine' -# Synchronization::AbstractObject must be defined before loading the extension -require 'concurrent/synchronization/abstract_object' - -module Concurrent - # @!visibility private - module Utility - # @!visibility private - module NativeExtensionLoader - - def allow_c_extensions? - Concurrent.on_cruby? - end - - def c_extensions_loaded? - defined?(@c_extensions_loaded) && @c_extensions_loaded - end - - def load_native_extensions - if Concurrent.on_cruby? && !c_extensions_loaded? - ['concurrent/concurrent_ruby_ext', - "concurrent/#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" - ].each { |p| try_load_c_extension p } - end - - if Concurrent.on_jruby? && !java_extensions_loaded? - begin - require 'concurrent/concurrent_ruby.jar' - set_java_extensions_loaded - rescue LoadError => e - raise e, "Java extensions are required for JRuby.\n" + e.message, e.backtrace - end - end - end - - private - - def load_error_path(error) - if error.respond_to? :path - error.path - else - error.message.split(' -- ').last - end - end - - def set_c_extensions_loaded - @c_extensions_loaded = true - end - - def java_extensions_loaded? - defined?(@java_extensions_loaded) && @java_extensions_loaded - end - - def set_java_extensions_loaded - @java_extensions_loaded = true - end - - def try_load_c_extension(path) - require path - set_c_extensions_loaded - rescue LoadError => e - if load_error_path(e) == path - # move on with pure-Ruby implementations - # TODO (pitr-ch 12-Jul-2018): warning on verbose? - else - raise e - end - end - - end - end - - # @!visibility private - extend Utility::NativeExtensionLoader -end - -Concurrent.load_native_extensions diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_integer.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_integer.rb deleted file mode 100644 index de1cdc3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/native_integer.rb +++ /dev/null @@ -1,54 +0,0 @@ -module Concurrent - # @!visibility private - module Utility - # @private - module NativeInteger - # http://stackoverflow.com/questions/535721/ruby-max-integer - MIN_VALUE = -(2**(0.size * 8 - 2)) - MAX_VALUE = (2**(0.size * 8 - 2) - 1) - - def ensure_upper_bound(value) - if value > MAX_VALUE - raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}") - end - value - end - - def ensure_lower_bound(value) - if value < MIN_VALUE - raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}") - end - value - end - - def ensure_integer(value) - unless value.is_a?(Integer) - raise ArgumentError.new("#{value} is not an Integer") - end - value - end - - def ensure_integer_and_bounds(value) - ensure_integer value - ensure_upper_bound value - ensure_lower_bound value - end - - def ensure_positive(value) - if value < 0 - raise ArgumentError.new("#{value} cannot be negative") - end - value - end - - def ensure_positive_and_no_zero(value) - if value < 1 - raise ArgumentError.new("#{value} cannot be negative or zero") - end - value - end - - extend self - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/processor_counter.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/processor_counter.rb deleted file mode 100644 index 2489cbd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +++ /dev/null @@ -1,220 +0,0 @@ -require 'etc' -require 'rbconfig' -require 'concurrent/delay' - -module Concurrent - # @!visibility private - module Utility - - # @!visibility private - class ProcessorCounter - def initialize - @processor_count = Delay.new { compute_processor_count } - @physical_processor_count = Delay.new { compute_physical_processor_count } - @cpu_quota = Delay.new { compute_cpu_quota } - @cpu_shares = Delay.new { compute_cpu_shares } - end - - def processor_count - @processor_count.value - end - - def physical_processor_count - @physical_processor_count.value - end - - def available_processor_count - cpu_count = processor_count.to_f - quota = cpu_quota - - return cpu_count if quota.nil? - - # cgroup cpus quotas have no limits, so they can be set to higher than the - # real count of cores. - if quota > cpu_count - cpu_count - else - quota - end - end - - def cpu_quota - @cpu_quota.value - end - - def cpu_shares - @cpu_shares.value - end - - private - - def compute_processor_count - if Concurrent.on_jruby? - java.lang.Runtime.getRuntime.availableProcessors - else - Etc.nprocessors - end - end - - def compute_physical_processor_count - ppc = case RbConfig::CONFIG["target_os"] - when /darwin\d\d/ - IO.popen("/usr/sbin/sysctl -n hw.physicalcpu", &:read).to_i - when /linux/ - cores = {} # unique physical ID / core ID combinations - phy = 0 - IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| - if ln.start_with?("physical") - phy = ln[/\d+/] - elsif ln.start_with?("core") - cid = phy + ":" + ln[/\d+/] - cores[cid] = true if not cores[cid] - end - end - cores.count - when /mswin|mingw/ - # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 - result = run('powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores | Select-Object -Property NumberOfCores"') - if !result || $?.exitstatus != 0 - # fallback to deprecated wmic for older systems - result = run("wmic cpu get NumberOfCores") - end - if !result || $?.exitstatus != 0 - # Bail out if both commands returned something unexpected - processor_count - else - # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" - # wmic: "NumberOfCores \n\n4 \n\n\n\n" - result.scan(/\d+/).map(&:to_i).reduce(:+) - end - else - processor_count - end - # fall back to logical count if physical info is invalid - ppc > 0 ? ppc : processor_count - rescue - return 1 - end - - def run(command) - IO.popen(command, &:read) - rescue Errno::ENOENT - end - - def compute_cpu_quota - if RbConfig::CONFIG["target_os"].include?("linux") - if File.exist?("/sys/fs/cgroup/cpu.max") - # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files - cpu_max = File.read("/sys/fs/cgroup/cpu.max") - return nil if cpu_max.start_with?("max ") # no limit - max, period = cpu_max.split.map(&:to_f) - max / period - elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us") - # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt - max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i - # If the cpu.cfs_quota_us is -1, cgroup does not adhere to any CPU time restrictions - # https://docs.kernel.org/scheduler/sched-bwc.html#management - return nil if max <= 0 - period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f - max / period - end - end - end - - def compute_cpu_shares - if RbConfig::CONFIG["target_os"].include?("linux") - if File.exist?("/sys/fs/cgroup/cpu.weight") - # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files - # Ref: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2 - weight = File.read("/sys/fs/cgroup/cpu.weight").to_f - ((((weight - 1) * 262142) / 9999) + 2) / 1024 - elsif File.exist?("/sys/fs/cgroup/cpu/cpu.shares") - # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt - File.read("/sys/fs/cgroup/cpu/cpu.shares").to_f / 1024 - end - end - end - end - end - - # create the default ProcessorCounter on load - @processor_counter = Utility::ProcessorCounter.new - singleton_class.send :attr_reader, :processor_counter - - # Number of processors seen by the OS and used for process scheduling. For - # performance reasons the calculated value will be memoized on the first - # call. - # - # When running under JRuby the Java runtime call - # `java.lang.Runtime.getRuntime.availableProcessors` will be used. According - # to the Java documentation this "value may change during a particular - # invocation of the virtual machine... [applications] should therefore - # occasionally poll this property." We still memoize this value once under - # JRuby. - # - # Otherwise Ruby's Etc.nprocessors will be used. - # - # @return [Integer] number of processors seen by the OS or Java runtime - # - # @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors() - def self.processor_count - processor_counter.processor_count - end - - # Number of physical processor cores on the current system. For performance - # reasons the calculated value will be memoized on the first call. - # - # On Windows the Win32 API will be queried for the `NumberOfCores from - # Win32_Processor`. This will return the total number "of cores for the - # current instance of the processor." On Unix-like operating systems either - # the `hwprefs` or `sysctl` utility will be called in a subshell and the - # returned value will be used. In the rare case where none of these methods - # work or an exception is raised the function will simply return 1. - # - # @return [Integer] number physical processor cores on the current system - # - # @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb - # - # @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx - # @see http://www.unix.com/man-page/osx/1/HWPREFS/ - # @see http://linux.die.net/man/8/sysctl - def self.physical_processor_count - processor_counter.physical_processor_count - end - - # Number of processors cores available for process scheduling. - # This method takes in account the CPU quota if the process is inside a cgroup with a - # dedicated CPU quota (typically Docker). - # Otherwise it returns the same value as #processor_count but as a Float. - # - # For performance reasons the calculated value will be memoized on the first - # call. - # - # @return [Float] number of available processors - def self.available_processor_count - processor_counter.available_processor_count - end - - # The maximum number of processors cores available for process scheduling. - # Returns `nil` if there is no enforced limit, or a `Float` if the - # process is inside a cgroup with a dedicated CPU quota (typically Docker). - # - # Note that nothing prevents setting a CPU quota higher than the actual number of - # cores on the system. - # - # For performance reasons the calculated value will be memoized on the first - # call. - # - # @return [nil, Float] Maximum number of available processors as set by a cgroup CPU quota, or nil if none set - def self.cpu_quota - processor_counter.cpu_quota - end - - # The CPU shares requested by the process. For performance reasons the calculated - # value will be memoized on the first call. - # - # @return [Float, nil] CPU shares requested by the process, or nil if not set - def self.cpu_shares - processor_counter.cpu_shares - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/version.rb b/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/version.rb deleted file mode 100644 index 1b0c4c2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Concurrent - VERSION = '1.3.4' -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/CHANGELOG.md b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/CHANGELOG.md deleted file mode 100644 index cd42c39..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/CHANGELOG.md +++ /dev/null @@ -1,179 +0,0 @@ -# Changelog - -## 1.2.7 (May 12, 2018) -* Fix segfault on large numbers of connections [#843] - -## 1.2.6 (April 30, 2018) -* *Fix segfault when an Exception is raised from unbind callback (for real this time!)* -* Fix race condition while initializing the machine [#756] -* Fix for newer compilers where bind() and std::bind() conflict [#830, #831] -* Be verbose about SSL connection errors [#807] -* Avoid explicitly calling class methods when in class scope -* Java: Add EM_PROTO_SSL/TLS definitions [#773, #791] -* Java: return zero when sending data to a closed connection [#475, #804] -* Pure Ruby: Connection::error? calls report_connection_error_status [#801] - -## 1.2.5 (July 27, 2017) -* Java: Use long for larger values in oneshot timer intervals [#784, #794] - -## 1.2.4 (July 27, 2017) -* Java: Add EM_PROTO_SSL/TLS definitions [#773, #791] -* Fix IPv6 UDP get_peername [#788] -* Allow for larger values in oneshot timer intervals [#784, #793] -* Update extconf.rb to allow MinGW builds with OpenSSL 1.1.0 [#785] - -## 1.2.3 (February 22, 2017) -* Pure Ruby: Add get_sockname [#308, #772] -* Fix segfault when an Exception is raised from unbind callback [#765, #766] -* Allow destructors to throw when compiling in >= C++11 [#767] - -## 1.2.2 (January 23, 2017) -* Java: Fix Fixnum deprecated warning in Ruby 2.4+ [#759] -* Fix uncaught C++ exception in file watcher and raise InvalidSignature [#512, #757] -* Fix connection count off-by-one for epoll and kqueue [#750] -* Fix uninitialized variable warning in EM::P::HttpClient [#749] -* Fix missing initial value for EventableDescriptor NextHeartbeat [#748] -* Fix hostname resolution on Solaris, Ilumos, SmartOS, et al [#745, #746] -* Improve reliability of tests, reduce public Internet accesses in tests [#656, #666, #749] - -## 1.2.1 (November 15, 2016) -* Throw strerror(errno) when getsockname or getpeername fail [#683] -* Use a single concrete implementation of getpeername/getsockname, the rest pure virtuals [#683] -* Use gai_strerror to get the failure string from getaddrinfo [#744] -* Fix deregistering descriptor when using KQUEUE [#728] -* Fix to enable to work an example code in EM::Pool [#731] -* LineText2: Add regular expression delimiter support [#706] -* Pure Ruby: EM rescue ECONNREFUSED on initial TCP connect [#741] -* Pure Ruby: EM SSL (working start_tls) [#712] -* Pure Ruby: EM fixes [#707] -* Java: Use Acceptors to get peer and sock names if not present in Connections [#743] - -## 1.2.0.1 (March 15, 2016) -* Fix crash when accepting IPv6 connections due to struct sockaddr_in [#698, #699] - -## 1.2.0 (March 15, 2016) -* Integrate work from the EventMachine-LE 1.1.x versions [#570] -* Add start_tls options :ecdh_curve, :dhparam, :fail_if_no_peer_cert [#195, #275, #399, #665] -* Add start_tls option :ssl_version for choosing SSL/TLS versions and ciphers [#359, #348, #603, #654] -* Add start_tls option :sni_hostname to be passed to TLS params [#593] -* Add method EM::Channel#num_subscribers to get the number of subscribers to a channel [#640] -* Add support for proc-sources in EM::Iterator [#639] -* Factor out method cleanup_machine to cleanup code from EM.run [#650] -* Replace Exception class with StandardError [#637] -* Close socket on close_connection even after close_connection_after_writing [#694] -* Allow reusing of datagram socket/setting bind device [#662] -* Handle deferred exceptions in reactor thread [#486] -* Reimplement Queue to avoid shift/push performance problem [#311] -* Windows: Switch from gethostbyname to getaddrinfo, support IPv6 addresses [#303, #630] -* Windows: Use rake-compiler-dock to cross-compile gems [#627] -* Windows: Add AppVeyor configuration for Windows CI testing [#578] -* Windows: Bump rake-compiler to version 0.9.x [#542] -* Fix compilation on AIX (w/ XLC) [#693] -* Fix build on OpenBSD [#690] -* Fix OpenSSL compile issue on AIX 7.1 [#678] -* Fix EventMachine.fork_reactor keeps the threadpool of the original process [#425] -* Fix to prevent event machine from stopping when a raise is done in an unbind [#327] - -## 1.0.9.1 (January 14, 2016) -* Fix EPROTO not defined on Windows [#676] -* Fix missing cast to struct sockaddr * [#671] -* Fix bug in OpenSSL path detection [#675] - -## 1.0.9 (January 13, 2016) -* Try more ways to detect OpenSSL [#602, #643, #661, #663, #668, #669] -* Use WSAGetLastError in pipe.cpp same as ed.cpp [#659] -* Test compiler flags with the C++ compiler and add them to CXXFLAGS [#634, #651] -* Restore silent-fail on unsupported EM.epoll and EM.kqueue [#638, #649] -* getDescriptorByFileno deprecated in JRuby 1.7.x, removed in JRuby 9000 [#642, #648] -* Add -Wno-address always-true because on Windows rb_fd_select [#578] -* Remove the WITHOUT_SSL constant [#578] -* Fix SSL error when the server replies a TLS Alert to our ClientHello [#544, #653] -* Use WSAStringToAddress in lieu of inet_pton for IPv6 address detection on Windows [#595, #632] -* Fix nasty TCP/IPv6 bug [#595, #632] -* Use select_large_fdset on Solaris [#611, #625] -* Detect the Solaris Studio compiler [#611, #625] -* Throw a message with strerror included [#136, #621] - -## 1.0.8 (August 6, 2015) -* fix kqueue assertion failed, postpone ArmKqueueWriter until all events are processed [#51, #176, #372, #401, #619] -* fix Rubinius GC, crank the machine from Ruby space when running Rubinius [#201, #202, #617] -* test to show that LineText2 preserves whitespace and newlines [#32, #622] -* bump up compiler warnings and resolve them [#616] -* fix Windows x64 use uintptr_t instead of unsigned long for binding pointers [#612, #615] -* fix linetext2 unroll tail recursion to avoid stack level too deep [#609] -* fix for compilation with SSL on windows [#601] -* open file descriptors and sockets with O_CLOEXEC where possible [#298, #488, #591] -* fix SmtpClient: send second EHLO after STARTTLS. [#589] -* fix nul-terminated strings in C, use StringValueCStr instead of StringValuePtr - -## 1.0.7 (February 10, 2015) -* fix delay in kqueue/epoll reactor shutdown when timers exist [#587] -* fix memory leak introduced in v1.0.5 [#586] -* expose EM.set_simultaneous_accept_count [#420] -* fix busy loop when EM.run and EM.next_tick are invoked from exception handler [#452] - -## 1.0.6 (February 3, 2015) -* add support for Rubinius Process::Status [#568] -* small bugfixes for SmtpServer [#449] -* update buftok.rb [#547] -* fix assertion on Write() [#525] -* work around mkmf.rb bug preventing gem installation [#574] -* add pause/resume support to jruby reactor [#556] -* fix pure ruby reactor to use 127.0.0.1 instead of localhost [#439] -* fix compilation under macruby [#243] -* add chunked encoding to http client [#111] -* fix errors on win32 when dealing with pipes [1ea45498] [#105] - -## 1.0.5 (February 2, 2015) -* use monotonic clocks on Linux, OS X, Solaris, and Windows [#563] -* use the rb_fd_* API to get autosized fd_sets [#502] -* add basic tests that the DNS resolver isn't leaking timers [#571] -* update to test-unit 2.x and improve various unit tests [#551] -* remove EventMachine_t::Popen code marked by ifdef OBSOLETE [#551] -* ruby 2.0 may fail at Queue.pop, so rescue and complain to $stderr [#551] -* set file handle to INVALID_HANDLE_VALUE after closing the file [#565] -* use `defined?` instead of rescuing NameError for flow control [#535] -* fix closing files and sockets on Windows [#564] -* fix file uploads in Windows [#562] -* catch failure to fork [#539] -* use chunks for SSL write [#545] - -## 1.0.4 (December 19, 2014) -* add starttls_options to smtp server [#552] -* fix closesocket on windows [#497] -* fix build on ruby 2.2 [#503] -* fix build error on ruby 1.9 [#508] -* fix timer leak during dns resolution [#489] -* add concurrency validation to EM::Iterator [#468] -* add get_file_descriptor to get fd for a signature [#467] -* add EM.attach_server and EM.attach_socket_server [#465, #466] -* calling pause from receive_data takes effect immediately [#464] -* reactor_running? returns false after fork [#455] -* fix infinite loop on double close [edc4d0e6, #441, #445] -* fix compilation issue on llvm [#433] -* fix socket error codes on win32 [ff811a81] -* fix EM.stop latency when timers exist [8b613d05, #426] -* fix infinite loop when system time changes [1427a2c80, #428] -* fix crash when callin attach/detach in the same tick [#427] -* fix compilation issue on solaris [#416] - -## 1.0.3 (March 8, 2013) -* EM.system was broken in 1.0.2 release [#413] - -## 1.0.2 (March 8, 2013) -* binary win32 gems now include fastfilereader shim [#222] -* fix long-standing connection timeout issues [27fdd5b, igrigorik/em-http-request#222] -* http and line protocol cleanups [#193, #151] -* reactor return value cleanup [#225] -* fix double require from gemspec [#284] -* fix smtp server reset behavior [#351] -* fix EM.system argument handling [#322] -* ruby 1.9 compat in smtp server and stomp protocols [#349, #315] -* fix pause from post_init [#380] - -## 1.0.1 (February 27, 2013) -* use rb_wait_for_single_fd() on ruby 2.0 to fix rb_thread_select() deprecation [#363] -* fix epoll/kqueue mode in ruby 2.0 by removing calls to rb_enable_interrupt() [#248, #389] -* fix memory leak when verifying ssl cerificates [#403] -* fix initial connection delay [#393, #374] -* fix build on windows [#371] diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/GNU b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/GNU deleted file mode 100644 index 3b70c5b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/GNU +++ /dev/null @@ -1,281 +0,0 @@ -. - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your - freedom to share and change it. By contrast, the GNU General Public - License is intended to guarantee your freedom to share and change free - software--to make sure the software is free for all its users. This - General Public License applies to most of the Free Software - Foundation's software and to any other program whose authors commit to - using it. (Some other Free Software Foundation software is covered by - the GNU Lesser General Public License instead.) You can apply it to - your programs, too. - - When we speak of free software, we are referring to freedom, not - price. Our General Public Licenses are designed to make sure that you - have the freedom to distribute copies of free software (and charge for - this service if you wish), that you receive source code or can get it - if you want it, that you can change the software or use pieces of it - in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid - anyone to deny you these rights or to ask you to surrender the rights. - These restrictions translate to certain responsibilities for you if you - distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether - gratis or for a fee, you must give the recipients all the rights that - you have. You must make sure that they, too, receive or can get the - source code. And you must show them these terms so they know their - rights. - - We protect your rights with two steps: (1) copyright the software, and - (2) offer you this license which gives you legal permission to copy, - distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain - that everyone understands that there is no warranty for this free - software. If the software is modified by someone else and passed on, we - want its recipients to know that what they have is not the original, so - that any problems introduced by others will not reflect on the original - authors' reputations. - - Finally, any free program is threatened constantly by software - patents. We wish to avoid the danger that redistributors of a free - program will individually obtain patent licenses, in effect making the - program proprietary. To prevent this, we have made it clear that any - patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and - modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains - a notice placed by the copyright holder saying it may be distributed - under the terms of this General Public License. The "Program", below, - refers to any such program or work, and a "work based on the Program" - means either the Program or any derivative work under copyright law: - that is to say, a work containing the Program or a portion of it, - either verbatim or with modifications and/or translated into another - language. (Hereinafter, translation is included without limitation in - the term "modification".) Each licensee is addressed as "you". - - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of - running the Program is not restricted, and the output from the Program - is covered only if its contents constitute a work based on the - Program (independent of having been made by running the Program). - Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's - source code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an appropriate - copyright notice and disclaimer of warranty; keep intact all the - notices that refer to this License and to the absence of any warranty; - and give any other recipients of the Program a copy of this License - along with the Program. - - You may charge a fee for the physical act of transferring a copy, and - you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion - of it, thus forming a work based on the Program, and copy and - distribute such modifications or work under the terms of Section 1 - above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Program, - and can be reasonably considered independent and separate works in - themselves, then this License, and its terms, do not apply to those - sections when you distribute them as separate works. But when you - distribute the same sections as part of a whole which is a work based - on the Program, the distribution of the whole must be on the terms of - this License, whose permissions for other licensees extend to the - entire whole, and thus to each and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or contest - your rights to work written entirely by you; rather, the intent is to - exercise the right to control the distribution of derivative or - collective works based on the Program. - - In addition, mere aggregation of another work not based on the Program - with the Program (or with a work based on the Program) on a volume of - a storage or distribution medium does not bring the other work under - the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the terms of - Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - - The source code for a work means the preferred form of the work for - making modifications to it. For an executable work, complete source - code means all the source code for all modules it contains, plus any - associated interface definition files, plus the scripts used to - control compilation and installation of the executable. However, as a - special exception, the source code distributed need not include - anything that is normally distributed (in either source or binary - form) with the major components (compiler, kernel, and so on) of the - operating system on which the executable runs, unless that component - itself accompanies the executable. - - If distribution of executable or object code is made by offering - access to copy from a designated place, then offering equivalent - access to copy the source code from the same place counts as - distribution of the source code, even though third parties are not - compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program is - void, and will automatically terminate your rights under this License. - However, parties who have received copies, or rights, from you under - this License will not have their licenses terminated so long as such - parties remain in full compliance. - - 5. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to modify or - distribute the Program or its derivative works. These actions are - prohibited by law if you do not accept this License. Therefore, by - modifying or distributing the Program (or any work based on the - Program), you indicate your acceptance of this License to do so, and - all its terms and conditions for copying, distributing or modifying - the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program subject to - these terms and conditions. You may not impose any further - restrictions on the recipients' exercise of the rights granted herein. - You are not responsible for enforcing compliance by third parties to - this License. - - 7. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent issues), - conditions are imposed on you (whether by court order, agreement or - otherwise) that contradict the conditions of this License, they do not - excuse you from the conditions of this License. If you cannot - distribute so as to satisfy simultaneously your obligations under this - License and any other pertinent obligations, then as a consequence you - may not distribute the Program at all. For example, if a patent - license would not permit royalty-free redistribution of the Program by - all those who receive copies directly or indirectly through you, then - the only way you could satisfy both it and this License would be to - refrain entirely from distribution of the Program. - - If any portion of this section is held invalid or unenforceable under - any particular circumstance, the balance of the section is intended to - apply and the section as a whole is intended to apply in other - circumstances. - - It is not the purpose of this section to induce you to infringe any - patents or other property right claims or to contest validity of any - such claims; this section has the sole purpose of protecting the - integrity of the free software distribution system, which is - implemented by public license practices. Many people have made - generous contributions to the wide range of software distributed - through that system in reliance on consistent application of that - system; it is up to the author/donor to decide if he or she is willing - to distribute software through any other system and a licensee cannot - impose that choice. - - This section is intended to make thoroughly clear what is believed to - be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted interfaces, the - original copyright holder who places the Program under this License - may add an explicit geographical distribution limitation excluding - those countries, so that distribution is permitted only in or among - countries not thus excluded. In such case, this License incorporates - the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions - of the General Public License from time to time. Such new versions will - be similar in spirit to the present version, but may differ in detail to - address new problems or concerns. - - Each version is given a distinguishing version number. If the Program - specifies a version number of this License which applies to it and "any - later version", you have the option of following the terms and conditions - either of that version or of any later version published by the Free - Software Foundation. If the Program does not specify a version number of - this License, you may choose any version ever published by the Free Software - Foundation. - - 10. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, write to the author - to ask for permission. For software which is copyrighted by the Free - Software Foundation, write to the Free Software Foundation; we sometimes - make exceptions for this. Our decision will be guided by the two goals - of preserving the free status of all derivatives of our free software and - of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY - FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES - PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED - OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS - TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, - REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING - WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR - REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, - INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING - OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED - TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY - YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/LICENSE b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/LICENSE deleted file mode 100644 index fbe8c83..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/LICENSE +++ /dev/null @@ -1,60 +0,0 @@ -EventMachine is copyrighted free software owned by Francis Cianfrocca -(blackhedd ... gmail.com). The Owner of this software permits you to -redistribute and/or modify the software under either the terms of the GPL -version 2 (see the file GPL), or the conditions below ("Ruby License"): - - 1. You may make and give away verbatim copies of the source form of this - software without restriction, provided that you retain ALL of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the Owner. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in a manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the Owner. - - 4. You may modify and include parts of the software into any other - software (possibly commercial), provided you comply with the terms in - Sections 1, 2, and 3 above. But some files in the distribution - are not written by the Owner, so they may be made available to you - under different terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whoever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/README.md b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/README.md deleted file mode 100644 index 4b17cb4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/README.md +++ /dev/null @@ -1,110 +0,0 @@ -# About EventMachine [![Build Status](https://travis-ci.org/eventmachine/eventmachine.svg?branch=master)](https://travis-ci.org/eventmachine/eventmachine) [![Code Climate Maintainability](https://api.codeclimate.com/v1/badges/e9b0603462905d5b9118/maintainability)](https://codeclimate.com/github/eventmachine/eventmachine/maintainability) - - -## What is EventMachine ## - -EventMachine is an event-driven I/O and lightweight concurrency library for Ruby. -It provides event-driven I/O using the [Reactor pattern](http://en.wikipedia.org/wiki/Reactor_pattern), -much like [JBoss Netty](http://www.jboss.org/netty), [Apache MINA](http://mina.apache.org/), -Python's [Twisted](http://twistedmatrix.com), [Node.js](http://nodejs.org), libevent and libev. - -EventMachine is designed to simultaneously meet two key needs: - - * Extremely high scalability, performance and stability for the most demanding production environments. - * An API that eliminates the complexities of high-performance threaded network programming, - allowing engineers to concentrate on their application logic. - -This unique combination makes EventMachine a premier choice for designers of critical networked -applications, including Web servers and proxies, email and IM production systems, authentication/authorization -processors, and many more. - -EventMachine has been around since the early 2000s and is a mature and battle-tested library. - - -## What EventMachine is good for? ## - - * Scalable event-driven servers. Examples: [Thin](http://code.macournoyer.com/thin/) or [Goliath](https://github.com/postrank-labs/goliath/). - * Scalable asynchronous clients for various protocols, RESTful APIs and so on. Examples: [em-http-request](https://github.com/igrigorik/em-http-request) or [amqp gem](https://github.com/ruby-amqp/amqp). - * Efficient network proxies with custom logic. Examples: [Proxymachine](https://github.com/mojombo/proxymachine/). - * File and network monitoring tools. Examples: [eventmachine-tail](https://github.com/jordansissel/eventmachine-tail) and [logstash](https://github.com/logstash/logstash). - - - -## What platforms are supported by EventMachine? ## - -EventMachine supports Ruby 1.8.7 through 2.6, REE, JRuby and **works well on Windows** as well -as many operating systems from the Unix family (Linux, Mac OS X, BSD flavors). - - - -## Install the gem ## - -Install it with [RubyGems](https://rubygems.org/) - - gem install eventmachine - -or add this to your Gemfile if you use [Bundler](http://gembundler.com/): - - gem "eventmachine" - - - -## Getting started ## - -For an introduction to EventMachine, check out: - - * [blog post about EventMachine by Ilya Grigorik](http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/). - * [EventMachine Introductions by Dan Sinclair](http://everburning.com/news/eventmachine-introductions.html). - - -### Server example: Echo server ### - -Here's a fully-functional echo server written with EventMachine: - -```ruby - require 'eventmachine' - - module EchoServer - def post_init - puts "-- someone connected to the echo server!" - end - - def receive_data data - send_data ">>>you sent: #{data}" - close_connection if data =~ /quit/i - end - - def unbind - puts "-- someone disconnected from the echo server!" - end -end - -# Note that this will block current thread. -EventMachine.run { - EventMachine.start_server "127.0.0.1", 8081, EchoServer -} -``` - - -## EventMachine documentation ## - -Currently we only have [reference documentation](http://rdoc.info/github/eventmachine/eventmachine/frames) and a [wiki](https://github.com/eventmachine/eventmachine/wiki). - - -## Community and where to get help ## - - * Join the [mailing list](http://groups.google.com/group/eventmachine) (Google Group) - * Join IRC channel #eventmachine on irc.freenode.net - - -## License and copyright ## - -EventMachine is copyrighted free software made available under the terms -of either the GPL or Ruby's License. - -Copyright: (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - - -## Alternatives ## - -If you are unhappy with EventMachine and want to use Ruby, check out [Celluloid](https://celluloid.io/). diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/DocumentationGuidesIndex.md b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/DocumentationGuidesIndex.md deleted file mode 100644 index b8ce5a2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/DocumentationGuidesIndex.md +++ /dev/null @@ -1,27 +0,0 @@ -# EventMachine documentation guides # - -Welcome to the documentation guides for [EventMachine](http://github.com/eventmachine/eventmachine), -a fast and simple event-processing library for Ruby programs (à la JBoss Netty, Twisted, Node.js -and so on). - -## Guide list ## - - * {file:docs/GettingStarted.md Getting started with EventMachine} - * {file:docs/EventDrivenServers.md Writing event-driven servers} - * {file:docs/EventDrivenClients.md Writing event-driven clients} - * {file:docs/ConnectionFailureAndRecovery.md Connection Failure and Recovery} - * {file:docs/TLS.md TLS (aka SSL)} - * {file:docs/Ecosystem.md EventMachine ecosystem}: Thin, Goliath, em-http-request, em-websockets, Proxymachine and beyond - * {file:docs/BlockingEventLoop.md On blocking the event loop: why it is harmful for performance and how to avoid it} - * {file:docs/LightweightConcurrency.md Lightweight concurrency with EventMachine} - * {file:docs/Deferrables.md Deferrables} - * {file:docs/ModernKernelInputOutputAPIs.md Brief introduction to epoll, kqueue, select} - * {file:docs/WorkingWithOtherIOSources.md Working with other IO sources such as the keyboard} - - -## Tell us what you think! ## - -Please take a moment and tell us what you think about this guide on the [EventMachine mailing list](http://bit.ly/jW3cR3) -or in the #eventmachine channel on irc.freenode.net: what was unclear? What wasn't covered? -Maybe you don't like the guide style or the grammar and spelling are incorrect? Reader feedback is -key to making documentation better. diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/GettingStarted.md b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/GettingStarted.md deleted file mode 100644 index 63acbb7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/GettingStarted.md +++ /dev/null @@ -1,521 +0,0 @@ -# @title Getting Started with Ruby EventMachine -# @markup markdown -# @author Michael S. Klishin, Dan Sinclair - -# Getting started with Ruby EventMachine # - - -## About this guide ## - -This guide is a quick tutorial that helps you to get started with EventMachine for writing event-driven -servers, clients and using it as a lightweight concurrency library. -It should take about 20 minutes to read and study the provided code examples. This guide covers - - * Installing EventMachine via [Rubygems](http://rubygems.org) and [Bundler](http://gembundler.com). - * Building an Echo server, the "Hello, world"-like code example of network servers. - * Building a simple chat, both server and client. - * Building a very small asynchronous Websockets client. - - -## Covered versions ## - -This guide covers EventMachine v0.12.10 and 1.0 (including betas). - - -## Level ## - -This guide assumes you are comfortable (but not necessary a guru) with the command line. On Microsoft Windows™, -we recommend you to use [JRuby](http://jruby.org) when running these examples. - - -## Installing EventMachine ## - -### Make sure you have Ruby installed ### - -This guide assumes you have one of the supported Ruby implementations installed: - - * Ruby 1.8.7 - * Ruby 1.9.2 - * [JRuby](http://jruby.org) (we recommend 1.6) - * [Rubinius](http://rubini.us) 1.2 or higher - * [Ruby Enterprise Edition](http://www.rubyenterpriseedition.com) - -EventMachine works on Microsoft Windows™. - - -### With Rubygems ### - -To install the EventMachine gem do - - gem install eventmachine - - -### With Bundler ### - - gem "eventmachine" - - -### Verifying your installation ### - -Lets verify your installation with this quick IRB session: - - irb -rubygems - - ruby-1.9.2-p180 :001 > require "eventmachine" - => true - ruby-1.9.2-p180 :002 > EventMachine::VERSION - => "1.0.0.beta.3" - - -## An Echo Server Example ## - -Lets begin with the classic "Hello, world"-like example, an echo server. The echo server responds clients with the -same data that was provided. First, here's the code: - -{include:file:examples/guides/getting\_started/01\_eventmachine\_echo_server.rb} - - -When run, the server binds to port 10000. We can connect using Telnet and verify it's working: - - telnet localhost 10000 - -On my machine the output looks like: - - ~ telnet localhost 10000 - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - -Let's send something to our server. Type in "Hello, EventMachine" and hit Enter. The server will respond with -the same string: - - ~ telnet localhost 10000 - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - Hello, EventMachine - # (here we hit Enter) - Hello, EventMachine - # (this ^^^ is our echo server reply) - -It works! Congratulations, you now can tell your Node.js-loving friends that you "have done some event-driven programming, too". -Oh, and to stop Telnet, hit Control + Shift + ] and then Control + C. - -Lets walk this example line by line and see what's going on. These lines - - require 'rubygems' # or use Bundler.setup - require 'eventmachine' - -probably look familiar: you use [RubyGems](http://rubygems.org) (or [Bundler](http://gembundler.com/)) for dependencies and then require EventMachine gem. Boring. - -Next: - - class EchoServer < EventMachine::Connection - def receive_data(data) - send_data(data) - end - end - -Is the implementation of our echo server. We define a class that inherits from {EventMachine::Connection} -and a handler (aka callback) for one event: when we receive data from a client. - -EventMachine handles the connection setup, receiving data and passing it to our handler, {EventMachine::Connection#receive_data}. - -Then we implement our protocol logic, which in the case of Echo is pretty trivial: we send back whatever we receive. -To do so, we're using {EventMachine::Connection#send_data}. - -Lets modify the example to recognize `exit` command: - -{include:file:examples/guides/getting\_started/02\_eventmachine\_echo_server\_that\_recognizes\_exit\_command.rb} - -Our `receive\_data` changed slightly and now looks like this: - - def receive_data(data) - if data.strip =~ /exit$/i - EventMachine.stop_event_loop - else - send_data(data) - end - end - -Because incoming data has trailing newline character, we strip it off before matching it against a simple regular -expression. If the data ends in `exit`, we stop EventMachine event loop with {EventMachine.stop_event_loop}. This unblocks -main thread and it finishes execution, and our little program exits as the result. - -To summarize this first example: - - * Subclass {EventMachine::Connection} and override {EventMachine::Connection#send_data} to handle incoming data. - * Use {EventMachine.run} to start EventMachine event loop and then bind echo server with {EventMachine.start_server}. - * To stop the event loop, use {EventMachine.stop_event_loop} (aliased as {EventMachine.stop}) - -Lets move on to a slightly more sophisticated example that will introduce several more features and methods -EventMachine has to offer. - - -## A Simple Chat Server Example ## - -Next we will write a simple chat. Initially clients will still use telnet to connect, but then we will add little -client application that will serve as a proxy between telnet and the chat server. This example is certainly longer -(~ 150 lines with whitespace and comments) so instead of looking at the final version and going through it line by line, -we will instead begin with a very simple version that only keeps track of connected clients and then add features -as we go. - -To set some expectations about our example: - - * It will keep track of connected clients - * It will support a couple of commands, à la IRC - * It will support direct messages using Twitter-like @usernames - * It won't use MongoDB, fibers or distributed map/reduce for anything but will be totally [Web Scale™](http://bit.ly/webscaletm) nonetheless. Maybe even [ROFLscale](http://bit.ly/roflscalevideo). - -### Step one: detecting connections and disconnectons ### - -First step looks like this: - -{include:file:examples/guides/getting\_started/04\_simple\_chat\_server\_step\_one.rb} - -We see familiar {EventMachine.run} and {EventMachine.start_server}, but also {EventMachine::Connection#post_init} and {EventMachine::Connection#unbind} we haven't -met yet. We don't use them in this code, so when are they run? Like {EventMachine::Connection#receive_data}, these methods are callbacks. EventMachine calls them -when certain events happen: - - * {EventMachine#post_init} is called by the event loop immediately after the network connection has been established. - In the chat server example case, this is when a new client connects. - * {EventMachine#unbind} is called when client disconnects, connection is closed or is lost (because of a network issue, for example). - -All our chat server does so far is logging connections or disconnections. What we want it to do next is to keep track of connected clients. - - -### Step two: keep track of connected clients ### - -Next iteration of the code looks like this: - -{include:file:examples/guides/getting\_started/05\_simple\_chat\_server\_step\_two.rb} - -While the code we added is very straightforward, we have to clarify one this first: subclasses of {EventMachine::Connection} are instantiated by -EventMachine for every new connected peer. So for 10 connected chat clients, there will be 10 separate `SimpleChatServer` instances in our -server process. Like any other objects, they can be stored in a collection, can provide public API other objects use, can instantiate or inject -dependencies and in general live a happy life all Ruby objects live until garbage collection happens. - -In the example above we use a @@class_variable to keep track of connected clients. In Ruby, @@class variables are accessible from instance -methods so we can add new connections to the list from `SimpleChatServer#post_init` and remove them in `SimpleChatServer#unbind`. We can also -filter connections by some criteria, as `SimpleChatServer#other_peers demonstrates`. - -So, we keep track of connections but how do we identify them? For a chat app, it's pretty common to use usernames for that. Lets ask our clients -to enter usernames when they connect. - - -### Step three: adding usernames ## - -To add usernames, we need to add a few things: - - * We need to invite newly connected clients to enter their username. - * A reader (getter) method on our {EventMachine::Connection} subclass. - * An idea of connection state (keeping track of whether a particular participant had entered username before). - -Here is one way to do it: - -{include:file:examples/guides/getting\_started/06\_simple\_chat\_server\_step\_three.rb} - -This is quite an update so lets take a look at each method individually. First, `SimpleChatServer#post_init`: - - def post_init - @username = nil - puts "A client has connected..." - ask_username - end - -To keep track of username we ask chat participants for, we add @username instance variable to our connection class. Connection -instances are just Ruby objects associated with a particular connected peer, so using @ivars is very natural. To make username -value accessible to other objects, we added a reader method that was not shown on the snippet above. - -Lets dig into `SimpleChatServer#ask_username`: - - def ask_username - self.send_line("[info] Enter your username:") - end # ask_username - - # ... - - def send_line(line) - self.send_data("#{line}\n") - end # send_line(line) - -Nothing new here, we are using {EventMachine::Connection#send_data} which we have seen before. - - -In `SimpleChatServer#receive_data` we now have to check if the username was entered or we need -to ask for it: - - def receive_data(data) - if entered_username? - handle_chat_message(data.strip) - else - handle_username(data.strip) - end - end - - # ... - - def entered_username? - !@username.nil? && !@username.empty? - end # entered_username? - -Finally, handler of chat messages is not yet implemented: - - def handle_chat_message(msg) - raise NotImplementedError - end - -Lets try this example out using Telnet: - - ~ telnet localhost 10000 - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - [info] Enter your username: - antares_ - [info] Ohai, antares_ - -and the server output: - - A client has connected... - antares_ has joined - -This version requires you to remember how to terminate your Telnet session (Ctrl + Shift + ], then Ctrl + C). -It is annoying, so why don't we add the same `exit` command to our chat server? - - -### Step four: adding exit command and delivering chat messages #### - -{include:file:examples/guides/getting\_started/07\_simple\_chat\_server\_step\_four.rb} - -TBD - -Lets test-drive this version. Client A: - - ~ telnet localhost 10000 - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - [info] Enter your username: - michael - [info] Ohai, michael - Hi everyone - michael: Hi everyone - joe has joined the room - # here ^^^ client B connects, lets greet him - hi joe - michael: hi joe - joe: hey michael - # ^^^ client B replies - exit - # ^^^ out command in action - Connection closed by foreign host. - -Client B: - - ~ telnet localhost 10000 - Trying 127.0.0.1... - Connected to localhost. - Escape character is '^]'. - [info] Enter your username: - joe - [info] Ohai, joe - michael: hi joe - # ^^^ client A greets us, lets reply - hey michael - joe: hey michael - exit - # ^^^ out command in action - Connection closed by foreign host. - -And finally, the server output: - - A client has connected... - michael has joined - A client has connected... - _antares has joined - [info] _antares has left - [info] michael has left - -Our little char server now supports usernames, sending messages and the `exit` command. Next up, private (aka direct) messages. - - -### Step five: adding direct messages and one more command ### - -To add direct messages, we come up with a simple convention: private messages begin with @username and may have optional colon before -message text, like this: - - @joe: hey, how do you like eventmachine? - -This convention makes parsing of messages simple so that we can concentrate on delivering them to a particular client connection. -Remember when we added `username` reader on our connection class? That tiny change makes this step possible: when a new direct -message comes in, we extract username and message text and then find then connection for @username in question: - - # - # Message handling - # - - def handle_chat_message(msg) - if command?(msg) - self.handle_command(msg) - else - if direct_message?(msg) - self.handle_direct_message(msg) - else - self.announce(msg, "#{@username}:") - end - end - end # handle_chat_message(msg) - - def direct_message?(input) - input =~ DM_REGEXP - end # direct_message?(input) - - def handle_direct_message(input) - username, message = parse_direct_message(input) - - if connection = @@connected_clients.find { |c| c.username == username } - puts "[dm] @#{@username} => @#{username}" - connection.send_line("[dm] @#{@username}: #{message}") - else - send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}" - end - end # handle_direct_message(input) - - def parse_direct_message(input) - return [$1, $2] if input =~ DM_REGEXP - end # parse_direct_message(input) - -This snippet demonstrates how one connection instance can obtain another connection instance and send data to it. -This is a very powerful feature, consider just a few use cases: - - * Peer-to-peer protocols - * Content-aware routing - * Efficient streaming with optional filtering - -Less common use cases include extending C++ core of EventMachine to provide access to hardware that streams events that -can be re-broadcasted to any interested parties connected via TCP, UDP or something like AMQP or WebSockets. With this, -sky is the limit. Actually, EventMachine has several features for efficient proxying data between connections. -We will not cover them in this guide. - -One last feature that we are going to add to our chat server is the `status` command that tells you current server time and how many people -are there in the chat room: - - # - # Commands handling - # - - def command?(input) - input =~ /(exit|status)$/i - end # command?(input) - - def handle_command(cmd) - case cmd - when /exit$/i then self.close_connection - when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room") - end - end # handle_command(cmd) - -Hopefully this piece of code is easy to follow. Try adding a few more commands, for example, the `whoishere` command that lists people -currently in the chat room. - -In the end, our chat server looks like this: - -{include:file:examples/guides/getting\_started/08\_simple\_chat\_server\_step\_five.rb} - -We are almost done with the server but there are some closing thoughts. - - -### Step six: final version ### - -Just in case, here is the final version of the chat server code we have built: - -{include:file:examples/guides/getting\_started/03\_simple\_chat\_server.rb} - - -### Step seven: future directions and some closing thoughts ### - -The chat server is just about 150 lines of Ruby including empty lines and comments, yet it has a few features most of chat server -examples never add. We did not, however, implement many other features that popular IRC clients like [Colloquy](http://colloquy.info) have: - - * Chat moderation - * Multiple rooms - * Connection timeout detection - -How would one go about implementing them? We thought it is worth discussing what else EventMachine has to offer and what ecosystem projects -one can use to build a really feature-rich Web-based IRC chat client. - -With multiple rooms it's more or less straightforward, just add one more hash and a bunch of commands and use the information about which rooms participant -is in when you are delivering messages. There is nothing in EventMachine itself that can make the job much easier for developer. - -To implement chat moderation feature you may want to do a few things: - - * Work with client IP addresses. Maybe we want to consider everyone who connects from certain IPs a moderator. - * Access persistent data about usernames of moderators and their credentials. - -Does EventMachine have anything to offer here? It does. To obtain peer IP address, take a look at {EventMachine::Connection#get_peername}. The name of this method is -a little bit misleading and originates from low-level socket programming APIs. - -#### A whirlwind tour of the EventMachine ecosystem #### - -To work with data stores you can use several database drivers that ship with EventMachine itself, however, quite often there are some 3rd party projects in -the EventMachine ecosystem that have more features, are faster or just better maintained. So we figured it will be helpful to provide a few pointers -to some of those projects: - - * For MySQL, check out [em-mysql](https://github.com/eventmachine/em-mysql) project. - * For PostgreSQL, have a look at Mike Perham's [EventMachine-based PostgreSQL driver](https://github.com/mperham/em_postgresql). - * For Redis, there is a young but already popular [em-hiredis](https://github.com/mloughran/em-hiredis) library that combines EventMachine's non-blocking I/O with - extreme performance of the official Redis C client, [hiredis](https://github.com/antirez/hiredis). - * For MongoDB, see [em-mongo](https://github.com/bcg/em-mongo) - * For Cassandra, Mike Perham [added transport agnosticism feature](http://www.mikeperham.com/2010/02/09/cassandra-and-eventmachine/) to the [cassandra gem](https://rubygems.org/gems/cassandra). - -[Riak](http://www.basho.com/products_riak_overview.php) and CouchDB talk HTTP so it's possible to use [em-http-request](https://github.com/igrigorik/em-http-request). -If you are aware of EventMachine-based non-blocking drivers for these databases, as well as for HBase, let us know on the [EventMachine mailing list](http://groups.google.com/group/eventmachine). -Also, EventMachine supports TLS (aka SSL) and works well on [JRuby](http://jruby.org) and Windows. - -Learn more in our {file:docs/Ecosystem.md EventMachine ecosystem} and {file:docs/TLS.md TLS (aka SSL)} guides. - - -#### Connection loss detection #### - -Finally, connection loss detection. When our chat participant closes her laptop lid, how do we know that she is no longer active? The answer is, when EventMachine -detects TCP connectin closure, it calls {EventMachine::Connection#unbind}. Version 1.0.beta3 and later also pass an optional argument to that method. The argument -indicates what error (if any) caused the connection to be closed. - -Learn more in our {file:docs/ConnectionFailureAndRecovery.md Connection Failure and Recovery} guide. - - -#### What the Chat Server Example doesn't demonstrate #### - -This chat server also leaves out something production quality clients and servers must take care of: buffering. We intentionally did not include any buffering in -our chat server example: it would only distract you from learning what you really came here to learn: how to use EventMachine to build blazing fast asynchronous -networking programs quickly. However, {EventMachine::Connection#receive_data} does not offer any guarantees that you will be receiving "whole messages" all the time, -largely because the underlying transport (UDP or TCP) does not offer such guarantees. Many protocols, for example, AMQP, mandate that large content chunks are -split into smaller _frames_ of certain size. This means that [amq-client](https://github.com/ruby-amqp/amq-client) library, for instance, that has EventMachine-based driver, -has to deal with figuring out when exactly we received "the whole message". To do so, it uses buffering and employs various checks to detect _frame boundaries_. -So **don't be deceived by the simplicity of this chat example**: it intentionally leaves framing out, but real world protocols usually require it. - - - -## A (Proxying) Chat Client Example ## - -TBD - - -## Wrapping up ## - -This tutorial ends here. Congratulations! You have learned quite a bit about EventMachine. - - -## What to read next ## - -The documentation is organized as a {file:docs/DocumentationGuidesIndex.md number of guides}, covering all kinds of -topics. TBD - - -## Tell us what you think! ## - -Please take a moment and tell us what you think about this guide on the [EventMachine mailing list](http://bit.ly/jW3cR3) -or in the #eventmachine channel on irc.freenode.net: what was unclear? What wasn't covered? -Maybe you don't like the guide style or the grammar and spelling are incorrect? Reader feedback is -key to making documentation better. diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/ChangeLog b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/ChangeLog deleted file mode 100644 index c7a6c48..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/ChangeLog +++ /dev/null @@ -1,211 +0,0 @@ -01Oct06: Replaced EventMachine#open_datagram_server with a version that can - take a Class or a Module, instead of just a Module. Thanks to Tobias - Gustafsson for pointing out the missing case. -04Oct06: Supported subsecond timer resolutions, per request by Jason Roelofs. -05Oct06: Added EventMachine#set_quantum, which sets the timer resolution. -15Nov06: Added Connection#set_comm_inactivity_timeout. -15Nov06: Checked in a Line-and-Text Protocol Handler. -18Nov06: Checked in a Header-and-Body Protocol Handler. -22Nov06: Changed EventMachine#reconnect: no longer excepts when called on an - already-connected handler. -28Nov06: Supported a binary-unix gem. -19Dec06: Added EventMachine#set_effective_user. -05Jan07: Upped max outstanding timers to 1000. -15May07: Applied Solaris patches from Brett Eisenberg -22May07: Cleaned up the license text in all the source files. -22May07: Released version 0.7.2 - -23May07: Per suggestion from Bill Kelly, fixed a bug with the initialization - of the network libraries under Windows. The goal is to enable EM to - be used without Ruby. -28May07: Applied patch from Bill Kelly, refactors the declarations of - event names to make EM easier to use from C programs without Ruby. -31May07: Added a preliminary implementation of EventMachine#popen. -01Jun07: Added EM, a "pseudo-alias" for EventMachine. -01Jun07: Added EM#next_tick. -01Jun07: Added EM::Connection#get_outbound_data_size -05Jun07: Removed the code which loads a pure-Ruby EM library in case the - compiled extension is unavailable. Suggested by Moshe Litvin. -06Jun07: Preliminary epoll implementation. -12Jun07: Added an evented popen implementation that, like Ruby's, is - full-duplex and makes the subprocess PID available to the caller. -06Jul07: Performance-tweaked the callback dispatcher in eventmachine.rb. -10Jul07: Released version 0.8.0. -12Jul07: Applied patches from Tim Pease to fix Solaris build problems. -15Jul07: Created a new provisional source branch, experiments/jruby-1. - This is a preliminary implementation of the EM reactor in Java, - suitable for use with JRuby. -17Jul07: Added EventMachine#stop_server, per request from Kirk Haines, - and associated unit tests. -22Jul07: Added EventMachine#stream_file_data. This is a very fast and scalable - way of sending data from static files over network connections. It - has separate implementations for small files and large file, and - has tunings to minimize memory consumption. -26Jul07: Added some patches by Kirk Haines to improve the behavior of - EM::Connection#send_file_data_to_connection. -26Jul07: Added a C++ module for directly integrating EM into C++ programs - with no Ruby dependencies. Needs example code. -29Jul07: Added EventMachine::Protocols::LineText2. -29Jul07: Added EventMachine::Protocols::Stomp. -30Jul07: Added sys/stat.h to project.h to fix compilation bug on Darwin. -13Aug07: Added EventMachine#reactor_running? -15Aug07: Added parameters for EventMachine::Connection:start_tls that can be - used to specify client-side private keys and certificates. -17Aug07: Added EventMachine#run_block, a sugaring for a common use case. -24Aug07: Added a preliminary keyboard handler. Needs docs and testing on - windows. -26Aug07: Created EventMachine::Spawnable, an implementation of Erlang-like - processes. -27Aug07: Silenced some -w warnings, requested by James Edward Gray II. -30Aug07: Added cookies to EM::HttpClient#request. -04Sep07: Added an initial implementation of an evented SMTP client. -04Sep07: Added an initial implementation of an evented SMTP server. -10Sep07: Changed EM#spawn to run spawned blocks in the context of the - SpawnedProcess object, not of whatever was the active object at the - time of the spawn. -14Sep07: Heartbeats weren't working with EPOLL. Noticed by Brian Candler. -15Sep07: Added some features, tests and documents to Deferrable. -16Sep07: Added [:content] parameter to EM::Protocols::SmtpClient#send. -16Sep07: Bumped version to 0.9.0 in anticipation of a release. -18Sep07: Released version 0.9.0. -19Sep07: Added #receive_reset to EM::Protocols::SmtpServer. -19Sep07: User overrides of EM::Protocols::SmtpServer#receive_recipient can now - return a Deferrable. Also fixed bug: SmtpClient now raises a protocol - error if none of its RCPT TO: commands are accepted by the server. -26Sep07: Fixed missing keyboard support for Windows. -03Oct07: Added a default handler for RuntimeErrors emitted from user-written - code. Suggested by Brian Candler. -19Oct07: Set the SO_BROADCAST option automatically on all UDP sockets. -10Nov07: Forced integer conversion of send_datagram's port parameter. -Suggested by Matthieu Riou. -12Nov07: Added saslauth.rb, a protocol module to replace the Cyrus SASL -daemons saslauthd and pwcheck. -15Nov07: Fixed bug reported by Mark Zvillius. We were failing to dispatch - zero-length datagrams under certain conditions. -19Nov07: Added EventMachine#set_max_timers. Requested by Matthieu Riou and - others. -19Nov07: Fixed bug with EM::Connection#start_tls. Was not working with server - connections. Reported by Michael S. Fischer. -26Nov07: Supported a hack for EventMachine#popen so it can return an exit - status from subprocesses. Requested by Michael S. Fischer. -30Nov07: Changed Pipe descriptors so that the child-side of the socketpair is - NOT set nonblocking. Suggested by Duane Johnson. -05Dec07: Re-enabled the pure-Ruby implementation. -06Dec07: Released Version 0.10.0. -13Dec07: Added EM::DeferrableChildProcess -24Dec07: Added a SASL client for simple password authentication. -27Dec07: Removed the hookable error handler. No one was using it and it significantly - degraded performance. -30Dec07: Implemented Kqueue support for OSX and BSD. -04Jan08: Fixed bug in epoll ("Bad file descriptor"), patch supplied by Chris - Heath. -04Jan08: Fixed bug reported by Michael S. Fischer. We were terminating - SSL connections that sent data before the handshake was complete. -08Jan08: Added an OpenBSD branch for extconf.rb, contributed by Guillaume - Sellier. -19Jan08: Added EM::Connection::get_sockname per request by Michael Fischer. -19Jan08: Supported IPv6 addresses. -30Apr08: Set the NODELAY option on sockets that we connect to other servers. - Omission noted by Roger Pack. -14May08: Generated a 0.12 release. -15May08: Supported EM#get_sockname for acceptors (TCP server sockets). - Requested by Roger Pack. -15May08; Accepted a patch from Dan Aquino that allows the interval of a - PeriodicTimer to be changed on the fly. -15Jun08: Supported nested calls to EM#run. Many people contributed ideas to - this, notably raggi and tmm1. -20Jul08: Accepted patch from tmm1 for EM#fork_reactor. -28Jul08: Added a Postgres3 implementation, written by FCianfrocca. -14Aug08: Added a patch by Mike Murphy to support basic auth in the http -client. -28Aug08: Added a patch by tmm1 to fix a longstanding problem with Java -data-sends. -13Sep08: Added LineText2#set_binary_mode, a back-compatibility alias. -13Sep08: Modified the load order of protocol libraries in eventmachine.rb - to permit a modification of HeaderAndContentProtocol. -13Sep08: Modified HeaderAndContent to use LineText2, which is less buggy - than LineAndTextProtocol. This change may be reversed if we can fix - the bugs in buftok. -13Sep08: Improved the password handling in the Postgres protocol handler. -15Sep08: Added attach/detach, contributed by Aman Gupta (tmm1) and Riham Aldakkak, - to support working with file descriptors not created in the reactor. -16Sep08: Added an optional version string to the HTTP client. This is a hack - that allows a client to specify a version 1.0 request, which - keeps the server from sending a chunked response. The right way to - solve this, of course, is to support chunked responses. -23Sep08: ChangeLog Summary for Merge of branches/raggi -Most notable work and patches by Aman Gupta, Roger Pack, and James Tucker. -Patches / Tickets also submitted by: Jeremy Evans, aanand, darix, mmmurf, -danielaquino, macournoyer. - - Moved docs into docs/ dir - - Major refactor of rakefile, added generic rakefile helpers in tasks - - Added example CPP build rakefile in tasks/cpp.rake - - Moved rake tests out to tasks/tests.rake - - Added svn ignores where appropriate - - Fixed jruby build on older java platforms - - Gem now builds from Rakefile rather than directly via extconf - - Gem unified for jruby, C++ and pure ruby. - - Correction for pure C++ build, removing ruby dependency - - Fix for CYGWIN builds on ipv6 - - Major refactor for extconf.rb - - Working mingw builds - - extconf optionally uses pkg_config over manual configuration - - extconf builds for 1.9 on any system that has 1.9 - - extconf no longer links pthread explicitly - - looks for kqueue on all *nix systems - - better error output on std::runtime_error, now says where it came from - - Fixed some tests on jruby - - Added test for general send_data flaw, required for a bugfix in jruby build - - Added timeout to epoll tests - - Added fixes for java reactor ruby api - - Small addition of some docs in httpclient.rb and httpcli2.rb - - Some refactor and fixes in smtpserver.rb - - Added parenthesis where possible to avoid excess ruby warnings - - Refactor of $eventmachine_library logic for accuracy and maintenance, jruby - - EM::start_server now supports unix sockets - - EM::connect now supports unix sockets - - EM::defer @threadqueue now handled more gracefully - - Added better messages on exceptions raised - - Fix edge case in timer fires - - Explicitly require buftok.rb - - Add protocols to autoload, rather than require them all immediately - - Fix a bug in pr_eventmachine for outbound_q - - Refactors to take some of the use of defer out of tests. - - Fixes in EM.defer under start/stop conditions. Reduced scope of threads. -23Sep08: Added patch from tmm1 to avoid popen errors on exit. -30Sep08: Added File.exists? checks in the args for start_tls, as suggested by - Brian Lopez (brianmario). -10Nov08: ruby 1.9 compatibility enhancements -28Nov08: Allow for older ruby builds where RARRAY_LEN is not defined -03Dec08: allow passing arguments to popen handlers -13Jan09: SSL support for httpclient2 (David Smalley) -22Jan09: Fixed errors on OSX with the kqueue reactor, fixed errors in the pure - ruby reactor. Added EM.current_time. Added EM.epoll? and EM.kqueue? -27Jan09: Reactor errors are now raised as ruby RuntimeErrors. -28Jan09: Documentation patch from alloy -29Jan09: (Late sign-off) Use a longer timeout for connect_server (Ilya - Grigorik) -07Feb09: Fix signal handling issues with threads+epoll -07Feb09: Use rb_thread_schedule in the epoll reactor -07Feb09: Use TRAP_BEG/END and rb_thread_schedule in kqueue reactor -08Feb09: Added fastfilereader from swiftiply -08Feb09: 1.9 fix for rb_trap_immediate -08Feb09: Enable rb_thread_blocking_region for 1.9.0 and 1.9.1 -10Feb09: Support win32 builds for fastfilereader -10Feb09: Added a new event to indicate completion of SSL handshake on TCP - connections -10Feb09: Working get_peer_cert method. Returns the certificate as a Ruby - String in PEM format. (Jake Douglas) -10Feb09: Added EM.get_max_timers -11Feb09: Fix compile options for sun compiler (Alasdairrr) -11Feb09: get_status returns a Process::Status object -12Feb09: Add EM::Protocols::Memcache with simple get/set functionality -19Feb09: Add catch-all EM.error_handler -20Feb09: Support miniunit (1.9) -20Feb09: Return success on content-length = 0 instead of start waiting forever - (Ugo Riboni) -25Feb09: Allow next_tick to be used to pre-schedule reactor operations before - EM.run -26Feb09: Added EM.get_connection_count -01Mar09: Switch back to extconf for compiling gem extensions -01Mar09: fixed a small bug with basic auth (mmmurf) diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/DEFERRABLES b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/DEFERRABLES deleted file mode 100644 index 6e8856c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/DEFERRABLES +++ /dev/null @@ -1,246 +0,0 @@ -EventMachine (EM) adds two different formalisms for lightweight concurrency -to the Ruby programmer's toolbox: spawned processes and deferrables. This -note will show you how to use deferrables. For more information, see the -separate document LIGHTWEIGHT_CONCURRENCY. - -=== What are Deferrables? - -EventMachine's Deferrable borrows heavily from the "deferred" object in -Python's "Twisted" event-handling framework. Here's a minimal example that -illustrates Deferrable: - - require 'eventmachine' - - class MyClass - include EM::Deferrable - - def print_value x - puts "MyClass instance received #{x}" - end - end - - EM.run { - df = MyClass.new - df.callback {|x| - df.print_value(x) - EM.stop - } - - EM::Timer.new(2) { - df.set_deferred_status :succeeded, 100 - } - } - - -This program will spin for two seconds, print out the string "MyClass -instance received 100" and then exit. The Deferrable pattern relies on -an unusual metaphor that may be unfamiliar to you, unless you've used -Python's Twisted. You may need to read the following material through -more than once before you get the idea. - -EventMachine::Deferrable is simply a Ruby Module that you can include -in your own classes. (There also is a class named -EventMachine::DefaultDeferrable for when you want to create one without -including it in code of your own.) - -An object that includes EventMachine::Deferrable is like any other Ruby -object: it can be created whenever you want, returned from your functions, -or passed as an argument to other functions. - -The Deferrable pattern allows you to specify any number of Ruby code -blocks (callbacks or errbacks) that will be executed at some future time -when the status of the Deferrable object changes. - -How might that be useful? Well, imagine that you're implementing an HTTP -server, but you need to make a call to some other server in order to fulfill -a client request. - -When you receive a request from one of your clients, you can create and -return a Deferrable object. Some other section of your program can add a -callback to the Deferrable that will cause the client's request to be -fulfilled. Simultaneously, you initiate an event-driven or threaded client -request to some different server. And then your EM program will continue to -process other events and service other client requests. - -When your client request to the other server completes some time later, you -will call the #set_deferred_status method on the Deferrable object, passing -either a success or failure status, and an arbitrary number of parameters -(which might include the data you received from the other server). - -At that point, the status of the Deferrable object becomes known, and its -callback or errback methods are immediately executed. Callbacks and errbacks -are code blocks that are attached to Deferrable objects at any time through -the methods #callback and #errback. - -The deep beauty of this pattern is that it decouples the disposition of one -operation (such as a client request to an outboard server) from the -subsequent operations that depend on that disposition (which may include -responding to a different client or any other operation). - -The code which invokes the deferred operation (that will eventually result -in a success or failure status together with associated data) is completely -separate from the code which depends on that status and data. This achieves -one of the primary goals for which threading is typically used in -sophisticated applications, with none of the nondeterminacy or debugging -difficulties of threads. - -As soon as the deferred status of a Deferrable becomes known by way of a call -to #set_deferred_status, the Deferrable will IMMEDIATELY execute all of its -callbacks or errbacks in the order in which they were added to the Deferrable. - -Callbacks and errbacks can be added to a Deferrable object at any time, not -just when the object is created. They can even be added after the status of -the object has been determined! (In this case, they will be executed -immediately when they are added.) - -A call to Deferrable#set_deferred_status takes :succeeded or :failed as its -first argument. (This determines whether the object will call its callbacks -or its errbacks.) #set_deferred_status also takes zero or more additional -parameters, that will in turn be passed as parameters to the callbacks or -errbacks. - -In general, you can only call #set_deferred_status ONCE on a Deferrable -object. A call to #set_deferred_status will not return until all of the -associated callbacks or errbacks have been called. If you add callbacks or -errbacks AFTER making a call to #set_deferred_status, those additional -callbacks or errbacks will execute IMMEDIATELY. Any given callback or -errback will be executed AT MOST once. - -It's possible to call #set_deferred_status AGAIN, during the execution a -callback or errback. This makes it possible to change the parameters which -will be sent to the callbacks or errbacks farther down the chain, enabling -some extremely elegant use-cases. You can transform the data returned from -a deferred operation in arbitrary ways as needed by subsequent users, without -changing any of the code that generated the original data. - -A call to #set_deferred_status will not return until all of the associated -callbacks or errbacks have been called. If you add callbacks or errbacks -AFTER making a call to #set_deferred_status, those additional callbacks or -errbacks will execute IMMEDIATELY. - -Let's look at some more sample code. It turns out that many of the internal -protocol implementations in the EventMachine package rely on Deferrable. One -of these is EM::Protocols::HttpClient. - -To make an evented HTTP request, use the module function -EM::Protocols::HttpClient#request, which returns a Deferrable object. -Here's how: - - require 'eventmachine' - - EM.run { - df = EM::Protocols::HttpClient.request( :host=>"www.example.com", - :request=>"/index.html" ) - - df.callback {|response| - puts "Succeeded: #{response[:content]}" - EM.stop - } - - df.errback {|response| - puts "ERROR: #{response[:status]}" - EM.stop - } - } - -(See the documentation of EventMachine::Protocols::HttpClient for information -on the object returned by #request.) - -In this code, we make a call to HttpClient#request, which immediately returns -a Deferrable object. In the background, an HTTP client request is being made -to www.example.com, although your code will continue to run concurrently. - -At some future point, the HTTP client request will complete, and the code in -EM::Protocols::HttpClient will process either a valid HTTP response (including -returned content), or an error. - -At that point, EM::Protocols::HttpClient will call -EM::Deferrable#set_deferred_status on the Deferrable object that was returned -to your program, as the return value from EM::Protocols::HttpClient.request. -You don't have to do anything to make this happen. All you have to do is tell -the Deferrable what to do in case of either success, failure, or both. - -In our code sample, we set one callback and one errback. The former will be -called if the HTTP call succeeds, and the latter if it fails. (For -simplicity, we have both of them calling EM#stop to end the program, although -real programs would be very unlikely to do this.) - -Setting callbacks and errbacks is optional. They are handlers to defined -events in the lifecycle of the Deferrable event. It's not an error if you -fail to set either a callback, an errback, or both. But of course your -program will then fail to receive those notifications. - -If through some bug it turns out that #set_deferred_status is never called -on a Deferrable object, then that object's callbacks or errbacks will NEVER -be called. It's also possible to set a timeout on a Deferrable. If the -timeout elapses before any other call to #set_deferred_status, the Deferrable -object will behave as is you had called set_deferred_status(:failed) on it. - - -Now let's modify the example to illustrate some additional points: - - require 'eventmachine' - - EM.run { - df = EM::Protocols::HttpClient.request( :host=>"www.example.com", - :request=>"/index.html" ) - - df.callback {|response| - df.set_deferred_status :succeeded, response[:content] - } - - df.callback {|string| - puts "Succeeded: #{string}" - EM.stop - } - - df.errback {|response| - puts "ERROR: #{response[:status]}" - EM.stop - } - } - - -Just for the sake of illustration, we've now set two callbacks instead of -one. If the deferrable operation (the HTTP client-request) succeeds, then -both of the callbacks will be executed in order. - -But notice that we've also made our own call to #set_deferred_status in the -first callback. This isn't required, because the HttpClient implementation -already made a call to #set_deferred_status. (Otherwise, of course, the -callback would not be executing.) - -But we used #set_deferred_status in the first callback in order to change the -parameters that will be sent to subsequent callbacks in the chain. In this -way, you can construct powerful sequences of layered functionality. If you -want, you can even change the status of the Deferrable from :succeeded to -:failed, which would abort the chain of callback calls, and invoke the chain -of errbacks instead. - -Now of course it's somewhat trivial to define two callbacks in the same -method, even with the parameter-changing effect we just described. It would -be much more interesting to pass the Deferrable to some other function (for -example, a function defined in another module or a different gem), that would -in turn add callbacks and/or errbacks of its own. That would illustrate the -true power of the Deferrable pattern: to isolate the HTTP client-request -from other functions that use the data that it returns without caring where -those data came from. - -Remember that you can add a callback or an errback to a Deferrable at any -point in time, regardless of whether the status of the deferred operation is -known (more precisely, regardless of when #set_deferred_status is called on -the object). Even hours or days later. - -When you add a callback or errback to a Deferrable object on which -#set_deferred_status has not yet been called, the callback/errback is queued -up for future execution, inside the Deferrable object. When you add a -callback or errback to a Deferrable on which #set_deferred_status has -already been called, the callback/errback will be executed immediately. -Your code doesn't have to worry about the ordering, and there are no timing -issues, as there would be with a threaded approach. - -For more information on Deferrables and their typical usage patterns, look -in the EM unit tests. There are also quite a few sugarings (including -EM::Deferrable#future) that make typical Deferrable usages syntactically -easier to work with. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/EPOLL b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/EPOLL deleted file mode 100644 index 13cea8f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/EPOLL +++ /dev/null @@ -1,141 +0,0 @@ -EventMachine now supports epoll, bringing large increases in performance and scalability to Ruby programs. - -Epoll(7) is a alternative mechanism for multiplexed I/O that is available in Linux 2.6 kernels. -It features significantly greater performance than the standard select(2) mechanism, when used in -applications that require very large numbers of open I/O descriptors. - -EventMachine has always used select(2) because its behavior is well standardized and broadly supported. -But select becomes unreasonably slow when a program has a -very large number of file descriptors or sockets. Ruby's version of select hardcodes a limit -of 1024 descriptors per process, but heavily loaded processes will start to show performance -degradation even after only a few hundred descriptors are in use. - -Epoll is an extended version of the poll(2) call, and it solves the problems with select. Programs -based on epoll can easily scale past Ruby's 1024-descriptor limit, potentially to tens of thousands -of connectors, with no significant impact on performance. - -(Another alternative which is very similar to epoll in principle is kqueue, supplied on BSD and its -variants.) - - - -This note shows you how to use epoll in your programs. - -=== Compiling EventMachine to use epoll. - -You don't have to do anything to get epoll support in EventMachine. -When you compile EventMachine on a platform that supports epoll, EM will -automatically generate a Makefile that includes epoll. (At this writing, this will only work -on Linux 2.6 kernels.) If you compile EM on a platform without epoll, then epoll support will -be omitted from the Makefile, and EM will work just as it always has. - -=== Using epoll in your programs. - -First, you need to tell EventMachine to use epoll instead of select (but see below, as this requirement -will be removed in a future EventMachine version). Second, you need to prepare your program to use -more than 1024 descriptors, an operation that generally requires superuser privileges. Third, you will probably -want your process to drop the superuser privileges after you increase your process's descriptor limit. - -=== Using EventMachine#epoll - -Call the method EventMachine#epoll anytime before you call EventMachine#run, and your program will -automatically use epoll, if available. It's safe to call EventMachine#epoll on any platform because -it compiles to a no-op on platforms that don't support epoll. - - require 'rubygems' - require 'eventmachine' - - EM.epoll - EM.run { - ... - } - - -EventMachine#epoll was included in this initial release only to avoid changing the behavior of existing -programs. However, it's expected that a future release of EM will convert EventMachine#epoll to a no-op, -and run epoll by default on platforms that support it. - -=== Using EventMachine#set_descriptor_table_size - -In Linux (as in every Unix-like platform), every process has a internal table that determines the maximum -number of file and socket descriptors you may have open at any given time. The size of this table is -generally fixed at 1024, although it may be increased within certain system-defined hard and soft limits. - -If you want your EventMachine program to support more than 1024 total descriptors, you must use -EventMachine#set_descriptor_table_size, as follows: - - require 'rubygems' - require 'eventmachine' - - new_size = EM.set_descriptor_table_size( 60000 ) - $>.puts "New descriptor-table size is #{new_size}" - - EM.run { - ... - } - -If successful, this example will increase the maximum number of descriptors that epoll can use to 60,000. -Call EventMachine#set_descriptor_table_size without an argument at any time to find out the current -size of the descriptor table. - -Using EventMachine#set_descriptor_table_size ONLY affects the number of descriptors that can be used -by epoll. It has no useful effect on platforms that don't support epoll, and it does NOT increase the -number of descriptors that Ruby's own I/O functions can use. - -#set_descriptor_table_size can fail if your process is not running as superuser, or if you try to set a -table size that exceeds the hard limits imposed by your system. In the latter case, try a smaller number. - - -=== Using EventMachine#set_effective_user - -In general, you must run your program with elevated or superuser privileges if you want to increase -your descriptor-table size beyond 1024 descriptors. This is easy enough to verify. Try running the -sample program given above, that increases the descriptor limit to 60,000. You will probably find that -the table size will not be increased if you don't run your program as root or with elevated privileges. - -But of course network servers, especially long-running ones, should not run with elevated privileges. -You will want to drop superuser privileges as soon as possible after initialization. To do this, -use EventMachine#set_effective_user: - - require 'rubygems' - require 'eventmachine' - - # (Here, program is running as superuser) - - EM.set_descriptor_table_size( 60000 ) - EM.set_effective_user( "nobody" ) - # (Here, program is running as nobody) - - EM.run { - ... - } - -Of course, you will need to replace "nobody" in the example with the name of an unprivileged user -that is valid on your system. What if you want to drop privileges after opening a server socket -on a privileged (low-numbered) port? Easy, just call #set_effective_user after opening your sockets: - - require 'rubygems' - require 'eventmachine' - - # (Here, program is running as superuser) - - EM.set_descriptor_table_size( 60000 ) - - EM.run { - EM.start_server( "0.0.0.0", 80, MyHttpServer ) - EM.start_server( "0.0.0.0", 443, MyEncryptedHttpServer ) - - EM.set_effective_user( "nobody" ) - # (Here, program is running as nobody) - - ... - } - - -Because EventMachine#set_effective_user is used to enforce security -requirements, it has no nonfatal errors. If you try to set a nonexistent or invalid effective user, -#set_effective_user will abort your program, rather than continue to run with elevated privileges. - -EventMachine#set_effective_user is a silent no-op on platforms that don't support it, such as Windows. - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/INSTALL b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/INSTALL deleted file mode 100644 index dee2e42..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/INSTALL +++ /dev/null @@ -1,13 +0,0 @@ -If you have obtained an EventMachine source-tarball (.tar.gz): -unzip and untar the tarball, and enter the directory that is -created. In that directory, say: -ruby setup.rb -(You may need to be root to execute this command.) - -To create documentation for EventMachine, simply type: -rake rdoc -in the distro directory. Rdocs will be created in subdirectory rdoc. - -If you have obtained a gem version of EventMachine, install it in the -usual way (gem install eventmachine). You may need superuser privileges -to execute this command. diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/KEYBOARD b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/KEYBOARD deleted file mode 100644 index 6c699e4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/KEYBOARD +++ /dev/null @@ -1,42 +0,0 @@ -EventMachine (EM) can respond to keyboard events. This gives your event-driven -programs the ability to respond to input from local users. - -Programming EM to handle keyboard input in Ruby is simplicity itself. Just use -EventMachine#open_keyboard, and supply the name of a Ruby module or class that -will receive the input: - - require 'rubygems' - require 'eventmachine' - - module MyKeyboardHandler - def receive_data keystrokes - puts "I received the following data from the keyboard: #{keystrokes}" - end - end - - EM.run { - EM.open_keyboard(MyKeyboardHandler) - } - -If you want EM to send line-buffered keyboard input to your program, just -include the LineText2 protocol module in your handler class or module: - - require 'rubygems' - require 'eventmachine' - - module MyKeyboardHandler - include EM::Protocols::LineText2 - def receive_line data - puts "I received the following line from the keyboard: #{data}" - end - end - - EM.run { - EM.open_keyboard(MyKeyboardHandler) - } - -As we said, simplicity itself. You can call EventMachine#open_keyboard at any -time while the EM reactor loop is running. In other words, the method -invocation may appear anywhere in an EventMachine#run block, or in any code -invoked in the #run block. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LEGAL b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LEGAL deleted file mode 100644 index ee01825..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LEGAL +++ /dev/null @@ -1,25 +0,0 @@ -LEGAL NOTICE INFORMATION ------------------------- - -EventMachine is Copyright (C) 2006-07 by Francis Cianfrocca. - -EventMachine is copyrighted software owned by Francis Cianfrocca -(blackhedd ... gmail.com). You may redistribute and/or modify this -software as long as you comply with either the terms of the GPL -(see the file GPL), or Ruby's license (see the file COPYING). - -Your use of all the files in this distribution is controlled by these -license terms, except for those files specifically mentioned below: - - - -setup.rb - This file is Copyright (C) 2000-2005 by Minero Aoki - You can distribute/modify this file under the terms of - the GNU LGPL, Lesser General Public License version 2.1. - - -lib/em/buftok.rb - This file is Copyright (C) 2007 by Tony Arcieri. This file is - covered by the terms of Ruby's License (see the file COPYING). - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LIGHTWEIGHT_CONCURRENCY b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LIGHTWEIGHT_CONCURRENCY deleted file mode 100644 index 3c2cfa0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/LIGHTWEIGHT_CONCURRENCY +++ /dev/null @@ -1,130 +0,0 @@ -EventMachine (EM) adds two different formalisms for lightweight concurrency to -the Ruby programmer's toolbox: spawned processes and deferrables. This note -will show you how to use them. - - -=== What is Lightweight Concurrency? - -We use the term "Lightweight Concurrency" (LC) to refer to concurrency -mechanisms that are lighter than Ruby threads. By "lighter," we mean: less -resource-intensive in one or more dimensions, usually including memory and -CPU usage. In general, you turn to LC in the hope of improving the -performance and scalability of your programs. - -In addition to the two EventMachine mechanisms we will discuss here, Ruby -has at least one other LC construct: Fibers, which are currently under -development in Ruby 1.9. - -The technical feature that makes all of these LC mechanisms different from -standard Ruby threads is that they are not scheduled automatically. - -When you create and run Ruby threads, you can assume (within certain -constraints) that your threads will all be scheduled fairly by Ruby's runtime. -Ruby itself is responsible for giving each of your threads its own share of -the total runtime. - -But with LC, your program is responsible for causing different execution -paths to run. In effect, your program has to act as a "thread scheduler." -Scheduled entities in LC run to completion and are never preempted. The -runtime system has far less work to do since it has no need to interrupt -threads or to schedule them fairly. This is what makes LC lighter and faster. - -You'll learn exactly how LC scheduling works in practice as we work through -specific examples. - - -=== EventMachine Lightweight Concurrency - -Recall that EM provides a reactor loop that must be running in order for -your programs to perform event-driven logic. An EM program typically has a -structure like this: - - require 'eventmachine' - - # your initializations - - EM.run { - # perform event-driven I/O here, including network clients, - # servers, timers, and thread-pool operations. - } - - # your cleanup - # end of the program - - -EventMachine#run executes the reactor loop, which causes your code to be -called as events of interest to your program occur. The block you pass to -EventMachine#run is executed right after the reactor loop starts, and is -the right place to start socket acceptors, etc. - -Because the reactor loop runs constantly in an EM program (until it is -stopped by a call to EventMachine#stop), it has the ability to schedule -blocks of code for asynchronous execution. Unlike a pre-emptive thread -scheduler, it's NOT able to interrupt code blocks while they execute. But -the scheduling capability it does have is enough to enable lightweight -concurrency. - - -For information on Spawned Processes, see the separate document -SPAWNED_PROCESSES. - -For information on Deferrables, see the separate document DEFERRABLES. - - -=== [SIDEBAR]: I Heard That EventMachine Doesn't Work With Ruby Threads. - -This is incorrect. EM is fully interoperable with all versions of Ruby -threads, and has been since its earliest releases. - -It's very true that EM encourages an "evented" (non-threaded) programming -style. The specific benefits of event-driven programming are far better -performance and scalability for well-written programs, and far easier -debugging. - -The benefit of using threads for similar applications is a possibly more -intuitive programming model, as well as the fact that threads are already -familiar to most programmers. Also, bugs in threaded programs often fail -to show up until programs go into production. These factors create the -illusion that threaded programs are easier to write. - -However, some operations that occur frequently in professional-caliber -applications simply can't be done without threads. (The classic example -is making calls to database client-libraries that block on network I/O -until they complete.) - -EventMachine not only allows the use of Ruby threads in these cases, but -it even provides a built-in thread-pool object to make them easier to -work with. - -You may have heard a persistent criticism that evented I/O is fundamentally -incompatible with Ruby threads. It is true that some well-publicized attempts -to incorporate event-handling libraries into Ruby were not successful. But -EventMachine was designed from the ground up with Ruby compatibility in mind, -so EM never suffered from the problems that defeated the earlier attempts. - - -=== [SIDEBAR]: I Heard That EventMachine Doesn't Work Very Well On Windows. - -This too is incorrect. EventMachine is an extension written in C++ and Java, -and therefore it requires compilation. Many Windows computers (and some Unix -computers, especially in production environments) don't have a build stack. -Attempting to install EventMachine on a machine without a compiler usually -produces a confusing error. - -In addition, Ruby has a much-debated issue with Windows compiler versions. -Ruby on Windows works best with Visual Studio 6, a compiler version that is -long out-of-print, no longer supported by Microsoft, and difficult to obtain. -(This problem is not specific to EventMachine.) - -Shortly after EventMachine was first released, the compiler issues led to -criticism that EM was incompatible with Windows. Since that time, every -EventMachine release has been supplied in a precompiled binary form for -Windows users, that does not require you to compile the code yourself. EM -binary Gems for Windows are compiled using Visual Studio 6. - -EventMachine does supply some advanced features (such as Linux EPOLL support, -reduced-privilege operation, UNIX-domain sockets, etc.) that have no -meaningful implementation on Windows. Apart from these special cases, all EM -functionality (including lightweight concurrency) works perfectly well on -Windows. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/PURE_RUBY b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/PURE_RUBY deleted file mode 100644 index 157d59e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/PURE_RUBY +++ /dev/null @@ -1,75 +0,0 @@ -EventMachine is supplied in three alternative versions. - -1) A version that includes a Ruby extension written in C++. This version requires compilation; -2) A version for JRuby that contains a precompiled JAR file written in Java; -3) A pure Ruby version that has no external dependencies and can run in any Ruby environment. - -The Java version of EventMachine is packaged in a distinct manner and must be installed using a -special procedure. This version is described fully in a different document, and not considered -further here. - -The C++ and pure-Ruby versions, however, are shipped in the same distribution. You use the same -files (either tarball or Ruby gem) to install both of these versions. - -If you intend to use the C++ version, you must successfully compile EventMachine after you install it. -(The gem installation attempts to perform this step automatically.) - -If you choose not to compile the EventMachine C++ extension, or if your compilation fails for any -reason, you still have a fully-functional installation of the pure-Ruby version of EM. - -However, for technical reasons, a default EM installation (whether or not the compilation succeeds) -will always assume that the compiled ("extension") implementation should be used. - -If you want your EM program to use the pure Ruby version, you must specifically request it. There -are two ways to do this: by setting either a Ruby global variable, or an environment string. - -The following code will invoke the pure-Ruby implementation of EM: - - $eventmachine_library = :pure_ruby - require 'eventmachine' - - EM.library_type #=> "pure_ruby" - -Notice that this requires a code change and is not the preferred way to select pure Ruby, unless -for some reason you are absolutely sure you will never want the compiled implementation. - -Setting the following environment string has the same effect: - - export EVENTMACHINE_LIBRARY="pure_ruby" - -This technique gives you the flexibility to select either version at runtime with no code changes. - -Support - -The EventMachine development team has committed to support precisely the same APIs for all the -various implementations of EM. - -This means that you can expect any EM program to behave identically, whether you use pure Ruby, -the compiled C++ extension, or JRuby. Deviations from this behavior are to be considered bugs -and should be reported as such. - -There is a small number of exceptions to this rule, which arise from underlying platform -distinctions. Notably, EM#epoll is a silent no-op in the pure Ruby implementation. - - -When Should You Use the Pure-Ruby Implementation of EM? - - -Use the pure Ruby implementation of EM when you must support a platform for which no C++ compiler -is available, or on which the standard EM C++ code can't be compiled. - -Keep in mind that you don't need a C++ compiler in order to deploy EM applications that rely on -the compiled version, so long as appropriate C++ runtime libraries are available on the target platform. - -In extreme cases, you may find that you can develop software with the compiled EM version, but are -not allowed to install required runtime libraries on the deployment system(s). This would be another -case in which the pure Ruby implementation can be useful. - -In general you should avoid the pure Ruby version of EM when performance and scalability are important. -EM in pure Ruby will necessarily run slower than the compiled version. Depending on your application -this may or may not be a key issue. - -Also, since EPOLL is not supported in pure Ruby, your applications will be affected by Ruby's built-in -limit of 1024 file and socket descriptors that may be open in a single process. For maximum scalability -and performance, always use EPOLL if possible. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/RELEASE_NOTES b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/RELEASE_NOTES deleted file mode 100644 index 6110820..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/RELEASE_NOTES +++ /dev/null @@ -1,94 +0,0 @@ -RUBY/EventMachine RELEASE NOTES - --------------------------------------------------- -Version: 0.9.0, released xxXXX07 -Added Erlang-like distributed-computing features - --------------------------------------------------- -Version: 0.8.0, released 23Jun07 -Added an epoll implementation for Linux 2.6 kernels. -Added evented #popen. - --------------------------------------------------- -Version: 0.7.3, released 22May07 -Added a large variety of small features. See the ChangeLog. - --------------------------------------------------- -Version: 0.7.1, released xxNov06 -Added protocol handlers for line-oriented protocols. -Various bug fixes. - --------------------------------------------------- -Version: 0.7.0, released 20Nov06 -Added a fix in em.cpp/ConnectToServer to fix a fatal exception that -occurred in FreeBSD when connecting successfully to a remote server. - --------------------------------------------------- -Version: 0.6.0, released xxJul06 -Added deferred operations, suggested by Don Stocks, amillionhitpoints@yahoo.com. - --------------------------------------------------- -Version: 0.5.4, released xxJun06 -Added get_peername support for streams and datagrams. - --------------------------------------------------- -Version: 0.5.3, released 17May06 -Fixed bugs in extconf.rb, thanks to Daniel Harple, dharple@generalconsumption.org. -Added proper setup.rb and rake tasks, thanks to Austin Ziegler. -Fixed a handful of reported problems with builds on various platforms. - --------------------------------------------------- -Version: 0.5.2, released 05May06 -Made several nonvisible improvements to the Windows -implementation. -Added an exception-handling patch contributed by Jeff Rose, jeff@rosejn.net. -Added a dir-config patch contributed anonymously. -Supported builds on Solaris. - --------------------------------------------------- -Version: 0.5.1, released 05May06 -Made it possible to pass a Class rather than a Module -to a protocol handler. -Added Windows port. - --------------------------------------------------- -Version: 0.5.0, released 30Apr06 -Added a preliminary SSL/TLS extension. This will probably -change over the next few releases. - --------------------------------------------------- -Version: 0.4.5, released 29Apr06 -Changed ext files so the ruby.h is installed after unistd.h -otherwise it doesn't compile on gcc 4.1 - --------------------------------------------------- -Version: 0.4.2, released 19Apr06 -Changed the Ruby-glue so the extension will play nicer -in the sandbox with Ruby threads. -Added an EventMachine::run_without_threads API to -switch off the thread-awareness for better performance -in programs that do not spin any Ruby threads. - --------------------------------------------------- -Version: 0.4.1, released 15Apr06 -Reworked the shared-object interface to make it easier to -use EventMachine from languages other than Ruby. - --------------------------------------------------- -Version: 0.3.2, released 12Apr06 -Added support for a user-supplied block in EventMachine#connect. - --------------------------------------------------- -Version: 0.3.1, released 11Apr06 -Fixed bug that prevented EventMachine from being run multiple -times in a single process. - --------------------------------------------------- -Version: 0.3.0, released 10Apr06 -Added method EventHandler::Connection::post_init - --------------------------------------------------- -Version: 0.2.0, released 10Apr06 -Added method EventHandler::stop - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SMTP b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SMTP deleted file mode 100644 index 92bf311..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SMTP +++ /dev/null @@ -1,4 +0,0 @@ -This note details the usage of EventMachine's built-in support for SMTP. EM -supports both client and server connections, which will be described in -separate sections. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SPAWNED_PROCESSES b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SPAWNED_PROCESSES deleted file mode 100644 index ee68e3e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/SPAWNED_PROCESSES +++ /dev/null @@ -1,148 +0,0 @@ -EventMachine (EM) adds two different formalisms for lightweight concurrency -to the Ruby programmer's toolbox: spawned processes and deferrables. This -note will show you how to use spawned processes. For more information, see -the separate document LIGHTWEIGHT_CONCURRENCY. - - -=== What are Spawned Processes? - -Spawned Processes in EventMachine are inspired directly by the "processes" -found in the Erlang programming language. EM deliberately borrows much (but -not all) of Erlang's terminology. However, EM's spawned processes differ from -Erlang's in ways that reflect not only Ruby style, but also the fact that -Ruby is not a functional language like Erlang. - -Let's proceed with a complete, working code sample that we will analyze line -by line. Here's an EM implementation of the "ping-pong" program that also -appears in the Erlang tutorial: - - - require 'eventmachine' - - EM.run { - pong = EM.spawn {|x, ping| - puts "Pong received #{x}" - ping.notify( x-1 ) - } - - ping = EM.spawn {|x| - if x > 0 - puts "Pinging #{x}" - pong.notify x, self - else - EM.stop - end - } - - ping.notify 3 - } - -If you run this program, you'll see the following output: - - Pinging 3 - Pong received 3 - Pinging 2 - Pong received 2 - Pinging 1 - Pong received 1 - -Let's take it step by step. - -EventMachine#spawn works very much like the built-in function spawn in -Erlang. It returns a reference to a Ruby object of class -EventMachine::SpawnedProcess, which is actually a schedulable entity. In -Erlang, the value returned from spawn is called a "process identifier" or -"pid." But we'll refer to the Ruby object returned from EM#spawn simply as a -"spawned process." - -You pass a Ruby block with zero or more parameters to EventMachine#spawn. -Like all Ruby blocks, this one is a closure, so it can refer to variables -defined in the local context when you call EM#spawn. - -However, the code block passed to EM#spawn does NOT execute immediately by -default. Rather, it will execute only when the Spawned Object is "notified." -In Erlang, this process is called "message passing," and is done with the -operator !, but in Ruby it's done simply by calling the #notify method of a -spawned-process object. The parameters you pass to #notify must match those -defined in the block that was originally passed to EM#spawn. - -When you call the #notify method of a spawned-process object, EM's reactor -core will execute the code block originally passed to EM#spawn, at some point -in the future. (#notify itself merely adds a notification to the object's -message queue and ALWAYS returns immediately.) - -When a SpawnedProcess object executes a notification, it does so in the -context of the SpawnedProcess object itself. The notified code block can see -local context from the point at which EM#spawn was called. However, the value -of "self" inside the notified code block is a reference to the SpawnedProcesss -object itself. - -An EM spawned process is nothing more than a Ruby object with a message -queue attached to it. You can have any number of spawned processes in your -program without compromising scalability. You can notify a spawned process -any number of times, and each notification will cause a "message" to be -placed in the queue of the spawned process. Spawned processes with non-empty -message queues are scheduled for execution automatically by the EM reactor. -Spawned processes with no visible references are garbage-collected like any -other Ruby object. - -Back to our code sample: - - pong = EM.spawn {|x, ping| - puts "Pong received #{x}" - ping.notify( x-1 ) - } - -This simply creates a spawned process and assigns it to the local variable -pong. You can see that the spawned code block takes a numeric parameter and a -reference to another spawned process. When pong is notified, it expects to -receive arguments corresponding to these two parameters. It simply prints out -the number it receives as the first argument. Then it notifies the spawned -process referenced by the second argument, passing it the first argument -minus 1. - -And then the block ends, which is crucial because otherwise nothing else -can run. (Remember that in LC, scheduled entities run to completion and are -never preempted.) - -On to the next bit of the code sample: - - ping = EM.spawn {|x| - if x > 0 - puts "Pinging #{x}" - pong.notify x, self - else - EM.stop - end - } - -Here, we're spawning a process that takes a single (numeric) parameter. If -the parameter is greater than zero, the block writes it to the console. It -then notifies the spawned process referenced by the pong local variable, -passing as arguments its number argument, and a reference to itself. The -latter reference, as you saw above, is used by pong to send a return -notification. - -If the ping process receives a zero value, it will stop the reactor loop and -end the program. - -Now we've created a pair of spawned processes, but nothing else has happened. -If we stop now, the program will spin in the EM reactor loop, doing nothing -at all. Our spawned processes will never be scheduled for execution. - -But look at the next line in the code sample: - - ping.notify 3 - -This line gets the ping-pong ball rolling. We call ping's #notify method, -passing the argument 3. This causes a message to be sent to the ping spawned -process. The message contains the single argument, and it causes the EM -reactor to schedule the ping process. And this in turn results in the -execution of the Ruby code block passed to EM#spawn when ping was created. -Everything else proceeds as a result of the messages that are subsequently -passed to each other by the spawned processes. - -[TODO, present the outbound network i/o use case, and clarify that spawned -processes are interleaved with normal i/o operations and don't interfere -with them at all. Also, blame Erlang for the confusing term "process"] - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/TODO b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/TODO deleted file mode 100644 index 686a0d5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/docs/old/TODO +++ /dev/null @@ -1,8 +0,0 @@ -TODO List: - -12Aug06: Noticed by Don Stocks. A TCP connect-request that results -in a failed DNS resolution fires a fatal error back to user code. -Uuuuuugly. We should probably cause an unbind event to get fired -instead, and add some parameterization so the caller can detect -the nature of the failure. - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/01_eventmachine_echo_server.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/01_eventmachine_echo_server.rb deleted file mode 100644 index 51c5c7d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/01_eventmachine_echo_server.rb +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class EchoServer < EM::Connection - def receive_data(data) - send_data(data) - end -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, EchoServer) -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb deleted file mode 100644 index 4cfff19..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class EchoServer < EM::Connection - def receive_data(data) - if data.strip =~ /exit$/i - EventMachine.stop - else - send_data(data) - end - end -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, EchoServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/03_simple_chat_server.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/03_simple_chat_server.rb deleted file mode 100644 index 3352551..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/03_simple_chat_server.rb +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - @@connected_clients = Array.new - DM_REGEXP = /^@([a-zA-Z0-9]+)\s*:?\s*(.+)/.freeze - - attr_reader :username - - - # - # EventMachine handlers - # - - def post_init - @username = nil - - puts "A client has connected..." - ask_username - end - - def unbind - @@connected_clients.delete(self) - puts "[info] #{@username} has left" if entered_username? - end - - def receive_data(data) - if entered_username? - handle_chat_message(data.strip) - else - handle_username(data.strip) - end - end - - - # - # Username handling - # - - def entered_username? - !@username.nil? && !@username.empty? - end # entered_username? - - def handle_username(input) - if input.empty? - send_line("Blank usernames are not allowed. Try again.") - ask_username - else - @username = input - @@connected_clients.push(self) - self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") } - puts "#{@username} has joined" - - self.send_line("[info] Ohai, #{@username}") - end - end # handle_username(input) - - def ask_username - self.send_line("[info] Enter your username:") - end # ask_username - - - # - # Message handling - # - - def handle_chat_message(msg) - if command?(msg) - self.handle_command(msg) - else - if direct_message?(msg) - self.handle_direct_message(msg) - else - self.announce(msg, "#{@username}:") - end - end - end # handle_chat_message(msg) - - def direct_message?(input) - input =~ DM_REGEXP - end # direct_message?(input) - - def handle_direct_message(input) - username, message = parse_direct_message(input) - - if connection = @@connected_clients.find { |c| c.username == username } - puts "[dm] @#{@username} => @#{username}" - connection.send_line("[dm] @#{@username}: #{message}") - else - send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}" - end - end # handle_direct_message(input) - - def parse_direct_message(input) - return [$1, $2] if input =~ DM_REGEXP - end # parse_direct_message(input) - - - # - # Commands handling - # - - def command?(input) - input =~ /(exit|status)$/i - end # command?(input) - - def handle_command(cmd) - case cmd - when /exit$/i then self.close_connection - when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room") - end - end # handle_command(cmd) - - - # - # Helpers - # - - def announce(msg = nil, prefix = "[chat server]") - @@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty? - end # announce(msg) - - def number_of_connected_clients - @@connected_clients.size - end # number_of_connected_clients - - def other_peers - @@connected_clients.reject { |c| self == c } - end # other_peers - - def send_line(line) - self.send_data("#{line}\n") - end # send_line(line) - - def usernames - @@connected_clients.map { |c| c.username } - end # usernames -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/04_simple_chat_server_step_one.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/04_simple_chat_server_step_one.rb deleted file mode 100644 index bb283a7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/04_simple_chat_server_step_one.rb +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - # - # EventMachine handlers - # - - def post_init - puts "A client has connected..." - end - - def unbind - puts "A client has left..." - end -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/05_simple_chat_server_step_two.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/05_simple_chat_server_step_two.rb deleted file mode 100644 index 1361c5d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/05_simple_chat_server_step_two.rb +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - @@connected_clients = Array.new - - - # - # EventMachine handlers - # - - def post_init - @@connected_clients.push(self) - puts "A client has connected..." - end - - def unbind - @@connected_clients.delete(self) - puts "A client has left..." - end - - - - - # - # Helpers - # - - def other_peers - @@connected_clients.reject { |c| self == c } - end # other_peers -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/06_simple_chat_server_step_three.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/06_simple_chat_server_step_three.rb deleted file mode 100644 index d9b85e2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/06_simple_chat_server_step_three.rb +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - @@connected_clients = Array.new - - - attr_reader :username - - - # - # EventMachine handlers - # - - def post_init - @username = nil - - puts "A client has connected..." - ask_username - end - - def unbind - @@connected_clients.delete(self) - puts "A client has left..." - end - - def receive_data(data) - if entered_username? - handle_chat_message(data.strip) - else - handle_username(data.strip) - end - end - - - - - # - # Username handling - # - - def entered_username? - !@username.nil? && !@username.empty? - end # entered_username? - - def handle_username(input) - if input.empty? - send_line("Blank usernames are not allowed. Try again.") - ask_username - else - @username = input - @@connected_clients.push(self) - self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") } - puts "#{@username} has joined" - - self.send_line("[info] Ohai, #{@username}") - end - end # handle_username(input) - - def ask_username - self.send_line("[info] Enter your username:") - end # ask_username - - - - # - # Message handling - # - - def handle_chat_message(msg) - raise NotImplementedError - end - - - - # - # Helpers - # - - def other_peers - @@connected_clients.reject { |c| self == c } - end # other_peers - - def send_line(line) - self.send_data("#{line}\n") - end # send_line(line) -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/07_simple_chat_server_step_four.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/07_simple_chat_server_step_four.rb deleted file mode 100644 index d4948af..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/07_simple_chat_server_step_four.rb +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - @@connected_clients = Array.new - - - attr_reader :username - - - # - # EventMachine handlers - # - - def post_init - @username = nil - - puts "A client has connected..." - ask_username - end - - def unbind - @@connected_clients.delete(self) - puts "[info] #{@username} has left" if entered_username? - end - - def receive_data(data) - if entered_username? - handle_chat_message(data.strip) - else - handle_username(data.strip) - end - end - - - - - # - # Username handling - # - - def entered_username? - !@username.nil? && !@username.empty? - end # entered_username? - - def handle_username(input) - if input.empty? - send_line("Blank usernames are not allowed. Try again.") - ask_username - else - @username = input - @@connected_clients.push(self) - self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") } - puts "#{@username} has joined" - - self.send_line("[info] Ohai, #{@username}") - end - end # handle_username(input) - - def ask_username - self.send_line("[info] Enter your username:") - end # ask_username - - - - # - # Message handling - # - - def handle_chat_message(msg) - if command?(msg) - self.handle_command(msg) - else - self.announce(msg, "#{@username}:") - end - end - - - # - # Commands handling - # - - def command?(input) - input =~ /exit$/i - end # command?(input) - - def handle_command(cmd) - case cmd - when /exit$/i then self.close_connection - end - end # handle_command(cmd) - - - - # - # Helpers - # - - def announce(msg = nil, prefix = "[chat server]") - @@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty? - end # announce(msg) - - def other_peers - @@connected_clients.reject { |c| self == c } - end # other_peers - - def send_line(line) - self.send_data("#{line}\n") - end # send_line(line) -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/08_simple_chat_server_step_five.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/08_simple_chat_server_step_five.rb deleted file mode 100644 index 03da66b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/guides/getting_started/08_simple_chat_server_step_five.rb +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env ruby - -require 'rubygems' # or use Bundler.setup -require 'eventmachine' - -class SimpleChatServer < EM::Connection - - @@connected_clients = Array.new - DM_REGEXP = /^@([a-zA-Z0-9]+)\s*:?\s+(.+)/.freeze - - attr_reader :username - - - # - # EventMachine handlers - # - - def post_init - @username = nil - - puts "A client has connected..." - ask_username - end - - def unbind - @@connected_clients.delete(self) - puts "[info] #{@username} has left" if entered_username? - end - - def receive_data(data) - if entered_username? - handle_chat_message(data.strip) - else - handle_username(data.strip) - end - end - - - # - # Username handling - # - - def entered_username? - !@username.nil? && !@username.empty? - end # entered_username? - - def handle_username(input) - if input.empty? - send_line("Blank usernames are not allowed. Try again.") - ask_username - else - @username = input - @@connected_clients.push(self) - self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") } - puts "#{@username} has joined" - - self.send_line("[info] Ohai, #{@username}") - end - end # handle_username(input) - - def ask_username - self.send_line("[info] Enter your username:") - end # ask_username - - - # - # Message handling - # - - def handle_chat_message(msg) - if command?(msg) - self.handle_command(msg) - else - if direct_message?(msg) - self.handle_direct_message(msg) - else - self.announce(msg, "#{@username}:") - end - end - end # handle_chat_message(msg) - - def direct_message?(input) - input =~ DM_REGEXP - end # direct_message?(input) - - def handle_direct_message(input) - username, message = parse_direct_message(input) - - if connection = @@connected_clients.find { |c| c.username == username } - puts "[dm] @#{@username} => @#{username}" - connection.send_line("[dm] @#{@username}: #{message}") - else - send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}" - end - end # handle_direct_message(input) - - def parse_direct_message(input) - return [$1, $2] if input =~ DM_REGEXP - end # parse_direct_message(input) - - - # - # Commands handling - # - - def command?(input) - input =~ /(exit|status)$/i - end # command?(input) - - def handle_command(cmd) - case cmd - when /exit$/i then self.close_connection - when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room") - end - end # handle_command(cmd) - - - # - # Helpers - # - - def announce(msg = nil, prefix = "[chat server]") - @@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty? - end # announce(msg) - - def other_peers - @@connected_clients.reject { |c| self == c } - end # other_peers - - def send_line(line) - self.send_data("#{line}\n") - end # send_line(line) -end - -EventMachine.run do - # hit Control + C to stop - Signal.trap("INT") { EventMachine.stop } - Signal.trap("TERM") { EventMachine.stop } - - EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_channel.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_channel.rb deleted file mode 100644 index 16e8d08..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_channel.rb +++ /dev/null @@ -1,43 +0,0 @@ -require File.dirname(__FILE__) + '/helper' - -EM.run do - - # Create a channel to push data to, this could be stocks... - RandChannel = EM::Channel.new - - # The server simply subscribes client connections to the channel on connect, - # and unsubscribes them on disconnect. - class Server < EM::Connection - def self.start(host = '127.0.0.1', port = 8000) - EM.start_server(host, port, self) - end - - def post_init - @sid = RandChannel.subscribe { |m| send_data "#{m.inspect}\n" } - end - - def unbind - RandChannel.unsubscribe @sid - end - end - Server.start - - # Two client connections, that just print what they receive. - 2.times do - EM.connect('127.0.0.1', 8000) do |c| - c.extend EM::P::LineText2 - def c.receive_line(line) - puts "Subscriber: #{signature} got #{line}" - end - EM.add_timer(2) { c.close_connection } - end - end - - # This part of the example is more fake, but imagine sleep was in fact a - # long running calculation to achieve the value. - 40.times do - EM.defer lambda { v = sleep(rand * 2); RandChannel << [Time.now, v] } - end - - EM.add_timer(5) { EM.stop } -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_queue.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_queue.rb deleted file mode 100644 index 761ea76..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_queue.rb +++ /dev/null @@ -1,2 +0,0 @@ -require File.dirname(__FILE__) + '/helper' - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_array.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_array.rb deleted file mode 100644 index 81b0ae3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_array.rb +++ /dev/null @@ -1,15 +0,0 @@ -require File.dirname(__FILE__) + '/helper' - -EM.run do - array = (1..100).to_a - - tickloop = EM.tick_loop do - if array.empty? - :stop - else - puts array.shift - end - end - - tickloop.on_stop { EM.stop } -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_counter.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_counter.rb deleted file mode 100644 index 58e51ff..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/ex_tick_loop_counter.rb +++ /dev/null @@ -1,32 +0,0 @@ -require File.dirname(__FILE__) + '/helper' - -class TickCounter - attr_reader :start_time, :count - - def initialize - reset - @tick_loop = EM.tick_loop(method(:tick)) - end - - def reset - @count = 0 - @start_time = EM.current_time - end - - def tick - @count += 1 - end - - def rate - @count / (EM.current_time - @start_time) - end -end - -period = 5 -EM.run do - counter = TickCounter.new - EM.add_periodic_timer(period) do - puts "Ticks per second: #{counter.rate} (mean of last #{period}s)" - counter.reset - end -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/helper.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/helper.rb deleted file mode 100644 index 835ded2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/examples/old/helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') -require 'eventmachine' \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.cpp deleted file mode 100644 index 5b90876..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: binder.cpp -Date: 07Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" - -#define DEV_URANDOM "/dev/urandom" - - -std::map Bindable_t::BindingBag; - - -/******************************** -STATIC Bindable_t::CreateBinding -********************************/ - -uintptr_t Bindable_t::CreateBinding() -{ - static uintptr_t num = 0; - while(BindingBag[++num]) {} - return num; -} - -#if 0 -string Bindable_t::CreateBinding() -{ - static int index = 0; - static string seed; - - if ((index >= 1000000) || (seed.length() == 0)) { - #ifdef OS_UNIX - int fd = open (DEV_URANDOM, O_RDONLY); - if (fd < 0) - throw std::runtime_error ("No entropy device"); - - unsigned char u[16]; - size_t r = read (fd, u, sizeof(u)); - if (r < sizeof(u)) - throw std::runtime_error ("Unable to read entropy device"); - - unsigned char *u1 = (unsigned char*)u; - char u2 [sizeof(u) * 2 + 1]; - - for (size_t i=0; i < sizeof(u); i++) - sprintf (u2 + (i * 2), "%02x", u1[i]); - - seed = string (u2); - #endif - - - #ifdef OS_WIN32 - UUID uuid; - UuidCreate (&uuid); - unsigned char *uuidstring = NULL; - UuidToString (&uuid, &uuidstring); - if (!uuidstring) - throw std::runtime_error ("Unable to read uuid"); - seed = string ((const char*)uuidstring); - - RpcStringFree (&uuidstring); - #endif - - index = 0; - - - } - - stringstream ss; - ss << seed << (++index); - return ss.str(); -} -#endif - -/***************************** -STATIC: Bindable_t::GetObject -*****************************/ - -Bindable_t *Bindable_t::GetObject (const uintptr_t binding) -{ - std::map::const_iterator i = BindingBag.find (binding); - if (i != BindingBag.end()) - return i->second; - else - return NULL; -} - - -/********************** -Bindable_t::Bindable_t -**********************/ - -Bindable_t::Bindable_t() -{ - Binding = Bindable_t::CreateBinding(); - BindingBag [Binding] = this; -} - - - -/*********************** -Bindable_t::~Bindable_t -***********************/ - -Bindable_t::~Bindable_t() NO_EXCEPT_FALSE -{ - BindingBag.erase (Binding); -} - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.h deleted file mode 100644 index dd32c8d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/binder.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: binder.h -Date: 07Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#ifndef __ObjectBindings__H_ -#define __ObjectBindings__H_ - - -#if __cplusplus >= 201103L -#define NO_EXCEPT_FALSE noexcept(false) -#else -#define NO_EXCEPT_FALSE -#endif - -class Bindable_t -{ - public: - static uintptr_t CreateBinding(); - static Bindable_t *GetObject (const uintptr_t); - static std::map BindingBag; - - public: - Bindable_t(); - virtual ~Bindable_t() NO_EXCEPT_FALSE; - - const uintptr_t GetBinding() {return Binding;} - - private: - uintptr_t Binding; -}; - - - - - -#endif // __ObjectBindings__H_ - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/cmain.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/cmain.cpp deleted file mode 100644 index f58c2cd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/cmain.cpp +++ /dev/null @@ -1,988 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: cmain.cpp -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" - -/* 21Sep09: ruby 1.9 defines macros for common i/o functions that point to rb_w32_* implementations. - We need to undef the stat to fix a build failure in evma_send_file_data_to_connection. - See http://groups.google.com/group/eventmachine/browse_thread/thread/fc60d9bb738ffc71 -*/ -#if defined(BUILD_FOR_RUBY) && defined(OS_WIN32) -#undef stat -#undef fstat -#endif - -static EventMachine_t *EventMachine; -static Poller_t Poller = Poller_Default; - -extern "C" void ensure_eventmachine (const char *caller = "unknown caller") -{ - if (!EventMachine) { - const int err_size = 128; - char err_string[err_size]; - snprintf (err_string, err_size, "eventmachine not initialized: %s", caller); - #ifdef BUILD_FOR_RUBY - rb_raise(rb_eRuntimeError, "%s", err_string); - #else - throw std::runtime_error (err_string); - #endif - } -} - -/*********************** -evma_initialize_library -***********************/ - -extern "C" void evma_initialize_library (EMCallback cb) -{ - if (EventMachine) - #ifdef BUILD_FOR_RUBY - rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library"); - #else - throw std::runtime_error ("eventmachine already initialized: evma_initialize_library"); - #endif - - EventMachine = new EventMachine_t (cb, Poller); -} - - -/******************** -evma_release_library -********************/ - -extern "C" void evma_release_library() -{ - ensure_eventmachine("evma_release_library"); - delete EventMachine; - EventMachine = NULL; -} - - -/********************* -evma_run_machine_once -*********************/ - -extern "C" bool evma_run_machine_once() -{ - ensure_eventmachine("evma_run_machine_once"); - return EventMachine->RunOnce(); -} - - -/**************** -evma_run_machine -****************/ - -extern "C" void evma_run_machine() -{ - ensure_eventmachine("evma_run_machine"); - EventMachine->Run(); -} - - -/************************** -evma_install_oneshot_timer -**************************/ - -extern "C" const uintptr_t evma_install_oneshot_timer (uint64_t milliseconds) -{ - ensure_eventmachine("evma_install_oneshot_timer"); - return EventMachine->InstallOneshotTimer (milliseconds); -} - - -/********************** -evma_connect_to_server -**********************/ - -extern "C" const uintptr_t evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port) -{ - ensure_eventmachine("evma_connect_to_server"); - return EventMachine->ConnectToServer (bind_addr, bind_port, server, port); -} - -/*************************** -evma_connect_to_unix_server -***************************/ - -extern "C" const uintptr_t evma_connect_to_unix_server (const char *server) -{ - ensure_eventmachine("evma_connect_to_unix_server"); - return EventMachine->ConnectToUnixServer (server); -} - -/************** -evma_attach_fd -**************/ - -extern "C" const uintptr_t evma_attach_fd (int file_descriptor, int watch_mode) -{ - ensure_eventmachine("evma_attach_fd"); - return EventMachine->AttachFD (file_descriptor, watch_mode ? true : false); -} - -/************** -evma_detach_fd -**************/ - -extern "C" int evma_detach_fd (const uintptr_t binding) -{ - ensure_eventmachine("evma_detach_fd"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return EventMachine->DetachFD (ed); - else - #ifdef BUILD_FOR_RUBY - rb_raise(rb_eRuntimeError, "invalid binding to detach"); - #else - throw std::runtime_error ("invalid binding to detach"); - #endif - return -1; -} - -/************************ -evma_get_file_descriptor -************************/ - -extern "C" int evma_get_file_descriptor (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_file_descriptor"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetSocket(); - else - #ifdef BUILD_FOR_RUBY - rb_raise(rb_eRuntimeError, "invalid binding to get_fd"); - #else - throw std::runtime_error ("invalid binding to get_fd"); - #endif - return -1; -} - -/*********************** -evma_is_notify_readable -***********************/ - -extern "C" int evma_is_notify_readable (const uintptr_t binding) -{ - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - return cd->IsNotifyReadable() ? 1 : 0; - return -1; -} - -/************************ -evma_set_notify_readable -************************/ - -extern "C" void evma_set_notify_readable (const uintptr_t binding, int mode) -{ - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - cd->SetNotifyReadable (mode ? true : false); -} - -/*********************** -evma_is_notify_writable -***********************/ - -extern "C" int evma_is_notify_writable (const uintptr_t binding) -{ - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - return cd->IsNotifyWritable() ? 1 : 0; - return -1; -} - -/************************ -evma_set_notify_writable -************************/ - -extern "C" void evma_set_notify_writable (const uintptr_t binding, int mode) -{ - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - cd->SetNotifyWritable (mode ? true : false); -} - -/********** -evma_pause -**********/ - -extern "C" int evma_pause (const uintptr_t binding) -{ - EventableDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - return cd->Pause() ? 1 : 0; - - return 0; -} - -/*********** -evma_resume -***********/ - -extern "C" int evma_resume (const uintptr_t binding) -{ - EventableDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - return cd->Resume() ? 1 : 0; - - return 0; -} - -/************** -evma_is_paused -**************/ - -extern "C" int evma_is_paused (const uintptr_t binding) -{ - EventableDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - return cd->IsPaused() ? 1 : 0; - - return 0; -} - -/************************ -evma_num_close_scheduled -************************/ - -extern "C" int evma_num_close_scheduled () -{ - ensure_eventmachine("evma_num_close_scheduled"); - return EventMachine->NumCloseScheduled; -} - -/********************** -evma_create_tcp_server -**********************/ - -extern "C" const uintptr_t evma_create_tcp_server (const char *address, int port) -{ - ensure_eventmachine("evma_create_tcp_server"); - return EventMachine->CreateTcpServer (address, port); -} - -/****************************** -evma_create_unix_domain_server -******************************/ - -extern "C" const uintptr_t evma_create_unix_domain_server (const char *filename) -{ - ensure_eventmachine("evma_create_unix_domain_server"); - return EventMachine->CreateUnixDomainServer (filename); -} - -/*********************** -evma_attach_sd -************************/ - -extern "C" const uintptr_t evma_attach_sd (int sd) -{ - ensure_eventmachine("evma_attach_sd"); - return EventMachine->AttachSD (sd); -} - -/************************* -evma_open_datagram_socket -*************************/ - -extern "C" const uintptr_t evma_open_datagram_socket (const char *address, int port) -{ - ensure_eventmachine("evma_open_datagram_socket"); - return EventMachine->OpenDatagramSocket (address, port); -} - -/****************** -evma_open_keyboard -******************/ - -extern "C" const uintptr_t evma_open_keyboard() -{ - ensure_eventmachine("evma_open_keyboard"); - return EventMachine->OpenKeyboard(); -} - -/******************* -evma_watch_filename -*******************/ - -extern "C" const uintptr_t evma_watch_filename (const char *fname) -{ - ensure_eventmachine("evma_watch_filename"); - return EventMachine->WatchFile(fname); -} - -/********************* -evma_unwatch_filename -*********************/ - -extern "C" void evma_unwatch_filename (const uintptr_t sig) -{ - ensure_eventmachine("evma_unwatch_file"); - EventMachine->UnwatchFile(sig); -} - -/************** -evma_watch_pid -**************/ - -extern "C" const uintptr_t evma_watch_pid (int pid) -{ - ensure_eventmachine("evma_watch_pid"); - return EventMachine->WatchPid(pid); -} - -/**************** -evma_unwatch_pid -****************/ - -extern "C" void evma_unwatch_pid (const uintptr_t sig) -{ - ensure_eventmachine("evma_unwatch_pid"); - EventMachine->UnwatchPid(sig); -} - -/**************************** -evma_send_data_to_connection -****************************/ - -extern "C" int evma_send_data_to_connection (const uintptr_t binding, const char *data, int data_length) -{ - ensure_eventmachine("evma_send_data_to_connection"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->SendOutboundData(data, data_length); - return -1; -} - -/****************** -evma_send_datagram -******************/ - -extern "C" int evma_send_datagram (const uintptr_t binding, const char *data, int data_length, const char *address, int port) -{ - ensure_eventmachine("evma_send_datagram"); - DatagramDescriptor *dd = dynamic_cast (Bindable_t::GetObject (binding)); - if (dd) - return dd->SendOutboundDatagram(data, data_length, address, port); - return -1; -} - - -/********************* -evma_close_connection -*********************/ - -extern "C" void evma_close_connection (const uintptr_t binding, int after_writing) -{ - ensure_eventmachine("evma_close_connection"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - ed->ScheduleClose (after_writing ? true : false); -} - -/*********************************** -evma_report_connection_error_status -***********************************/ - -extern "C" int evma_report_connection_error_status (const uintptr_t binding) -{ - ensure_eventmachine("evma_report_connection_error_status"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->ReportErrorStatus(); - return -1; -} - -/******************** -evma_stop_tcp_server -********************/ - -extern "C" void evma_stop_tcp_server (const uintptr_t binding) -{ - ensure_eventmachine("evma_stop_tcp_server"); - AcceptorDescriptor::StopAcceptor (binding); -} - - -/***************** -evma_stop_machine -*****************/ - -extern "C" void evma_stop_machine() -{ - ensure_eventmachine("evma_stop_machine"); - EventMachine->ScheduleHalt(); -} - -/***************** -evma_stopping -*****************/ - -extern "C" bool evma_stopping() -{ - ensure_eventmachine("evma_stopping"); - return EventMachine->Stopping(); -} - -/************** -evma_start_tls -**************/ - -extern "C" void evma_start_tls (const uintptr_t binding) -{ - ensure_eventmachine("evma_start_tls"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - ed->StartTls(); -} - -/****************** -evma_set_tls_parms -******************/ - -extern "C" void evma_set_tls_parms (const uintptr_t binding, const char *privatekey_filename, const char *certchain_filename, int verify_peer, int fail_if_no_peer_cert, const char *sni_hostname, const char *cipherlist, const char *ecdh_curve, const char *dhparam, int ssl_version) -{ - ensure_eventmachine("evma_set_tls_parms"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - ed->SetTlsParms (privatekey_filename, certchain_filename, (verify_peer == 1 ? true : false), (fail_if_no_peer_cert == 1 ? true : false), sni_hostname, cipherlist, ecdh_curve, dhparam, ssl_version); -} - -/****************** -evma_get_peer_cert -******************/ - -#ifdef WITH_SSL -extern "C" X509 *evma_get_peer_cert (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_peer_cert"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetPeerCert(); - return NULL; -} -#endif - -/****************** -evma_get_cipher_bits -******************/ - -#ifdef WITH_SSL -extern "C" int evma_get_cipher_bits (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_cipher_bits"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetCipherBits(); - return -1; -} -#endif - -/****************** -evma_get_cipher_name -******************/ - -#ifdef WITH_SSL -extern "C" const char *evma_get_cipher_name (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_cipher_name"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetCipherName(); - return NULL; -} -#endif - -/****************** -evma_get_cipher_protocol -******************/ - -#ifdef WITH_SSL -extern "C" const char *evma_get_cipher_protocol (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_cipher_protocol"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetCipherProtocol(); - return NULL; -} -#endif - -/****************** -evma_get_sni_hostname -******************/ - -#ifdef WITH_SSL -extern "C" const char *evma_get_sni_hostname (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_sni_hostname"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) - return ed->GetSNIHostname(); - return NULL; -} -#endif - -/******************** -evma_accept_ssl_peer -********************/ - -#ifdef WITH_SSL -extern "C" void evma_accept_ssl_peer (const uintptr_t binding) -{ - ensure_eventmachine("evma_accept_ssl_peer"); - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject (binding)); - if (cd) - cd->AcceptSslPeer(); -} -#endif - -/***************** -evma_get_peername -*****************/ - -extern "C" int evma_get_peername (const uintptr_t binding, struct sockaddr *sa, socklen_t *len) -{ - ensure_eventmachine("evma_get_peername"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ed->GetPeername (sa, len) ? 1 : 0; - } - else - return 0; -} - -/***************** -evma_get_sockname -*****************/ - -extern "C" int evma_get_sockname (const uintptr_t binding, struct sockaddr *sa, socklen_t *len) -{ - ensure_eventmachine("evma_get_sockname"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ed->GetSockname (sa, len) ? 1 : 0; - } - else - return 0; -} - -/*********************** -evma_get_subprocess_pid -***********************/ - -#ifdef OS_UNIX -extern "C" int evma_get_subprocess_pid (const uintptr_t binding, pid_t *pid) -{ - ensure_eventmachine("evma_get_subprocess_pid"); - PipeDescriptor *pd = dynamic_cast (Bindable_t::GetObject (binding)); - if (pd) { - return pd->GetSubprocessPid (pid) ? 1 : 0; - } - else if (pid && EventMachine->SubprocessPid) { - *pid = EventMachine->SubprocessPid; - return 1; - } - else - return 0; -} -#else -extern "C" int evma_get_subprocess_pid (const uintptr_t binding UNUSED, pid_t *pid UNUSED) -{ - return 0; -} -#endif - -/************************** -evma_get_subprocess_status -**************************/ - -extern "C" int evma_get_subprocess_status (const uintptr_t binding UNUSED, int *status) -{ - ensure_eventmachine("evma_get_subprocess_status"); - if (status) { - *status = EventMachine->SubprocessExitStatus; - return 1; - } - else - return 0; -} - -/************************* -evma_get_connection_count -*************************/ - -extern "C" int evma_get_connection_count() -{ - ensure_eventmachine("evma_get_connection_count"); - return EventMachine->GetConnectionCount(); -} - -/********************* -evma_signal_loopbreak -*********************/ - -extern "C" void evma_signal_loopbreak() -{ - ensure_eventmachine("evma_signal_loopbreak"); - EventMachine->SignalLoopBreaker(); -} - - - -/******************************** -evma_get_comm_inactivity_timeout -********************************/ - -extern "C" float evma_get_comm_inactivity_timeout (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_comm_inactivity_timeout"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ((float)ed->GetCommInactivityTimeout() / 1000); - } - else - return 0.0; //Perhaps this should be an exception. Access to an unknown binding. -} - -/******************************** -evma_set_comm_inactivity_timeout -********************************/ - -extern "C" int evma_set_comm_inactivity_timeout (const uintptr_t binding, float value) -{ - ensure_eventmachine("evma_set_comm_inactivity_timeout"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ed->SetCommInactivityTimeout ((uint64_t)(value * 1000)); - } - else - return 0; //Perhaps this should be an exception. Access to an unknown binding. -} - - -/******************************** -evma_get_pending_connect_timeout -********************************/ - -extern "C" float evma_get_pending_connect_timeout (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_pending_connect_timeout"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ((float)ed->GetPendingConnectTimeout() / 1000); - } - else - return 0.0; -} - - -/******************************** -evma_set_pending_connect_timeout -********************************/ - -extern "C" int evma_set_pending_connect_timeout (const uintptr_t binding, float value) -{ - ensure_eventmachine("evma_set_pending_connect_timeout"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - if (ed) { - return ed->SetPendingConnectTimeout ((uint64_t)(value * 1000)); - } - else - return 0; -} - - -/********************** -evma_set_timer_quantum -**********************/ - -extern "C" void evma_set_timer_quantum (int interval) -{ - ensure_eventmachine("evma_set_timer_quantum"); - EventMachine->SetTimerQuantum (interval); -} - - -/************************ -evma_get_max_timer_count -************************/ - -extern "C" int evma_get_max_timer_count() -{ - return EventMachine_t::GetMaxTimerCount(); -} - -/************************ -evma_set_max_timer_count -************************/ - -extern "C" void evma_set_max_timer_count (int ct) -{ - // This may only be called if the reactor is not running. - - if (EventMachine) - #ifdef BUILD_FOR_RUBY - rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count"); - #else - throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count"); - #endif - EventMachine_t::SetMaxTimerCount (ct); -} - -/****************** -evma_get/set_simultaneous_accept_count -******************/ - -extern "C" void evma_set_simultaneous_accept_count (int count) -{ - EventMachine_t::SetSimultaneousAcceptCount(count); -} - -extern "C" int evma_get_simultaneous_accept_count() -{ - return EventMachine_t::GetSimultaneousAcceptCount(); -} - - -/****************** -evma_setuid_string -******************/ - -extern "C" void evma_setuid_string (const char *username) -{ - // We do NOT need to be running an EM instance because this method is static. - EventMachine_t::SetuidString (username); -} - - -/********** -evma_popen -**********/ - -extern "C" const uintptr_t evma_popen (char * const*cmd_strings) -{ - ensure_eventmachine("evma_popen"); - return EventMachine->Socketpair (cmd_strings); -} - - -/*************************** -evma_get_outbound_data_size -***************************/ - -extern "C" int evma_get_outbound_data_size (const uintptr_t binding) -{ - ensure_eventmachine("evma_get_outbound_data_size"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (binding)); - return ed ? ed->GetOutboundDataSize() : 0; -} - - -/************** -evma_set_epoll -**************/ - -extern "C" void evma_set_epoll (int use) -{ - if (use) - Poller = Poller_Epoll; - else - Poller = Poller_Default; -} - -/*************** -evma_set_kqueue -***************/ - -extern "C" void evma_set_kqueue (int use) -{ - if (use) - Poller = Poller_Kqueue; - else - Poller = Poller_Default; -} - - -/********************** -evma_set_rlimit_nofile -**********************/ - -extern "C" int evma_set_rlimit_nofile (int nofiles) -{ - return EventMachine_t::SetRlimitNofile (nofiles); -} - - -/********************************* -evma_send_file_data_to_connection -*********************************/ - -extern "C" int evma_send_file_data_to_connection (const uintptr_t binding, const char *filename) -{ - /* This is a sugaring over send_data_to_connection that reads a file into a - * locally-allocated buffer, and sends the file data to the remote peer. - * Return the number of bytes written to the caller. - * TODO, needs to impose a limit on the file size. This is intended only for - * small files. (I don't know, maybe 8K or less.) For larger files, use interleaved - * I/O to avoid slowing the rest of the system down. - * TODO: we should return a code rather than barf, in case of file-not-found. - * TODO, does this compile on Windows? - * TODO, given that we want this to work only with small files, how about allocating - * the buffer on the stack rather than the heap? - * - * Modified 25Jul07. This now returns -1 on file-too-large; 0 for success, and a positive - * errno in case of other errors. - * - * Contributed by Kirk Haines. - */ - - char data[32*1024]; - int r; - - ensure_eventmachine("evma_send_file_data_to_connection"); - -#if defined(OS_WIN32) - int Fd = open (filename, O_RDONLY|O_BINARY); -#else - int Fd = open (filename, O_RDONLY); -#endif - if (Fd < 0) - return errno; - // From here on, all early returns MUST close Fd. - - struct stat st; - if (fstat (Fd, &st)) { - int e = errno; - close (Fd); - return e; - } - - off_t filesize = st.st_size; - if (filesize <= 0) { - close (Fd); - return 0; - } - else if (filesize > (off_t) sizeof(data)) { - close (Fd); - return -1; - } - - r = read (Fd, data, filesize); - if (r != filesize) { - int e = errno; - close (Fd); - return e; - } - evma_send_data_to_connection (binding, data, r); - close (Fd); - - return 0; -} - - -/**************** -evma_start_proxy -*****************/ - -extern "C" void evma_start_proxy (const uintptr_t from, const uintptr_t to, const unsigned long bufsize, const unsigned long length) -{ - ensure_eventmachine("evma_start_proxy"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (from)); - if (ed) - ed->StartProxy(to, bufsize, length); -} - - -/*************** -evma_stop_proxy -****************/ - -extern "C" void evma_stop_proxy (const uintptr_t from) -{ - ensure_eventmachine("evma_stop_proxy"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (from)); - if (ed) - ed->StopProxy(); -} - -/****************** -evma_proxied_bytes -*******************/ - -extern "C" unsigned long evma_proxied_bytes (const uintptr_t from) -{ - ensure_eventmachine("evma_proxied_bytes"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (from)); - if (ed) - return ed->GetProxiedBytes(); - else - return 0; -} - - -/*************************** -evma_get_last_activity_time -****************************/ - -extern "C" uint64_t evma_get_last_activity_time(const uintptr_t from) -{ - ensure_eventmachine("evma_get_last_activity_time"); - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (from)); - if (ed) - return ed->GetLastActivity(); - else - return 0; -} - - -/*************************** -evma_get_heartbeat_interval -****************************/ - -extern "C" float evma_get_heartbeat_interval() -{ - ensure_eventmachine("evma_get_heartbeat_interval"); - return EventMachine->GetHeartbeatInterval(); -} - - -/*************************** -evma_set_heartbeat_interval -****************************/ - -extern "C" int evma_set_heartbeat_interval(float interval) -{ - ensure_eventmachine("evma_set_heartbeat_interval"); - return EventMachine->SetHeartbeatInterval(interval); -} - - -/************************** -evma_get_current_loop_time -***************************/ - -extern "C" uint64_t evma_get_current_loop_time() -{ - ensure_eventmachine("evma_get_current_loop_time"); - return EventMachine->GetCurrentLoopTime(); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.cpp deleted file mode 100644 index a469dff..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.cpp +++ /dev/null @@ -1,2096 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: ed.cpp -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" - - - -/******************** -SetSocketNonblocking -********************/ - -bool SetSocketNonblocking (SOCKET sd) -{ - #ifdef OS_UNIX - int val = fcntl (sd, F_GETFL, 0); - return (fcntl (sd, F_SETFL, val | O_NONBLOCK) != SOCKET_ERROR) ? true : false; - #endif - - #ifdef OS_WIN32 - #ifdef BUILD_FOR_RUBY - // 14Jun09 Ruby provides its own wrappers for ioctlsocket. On 1.8 this is a simple wrapper, - // however, 1.9 keeps its own state about the socket. - // NOTE: F_GETFL is not supported - return (fcntl (sd, F_SETFL, O_NONBLOCK) == 0) ? true : false; - #else - unsigned long one = 1; - return (ioctlsocket (sd, FIONBIO, &one) == 0) ? true : false; - #endif - #endif -} - -/************ -SetFdCloexec -************/ - -#ifdef OS_UNIX -bool SetFdCloexec (int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - assert (flags >= 0); - flags |= FD_CLOEXEC; - return (fcntl(fd, F_SETFD, FD_CLOEXEC) == 0) ? true : false; -} -#else -bool SetFdCloexec (int fd UNUSED) -{ - return true; -} -#endif - -/**************************************** -EventableDescriptor::EventableDescriptor -****************************************/ - -EventableDescriptor::EventableDescriptor (SOCKET sd, EventMachine_t *em): - bCloseNow (false), - bCloseAfterWriting (false), - MySocket (sd), - bAttached (false), - bWatchOnly (false), - EventCallback (NULL), - bCallbackUnbind (true), - UnbindReasonCode (0), - ProxyTarget(NULL), - ProxiedFrom(NULL), - ProxiedBytes(0), - MaxOutboundBufSize(0), - MyEventMachine (em), - PendingConnectTimeout(20000000), - InactivityTimeout (0), - NextHeartbeat (0), - bPaused (false) -{ - /* There are three ways to close a socket, all of which should - * automatically signal to the event machine that this object - * should be removed from the polling scheduler. - * First is a hard close, intended for bad errors or possible - * security violations. It immediately closes the connection - * and puts this object into an error state. - * Second is to set bCloseNow, which will cause the event machine - * to delete this object (and thus close the connection in our - * destructor) the next chance it gets. bCloseNow also inhibits - * the writing of new data on the socket (but not necessarily - * the reading of new data). - * The third way is to set bCloseAfterWriting, which inhibits - * the writing of new data and converts to bCloseNow as soon - * as everything in the outbound queue has been written. - * bCloseAfterWriting is really for use only by protocol handlers - * (for example, HTTP writes an HTML page and then closes the - * connection). All of the error states we generate internally - * cause an immediate close to be scheduled, which may have the - * effect of discarding outbound data. - */ - - if (sd == INVALID_SOCKET) - throw std::runtime_error ("bad eventable descriptor"); - if (MyEventMachine == NULL) - throw std::runtime_error ("bad em in eventable descriptor"); - CreatedAt = MyEventMachine->GetCurrentLoopTime(); - LastActivity = MyEventMachine->GetCurrentLoopTime(); - - #ifdef HAVE_EPOLL - EpollEvent.events = 0; - EpollEvent.data.ptr = this; - #endif -} - - -/***************************************** -EventableDescriptor::~EventableDescriptor -*****************************************/ - -EventableDescriptor::~EventableDescriptor() NO_EXCEPT_FALSE -{ - if (NextHeartbeat) - MyEventMachine->ClearHeartbeat(NextHeartbeat, this); - if (EventCallback && bCallbackUnbind) - (*EventCallback)(GetBinding(), EM_CONNECTION_UNBOUND, NULL, UnbindReasonCode); - if (ProxiedFrom) { - (*EventCallback)(ProxiedFrom->GetBinding(), EM_PROXY_TARGET_UNBOUND, NULL, 0); - ProxiedFrom->StopProxy(); - } - MyEventMachine->NumCloseScheduled--; - StopProxy(); - Close(); -} - - -/************************************* -EventableDescriptor::SetEventCallback -*************************************/ - -void EventableDescriptor::SetEventCallback (EMCallback cb) -{ - EventCallback = cb; -} - - -/************************** -EventableDescriptor::Close -**************************/ - -void EventableDescriptor::Close() -{ - /* EventMachine relies on the fact that when close(fd) - * is called that the fd is removed from any - * epoll event queues. - * - * However, this is not *always* the behavior of close(fd) - * - * See man 4 epoll Q6/A6 and then consider what happens - * when using pipes with eventmachine. - * (As is often done when communicating with a subprocess) - * - * The pipes end up looking like: - * - * ls -l /proc//fd - * ... - * lr-x------ 1 root root 64 2011-08-19 21:31 3 -> pipe:[940970] - * l-wx------ 1 root root 64 2011-08-19 21:31 4 -> pipe:[940970] - * - * This meets the critera from man 4 epoll Q6/A4 for not - * removing fds from epoll event queues until all fds - * that reference the underlying file have been removed. - * - * If the EventableDescriptor associated with fd 3 is deleted, - * its dtor will call EventableDescriptor::Close(), - * which will call ::close(int fd). - * - * However, unless the EventableDescriptor associated with fd 4 is - * also deleted before the next call to epoll_wait, events may fire - * for fd 3 that were registered with an already deleted - * EventableDescriptor. - * - * Therefore, it is necessary to notify EventMachine that - * the fd associated with this EventableDescriptor is - * closing. - * - * EventMachine also never closes fds for STDIN, STDOUT and - * STDERR (0, 1 & 2) - */ - - // Close the socket right now. Intended for emergencies. - if (MySocket != INVALID_SOCKET) { - MyEventMachine->Deregister (this); - - // Do not close STDIN, STDOUT, STDERR - if (MySocket > 2 && !bAttached) { - shutdown (MySocket, 1); - close (MySocket); - } - - MySocket = INVALID_SOCKET; - } -} - - -/********************************* -EventableDescriptor::ShouldDelete -*********************************/ - -bool EventableDescriptor::ShouldDelete() -{ - /* For use by a socket manager, which needs to know if this object - * should be removed from scheduling events and deleted. - * Has an immediate close been scheduled, or are we already closed? - * If either of these are the case, return true. In theory, the manager will - * then delete us, which in turn will make sure the socket is closed. - * Note, if bCloseAfterWriting is true, we check a virtual method to see - * if there is outbound data to write, and only request a close if there is none. - */ - - return ((MySocket == INVALID_SOCKET) || bCloseNow || (bCloseAfterWriting && (GetOutboundDataSize() <= 0))); -} - - -/********************************** -EventableDescriptor::ScheduleClose -**********************************/ - -void EventableDescriptor::ScheduleClose (bool after_writing) -{ - if (IsCloseScheduled()) { - if (!after_writing) { - // If closing has become more urgent, then upgrade the scheduled - // after_writing close to one NOW. - bCloseNow = true; - } - return; - } - MyEventMachine->NumCloseScheduled++; - // KEEP THIS SYNCHRONIZED WITH ::IsCloseScheduled. - if (after_writing) - bCloseAfterWriting = true; - else - bCloseNow = true; -} - - -/************************************* -EventableDescriptor::IsCloseScheduled -*************************************/ - -bool EventableDescriptor::IsCloseScheduled() -{ - // KEEP THIS SYNCHRONIZED WITH ::ScheduleClose. - return (bCloseNow || bCloseAfterWriting); -} - - -/******************************* -EventableDescriptor::StartProxy -*******************************/ - -void EventableDescriptor::StartProxy(const uintptr_t to, const unsigned long bufsize, const unsigned long length) -{ - EventableDescriptor *ed = dynamic_cast (Bindable_t::GetObject (to)); - if (ed) { - StopProxy(); - ProxyTarget = ed; - BytesToProxy = length; - ProxiedBytes = 0; - ed->SetProxiedFrom(this, bufsize); - return; - } - throw std::runtime_error ("Tried to proxy to an invalid descriptor"); -} - - -/****************************** -EventableDescriptor::StopProxy -******************************/ - -void EventableDescriptor::StopProxy() -{ - if (ProxyTarget) { - ProxyTarget->SetProxiedFrom(NULL, 0); - ProxyTarget = NULL; - } -} - - -/*********************************** -EventableDescriptor::SetProxiedFrom -***********************************/ - -void EventableDescriptor::SetProxiedFrom(EventableDescriptor *from, const unsigned long bufsize) -{ - if (from != NULL && ProxiedFrom != NULL) - throw std::runtime_error ("Tried to proxy to a busy target"); - - ProxiedFrom = from; - MaxOutboundBufSize = bufsize; -} - - -/******************************************** -EventableDescriptor::_GenericInboundDispatch -********************************************/ - -void EventableDescriptor::_GenericInboundDispatch(const char *buf, unsigned long size) -{ - assert(EventCallback); - - if (ProxyTarget) { - if (BytesToProxy > 0) { - unsigned long proxied = std::min(BytesToProxy, size); - ProxyTarget->SendOutboundData(buf, proxied); - ProxiedBytes += (unsigned long) proxied; - BytesToProxy -= proxied; - if (BytesToProxy == 0) { - StopProxy(); - (*EventCallback)(GetBinding(), EM_PROXY_COMPLETED, NULL, 0); - if (proxied < size) { - (*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf + proxied, size - proxied); - } - } - } else { - ProxyTarget->SendOutboundData(buf, size); - ProxiedBytes += size; - } - } else { - (*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size); - } -} - - -/********************************* -EventableDescriptor::_GenericGetPeername -*********************************/ - -bool EventableDescriptor::_GenericGetPeername (struct sockaddr *s, socklen_t *len) -{ - if (!s) - return false; - - int gp = getpeername (GetSocket(), s, len); - if (gp == -1) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "unable to get peer name: %s", strerror(errno)); - throw std::runtime_error (buf); - } - - return true; -} - -/********************************* -EventableDescriptor::_GenericGetSockname -*********************************/ - -bool EventableDescriptor::_GenericGetSockname (struct sockaddr *s, socklen_t *len) -{ - if (!s) - return false; - - int gp = getsockname (GetSocket(), s, len); - if (gp == -1) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "unable to get sock name: %s", strerror(errno)); - throw std::runtime_error (buf); - } - - return true; -} - - -/********************************************* -EventableDescriptor::GetPendingConnectTimeout -*********************************************/ - -uint64_t EventableDescriptor::GetPendingConnectTimeout() -{ - return PendingConnectTimeout / 1000; -} - - -/********************************************* -EventableDescriptor::SetPendingConnectTimeout -*********************************************/ - -int EventableDescriptor::SetPendingConnectTimeout (uint64_t value) -{ - if (value > 0) { - PendingConnectTimeout = value * 1000; - MyEventMachine->QueueHeartbeat(this); - return 1; - } - return 0; -} - - -/************************************* -EventableDescriptor::GetNextHeartbeat -*************************************/ - -uint64_t EventableDescriptor::GetNextHeartbeat() -{ - if (NextHeartbeat) - MyEventMachine->ClearHeartbeat(NextHeartbeat, this); - - NextHeartbeat = 0; - - if (!ShouldDelete()) { - uint64_t time_til_next = InactivityTimeout; - if (IsConnectPending()) { - if (time_til_next == 0 || PendingConnectTimeout < time_til_next) - time_til_next = PendingConnectTimeout; - } - if (time_til_next == 0) - return 0; - NextHeartbeat = time_til_next + MyEventMachine->GetRealTime(); - } - - return NextHeartbeat; -} - - -/****************************************** -ConnectionDescriptor::ConnectionDescriptor -******************************************/ - -ConnectionDescriptor::ConnectionDescriptor (SOCKET sd, EventMachine_t *em): - EventableDescriptor (sd, em), - bConnectPending (false), - bNotifyReadable (false), - bNotifyWritable (false), - bReadAttemptedAfterClose (false), - bWriteAttemptedAfterClose (false), - OutboundDataSize (0), - #ifdef WITH_SSL - SslBox (NULL), - bHandshakeSignaled (false), - bSslVerifyPeer (false), - bSslPeerAccepted(false), - #endif - #ifdef HAVE_KQUEUE - bGotExtraKqueueEvent(false), - #endif - bIsServer (false) -{ - // 22Jan09: Moved ArmKqueueWriter into SetConnectPending() to fix assertion failure in _WriteOutboundData() - // 5May09: Moved EPOLLOUT into SetConnectPending() so it doesn't happen for attached read pipes -} - - -/******************************************* -ConnectionDescriptor::~ConnectionDescriptor -*******************************************/ - -ConnectionDescriptor::~ConnectionDescriptor() -{ - // Run down any stranded outbound data. - for (size_t i=0; i < OutboundPages.size(); i++) - OutboundPages[i].Free(); - - #ifdef WITH_SSL - if (SslBox) - delete SslBox; - #endif -} - - -/*********************************** -ConnectionDescriptor::_UpdateEvents -************************************/ - -void ConnectionDescriptor::_UpdateEvents() -{ - _UpdateEvents(true, true); -} - -void ConnectionDescriptor::_UpdateEvents(bool read, bool write) -{ - if (MySocket == INVALID_SOCKET) - return; - - if (!read && !write) - return; - - #ifdef HAVE_EPOLL - unsigned int old = EpollEvent.events; - - if (read) { - if (SelectForRead()) - EpollEvent.events |= EPOLLIN; - else - EpollEvent.events &= ~EPOLLIN; - } - - if (write) { - if (SelectForWrite()) - EpollEvent.events |= EPOLLOUT; - else - EpollEvent.events &= ~EPOLLOUT; - } - - if (old != EpollEvent.events) - MyEventMachine->Modify (this); - #endif - - #ifdef HAVE_KQUEUE - if (read && SelectForRead()) - MyEventMachine->ArmKqueueReader (this); - bKqueueArmWrite = SelectForWrite(); - if (write && bKqueueArmWrite) - MyEventMachine->Modify (this); - #endif -} - -/*************************************** -ConnectionDescriptor::SetConnectPending -****************************************/ - -void ConnectionDescriptor::SetConnectPending(bool f) -{ - bConnectPending = f; - MyEventMachine->QueueHeartbeat(this); - _UpdateEvents(); -} - - -/********************************** -ConnectionDescriptor::SetAttached -***********************************/ - -void ConnectionDescriptor::SetAttached(bool state) -{ - bAttached = state; -} - - -/********************************** -ConnectionDescriptor::SetWatchOnly -***********************************/ - -void ConnectionDescriptor::SetWatchOnly(bool watching) -{ - bWatchOnly = watching; - _UpdateEvents(); -} - - -/********************************* -ConnectionDescriptor::HandleError -*********************************/ - -void ConnectionDescriptor::HandleError() -{ - if (bWatchOnly) { - // An EPOLLHUP | EPOLLIN condition will call Read() before HandleError(), in which case the - // socket is already detached and invalid, so we don't need to do anything. - if (MySocket == INVALID_SOCKET) return; - - // HandleError() is called on WatchOnly descriptors by the epoll reactor - // when it gets a EPOLLERR | EPOLLHUP. Usually this would show up as a readable and - // writable event on other reactors, so we have to fire those events ourselves. - if (bNotifyReadable) Read(); - if (bNotifyWritable) Write(); - } else { - ScheduleClose (false); - } -} - - -/*********************************** -ConnectionDescriptor::ScheduleClose -***********************************/ - -void ConnectionDescriptor::ScheduleClose (bool after_writing) -{ - if (bWatchOnly) - throw std::runtime_error ("cannot close 'watch only' connections"); - - EventableDescriptor::ScheduleClose(after_writing); -} - - -/*************************************** -ConnectionDescriptor::SetNotifyReadable -****************************************/ - -void ConnectionDescriptor::SetNotifyReadable(bool readable) -{ - if (!bWatchOnly) - throw std::runtime_error ("notify_readable must be on 'watch only' connections"); - - bNotifyReadable = readable; - _UpdateEvents(true, false); -} - - -/*************************************** -ConnectionDescriptor::SetNotifyWritable -****************************************/ - -void ConnectionDescriptor::SetNotifyWritable(bool writable) -{ - if (!bWatchOnly) - throw std::runtime_error ("notify_writable must be on 'watch only' connections"); - - bNotifyWritable = writable; - _UpdateEvents(false, true); -} - - -/************************************** -ConnectionDescriptor::SendOutboundData -**************************************/ - -int ConnectionDescriptor::SendOutboundData (const char *data, unsigned long length) -{ - if (bWatchOnly) - throw std::runtime_error ("cannot send data on a 'watch only' connection"); - - if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)(GetOutboundDataSize() + length) > MaxOutboundBufSize) - ProxiedFrom->Pause(); - - #ifdef WITH_SSL - if (SslBox) { - if (length > 0) { - unsigned long writed = 0; - char *p = (char*)data; - - while (writed < length) { - int to_write = SSLBOX_INPUT_CHUNKSIZE; - int remaining = length - writed; - - if (remaining < SSLBOX_INPUT_CHUNKSIZE) - to_write = remaining; - - int w = SslBox->PutPlaintext (p, to_write); - if (w < 0) { - ScheduleClose (false); - }else - _DispatchCiphertext(); - - p += to_write; - writed += to_write; - } - } - // TODO: What's the correct return value? - return 1; // That's a wild guess, almost certainly wrong. - } - else - #endif - return _SendRawOutboundData (data, length); -} - - - -/****************************************** -ConnectionDescriptor::_SendRawOutboundData -******************************************/ - -int ConnectionDescriptor::_SendRawOutboundData (const char *data, unsigned long length) -{ - /* This internal method is called to schedule bytes that - * will be sent out to the remote peer. - * It's not directly accessed by the caller, who hits ::SendOutboundData, - * which may or may not filter or encrypt the caller's data before - * sending it here. - */ - - // Highly naive and incomplete implementation. - // There's no throttle for runaways (which should abort only this connection - // and not the whole process), and no coalescing of small pages. - // (Well, not so bad, small pages are coalesced in ::Write) - - if (IsCloseScheduled()) - return 0; - // 25Mar10: Ignore 0 length packets as they are not meaningful in TCP (as opposed to UDP) - // and can cause the assert(nbytes>0) to fail when OutboundPages has a bunch of 0 length pages. - if (length == 0) - return 0; - - if (!data && (length > 0)) - throw std::runtime_error ("bad outbound data"); - char *buffer = (char *) malloc (length + 1); - if (!buffer) - throw std::runtime_error ("no allocation for outbound data"); - - memcpy (buffer, data, length); - buffer [length] = 0; - OutboundPages.push_back (OutboundPage (buffer, length)); - OutboundDataSize += length; - - _UpdateEvents(false, true); - - return length; -} - - - -/*********************************** -ConnectionDescriptor::SelectForRead -***********************************/ - -bool ConnectionDescriptor::SelectForRead() -{ - /* A connection descriptor is always scheduled for read, - * UNLESS it's in a pending-connect state. - * On Linux, unlike Unix, a nonblocking socket on which - * connect has been called, does NOT necessarily select - * both readable and writable in case of error. - * The socket will select writable when the disposition - * of the connect is known. On the other hand, a socket - * which successfully connects and selects writable may - * indeed have some data available on it, so it will - * select readable in that case, violating expectations! - * So we will not poll for readability until the socket - * is known to be in a connected state. - */ - - if (bPaused) - return false; - else if (bConnectPending) - return false; - else if (bWatchOnly) - return bNotifyReadable ? true : false; - else - return true; -} - - -/************************************ -ConnectionDescriptor::SelectForWrite -************************************/ - -bool ConnectionDescriptor::SelectForWrite() -{ - /* Cf the notes under SelectForRead. - * In a pending-connect state, we ALWAYS select for writable. - * In a normal state, we only select for writable when we - * have outgoing data to send. - */ - - if (bPaused) - return false; - else if (bConnectPending) - return true; - else if (bWatchOnly) - return bNotifyWritable ? true : false; - else - return (GetOutboundDataSize() > 0); -} - -/*************************** -ConnectionDescriptor::Pause -***************************/ - -bool ConnectionDescriptor::Pause() -{ - if (bWatchOnly) - throw std::runtime_error ("cannot pause/resume 'watch only' connections, set notify readable/writable instead"); - - bool old = bPaused; - bPaused = true; - _UpdateEvents(); - return old == false; -} - -/**************************** -ConnectionDescriptor::Resume -****************************/ - -bool ConnectionDescriptor::Resume() -{ - if (bWatchOnly) - throw std::runtime_error ("cannot pause/resume 'watch only' connections, set notify readable/writable instead"); - - bool old = bPaused; - bPaused = false; - _UpdateEvents(); - return old == true; -} - -/************************** -ConnectionDescriptor::Read -**************************/ - -void ConnectionDescriptor::Read() -{ - /* Read and dispatch data on a socket that has selected readable. - * It's theoretically possible to get and dispatch incoming data on - * a socket that has already been scheduled for closing or close-after-writing. - * In those cases, we'll leave it up the to protocol handler to "do the - * right thing" (which probably means to ignore the incoming data). - * - * 22Aug06: Chris Ochs reports that on FreeBSD, it's possible to come - * here with the socket already closed, after the process receives - * a ctrl-C signal (not sure if that's TERM or INT on BSD). The application - * was one in which network connections were doing a lot of interleaved reads - * and writes. - * Since we always write before reading (in order to keep the outbound queues - * as light as possible), I think what happened is that an interrupt caused - * the socket to be closed in ConnectionDescriptor::Write. We'll then - * come here in the same pass through the main event loop, and won't get - * cleaned up until immediately after. - * We originally asserted that the socket was valid when we got here. - * To deal properly with the possibility that we are closed when we get here, - * I removed the assert. HOWEVER, the potential for an infinite loop scares me, - * so even though this is really clunky, I added a flag to assert that we never - * come here more than once after being closed. (FCianfrocca) - */ - - SOCKET sd = GetSocket(); - //assert (sd != INVALID_SOCKET); (original, removed 22Aug06) - if (sd == INVALID_SOCKET) { - assert (!bReadAttemptedAfterClose); - bReadAttemptedAfterClose = true; - return; - } - - if (bWatchOnly) { - if (bNotifyReadable && EventCallback) - (*EventCallback)(GetBinding(), EM_CONNECTION_NOTIFY_READABLE, NULL, 0); - return; - } - - LastActivity = MyEventMachine->GetCurrentLoopTime(); - - int total_bytes_read = 0; - char readbuffer [16 * 1024 + 1]; - - for (int i=0; i < 10; i++) { - // Don't read just one buffer and then move on. This is faster - // if there is a lot of incoming. - // But don't read indefinitely. Give other sockets a chance to run. - // NOTICE, we're reading one less than the buffer size. - // That's so we can put a guard byte at the end of what we send - // to user code. - - - int r = read (sd, readbuffer, sizeof(readbuffer) - 1); -#ifdef OS_WIN32 - int e = WSAGetLastError(); -#else - int e = errno; -#endif - //cerr << ""; - - if (r > 0) { - total_bytes_read += r; - - // Add a null-terminator at the the end of the buffer - // that we will send to the callback. - // DO NOT EVER CHANGE THIS. We want to explicitly allow users - // to be able to depend on this behavior, so they will have - // the option to do some things faster. Additionally it's - // a security guard against buffer overflows. - readbuffer [r] = 0; - _DispatchInboundData (readbuffer, r); - if (bPaused) - break; - } - else if (r == 0) { - break; - } - else { - #ifdef OS_UNIX - if ((e != EINPROGRESS) && (e != EWOULDBLOCK) && (e != EAGAIN) && (e != EINTR)) { - #endif - #ifdef OS_WIN32 - if ((e != WSAEINPROGRESS) && (e != WSAEWOULDBLOCK)) { - #endif - // 26Mar11: Previously, all read errors were assumed to be EWOULDBLOCK and ignored. - // Now, instead, we call Close() on errors like ECONNRESET and ENOTCONN. - UnbindReasonCode = e; - Close(); - break; - } else { - // Basically a would-block, meaning we've read everything there is to read. - break; - } - } - - } - - - if (total_bytes_read == 0) { - // If we read no data on a socket that selected readable, - // it generally means the other end closed the connection gracefully. - ScheduleClose (false); - //bCloseNow = true; - } - -} - - - -/****************************************** -ConnectionDescriptor::_DispatchInboundData -******************************************/ - -#ifdef WITH_SSL -void ConnectionDescriptor::_DispatchInboundData (const char *buffer, unsigned long size) -{ - if (SslBox) { - SslBox->PutCiphertext (buffer, size); - - int s; - char B [2048]; - while ((s = SslBox->GetPlaintext (B, sizeof(B) - 1)) > 0) { - _CheckHandshakeStatus(); - B [s] = 0; - _GenericInboundDispatch(B, s); - } - - // If our SSL handshake had a problem, shut down the connection. - if (s == -2) { - #ifndef EPROTO // OpenBSD does not have EPROTO - #define EPROTO EINTR - #endif - #ifdef OS_UNIX - UnbindReasonCode = EPROTO; - #endif - #ifdef OS_WIN32 - UnbindReasonCode = WSAECONNABORTED; - #endif - ScheduleClose(false); - return; - } - - _CheckHandshakeStatus(); - _DispatchCiphertext(); - } - else { - _GenericInboundDispatch(buffer, size); - } -} -#else -void ConnectionDescriptor::_DispatchInboundData (const char *buffer, unsigned long size) -{ - _GenericInboundDispatch(buffer, size); -} -#endif - - - -/******************************************* -ConnectionDescriptor::_CheckHandshakeStatus -*******************************************/ - -void ConnectionDescriptor::_CheckHandshakeStatus() -{ - #ifdef WITH_SSL - if (SslBox && (!bHandshakeSignaled) && SslBox->IsHandshakeCompleted()) { - bHandshakeSignaled = true; - if (EventCallback) - (*EventCallback)(GetBinding(), EM_SSL_HANDSHAKE_COMPLETED, NULL, 0); - } - #endif -} - - - -/*************************** -ConnectionDescriptor::Write -***************************/ - -void ConnectionDescriptor::Write() -{ - /* A socket which is in a pending-connect state will select - * writable when the disposition of the connect is known. - * At that point, check to be sure there are no errors, - * and if none, then promote the socket out of the pending - * state. - * TODO: I haven't figured out how Windows signals errors on - * unconnected sockets. Maybe it does the untraditional but - * logical thing and makes the socket selectable for error. - * If so, it's unsupported here for the time being, and connect - * errors will have to be caught by the timeout mechanism. - */ - - if (bConnectPending) { - int error; - socklen_t len; - len = sizeof(error); - #ifdef OS_UNIX - int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, &error, &len); - #endif - #ifdef OS_WIN32 - int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, (char*)&error, &len); - #endif - if ((o == 0) && (error == 0)) { - if (EventCallback) - (*EventCallback)(GetBinding(), EM_CONNECTION_COMPLETED, "", 0); - - // 5May09: Moved epoll/kqueue read/write arming into SetConnectPending, so it can be called - // from EventMachine_t::AttachFD as well. - SetConnectPending (false); - } - else { - if (o == 0) - UnbindReasonCode = error; - ScheduleClose (false); - //bCloseNow = true; - } - } - else { - - if (bNotifyWritable) { - if (EventCallback) - (*EventCallback)(GetBinding(), EM_CONNECTION_NOTIFY_WRITABLE, NULL, 0); - - _UpdateEvents(false, true); - return; - } - - assert(!bWatchOnly); - - /* 5May09: Kqueue bugs on OSX cause one extra writable event to fire even though we're using - EV_ONESHOT. We ignore this extra event once, but only the first time. If it happens again, - we should fall through to the assert(nbytes>0) failure to catch any EM bugs which might cause - ::Write to be called in a busy-loop. - */ - #ifdef HAVE_KQUEUE - if (MyEventMachine->GetPoller() == Poller_Kqueue) { - if (OutboundDataSize == 0 && !bGotExtraKqueueEvent) { - bGotExtraKqueueEvent = true; - return; - } else if (OutboundDataSize > 0) { - bGotExtraKqueueEvent = false; - } - } - #endif - - _WriteOutboundData(); - } -} - - -/**************************************** -ConnectionDescriptor::_WriteOutboundData -****************************************/ - -void ConnectionDescriptor::_WriteOutboundData() -{ - /* This is a helper function called by ::Write. - * It's possible for a socket to select writable and then no longer - * be writable by the time we get around to writing. The kernel might - * have used up its available output buffers between the select call - * and when we get here. So this condition is not an error. - * - * 20Jul07, added the same kind of protection against an invalid socket - * that is at the top of ::Read. Not entirely how this could happen in - * real life (connection-reset from the remote peer, perhaps?), but I'm - * doing it to address some reports of crashing under heavy loads. - */ - - SOCKET sd = GetSocket(); - //assert (sd != INVALID_SOCKET); - if (sd == INVALID_SOCKET) { - assert (!bWriteAttemptedAfterClose); - bWriteAttemptedAfterClose = true; - return; - } - - LastActivity = MyEventMachine->GetCurrentLoopTime(); - size_t nbytes = 0; - - #ifdef HAVE_WRITEV - int iovcnt = OutboundPages.size(); - // Max of 16 outbound pages at a time - if (iovcnt > 16) iovcnt = 16; - - iovec iov[16]; - - for(int i = 0; i < iovcnt; i++){ - OutboundPage *op = &(OutboundPages[i]); - #ifdef CC_SUNWspro - // TODO: The void * cast works fine on Solaris 11, but - // I don't know at what point that changed from older Solaris. - iov[i].iov_base = (char *)(op->Buffer + op->Offset); - #else - iov[i].iov_base = (void *)(op->Buffer + op->Offset); - #endif - iov[i].iov_len = op->Length - op->Offset; - - nbytes += iov[i].iov_len; - } - #else - char output_buffer [16 * 1024]; - - while ((OutboundPages.size() > 0) && (nbytes < sizeof(output_buffer))) { - OutboundPage *op = &(OutboundPages[0]); - if ((nbytes + op->Length - op->Offset) < sizeof (output_buffer)) { - memcpy (output_buffer + nbytes, op->Buffer + op->Offset, op->Length - op->Offset); - nbytes += (op->Length - op->Offset); - op->Free(); - OutboundPages.pop_front(); - } - else { - int len = sizeof(output_buffer) - nbytes; - memcpy (output_buffer + nbytes, op->Buffer + op->Offset, len); - op->Offset += len; - nbytes += len; - } - } - #endif - - // We should never have gotten here if there were no data to write, - // so assert that as a sanity check. - // Don't bother to make sure nbytes is less than output_buffer because - // if it were we probably would have crashed already. - assert (nbytes > 0); - - assert (GetSocket() != INVALID_SOCKET); - #ifdef HAVE_WRITEV - int bytes_written = writev (GetSocket(), iov, iovcnt); - #else - int bytes_written = write (GetSocket(), output_buffer, nbytes); - #endif - - bool err = false; -#ifdef OS_WIN32 - int e = WSAGetLastError(); -#else - int e = errno; -#endif - if (bytes_written < 0) { - err = true; - bytes_written = 0; - } - - assert (bytes_written >= 0); - OutboundDataSize -= bytes_written; - - if (ProxiedFrom && MaxOutboundBufSize && (unsigned int)GetOutboundDataSize() < MaxOutboundBufSize && ProxiedFrom->IsPaused()) - ProxiedFrom->Resume(); - - #ifdef HAVE_WRITEV - if (!err) { - unsigned int sent = bytes_written; - std::deque::iterator op = OutboundPages.begin(); - - for (int i = 0; i < iovcnt; i++) { - if (iov[i].iov_len <= sent) { - // Sent this page in full, free it. - op->Free(); - OutboundPages.pop_front(); - - sent -= iov[i].iov_len; - } else { - // Sent part (or none) of this page, increment offset to send the remainder - op->Offset += sent; - break; - } - - // Shouldn't be possible run out of pages before the loop ends - assert(op != OutboundPages.end()); - *op++; - } - } - #else - if ((size_t)bytes_written < nbytes) { - int len = nbytes - bytes_written; - char *buffer = (char*) malloc (len + 1); - if (!buffer) - throw std::runtime_error ("bad alloc throwing back data"); - memcpy (buffer, output_buffer + bytes_written, len); - buffer [len] = 0; - OutboundPages.push_front (OutboundPage (buffer, len)); - } - #endif - - _UpdateEvents(false, true); - - if (err) { - #ifdef OS_UNIX - if ((e != EINPROGRESS) && (e != EWOULDBLOCK) && (e != EINTR)) { - #endif - #ifdef OS_WIN32 - if ((e != WSAEINPROGRESS) && (e != WSAEWOULDBLOCK)) { - #endif - UnbindReasonCode = e; - Close(); - } - } -} - - -/*************************************** -ConnectionDescriptor::ReportErrorStatus -***************************************/ - -int ConnectionDescriptor::ReportErrorStatus() -{ - if (MySocket == INVALID_SOCKET) { - return -1; - } - - int error; - socklen_t len; - len = sizeof(error); - #ifdef OS_UNIX - int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, &error, &len); - #endif - #ifdef OS_WIN32 - int o = getsockopt (GetSocket(), SOL_SOCKET, SO_ERROR, (char*)&error, &len); - #endif - if ((o == 0) && (error == 0)) - return 0; - else if (o == 0) - return error; - else - return -1; -} - - -/****************************** -ConnectionDescriptor::StartTls -******************************/ - -#ifdef WITH_SSL -void ConnectionDescriptor::StartTls() -{ - if (SslBox) - throw std::runtime_error ("SSL/TLS already running on connection"); - - SslBox = new SslBox_t (bIsServer, PrivateKeyFilename, CertChainFilename, bSslVerifyPeer, bSslFailIfNoPeerCert, SniHostName, CipherList, EcdhCurve, DhParam, Protocols, GetBinding()); - _DispatchCiphertext(); - -} -#else -void ConnectionDescriptor::StartTls() -{ - throw std::runtime_error ("Encryption not available on this event-machine"); -} -#endif - - -/********************************* -ConnectionDescriptor::SetTlsParms -*********************************/ - -#ifdef WITH_SSL -void ConnectionDescriptor::SetTlsParms (const char *privkey_filename, const char *certchain_filename, bool verify_peer, bool fail_if_no_peer_cert, const char *sni_hostname, const char *cipherlist, const char *ecdh_curve, const char *dhparam, int protocols) -{ - if (SslBox) - throw std::runtime_error ("call SetTlsParms before calling StartTls"); - if (privkey_filename && *privkey_filename) - PrivateKeyFilename = privkey_filename; - if (certchain_filename && *certchain_filename) - CertChainFilename = certchain_filename; - bSslVerifyPeer = verify_peer; - bSslFailIfNoPeerCert = fail_if_no_peer_cert; - - if (sni_hostname && *sni_hostname) - SniHostName = sni_hostname; - if (cipherlist && *cipherlist) - CipherList = cipherlist; - if (ecdh_curve && *ecdh_curve) - EcdhCurve = ecdh_curve; - if (dhparam && *dhparam) - DhParam = dhparam; - - Protocols = protocols; -} -#else -void ConnectionDescriptor::SetTlsParms (const char *privkey_filename UNUSED, const char *certchain_filename UNUSED, bool verify_peer UNUSED, bool fail_if_no_peer_cert UNUSED, const char *sni_hostname UNUSED, const char *cipherlist UNUSED, const char *ecdh_curve UNUSED, const char *dhparam UNUSED, int protocols UNUSED) -{ - throw std::runtime_error ("Encryption not available on this event-machine"); -} -#endif - - -/********************************* -ConnectionDescriptor::GetPeerCert -*********************************/ - -#ifdef WITH_SSL -X509 *ConnectionDescriptor::GetPeerCert() -{ - if (!SslBox) - throw std::runtime_error ("SSL/TLS not running on this connection"); - return SslBox->GetPeerCert(); -} -#endif - - -/********************************* -ConnectionDescriptor::GetCipherBits -*********************************/ - -#ifdef WITH_SSL -int ConnectionDescriptor::GetCipherBits() -{ - if (!SslBox) - throw std::runtime_error ("SSL/TLS not running on this connection"); - return SslBox->GetCipherBits(); -} -#endif - - -/********************************* -ConnectionDescriptor::GetCipherName -*********************************/ - -#ifdef WITH_SSL -const char *ConnectionDescriptor::GetCipherName() -{ - if (!SslBox) - throw std::runtime_error ("SSL/TLS not running on this connection"); - return SslBox->GetCipherName(); -} -#endif - - -/********************************* -ConnectionDescriptor::GetCipherProtocol -*********************************/ - -#ifdef WITH_SSL -const char *ConnectionDescriptor::GetCipherProtocol() -{ - if (!SslBox) - throw std::runtime_error ("SSL/TLS not running on this connection"); - return SslBox->GetCipherProtocol(); -} -#endif - - -/********************************* -ConnectionDescriptor::GetSNIHostname -*********************************/ - -#ifdef WITH_SSL -const char *ConnectionDescriptor::GetSNIHostname() -{ - if (!SslBox) - throw std::runtime_error ("SSL/TLS not running on this connection"); - return SslBox->GetSNIHostname(); -} -#endif - - -/*********************************** -ConnectionDescriptor::VerifySslPeer -***********************************/ - -#ifdef WITH_SSL -bool ConnectionDescriptor::VerifySslPeer(const char *cert) -{ - bSslPeerAccepted = false; - - if (EventCallback) - (*EventCallback)(GetBinding(), EM_SSL_VERIFY, cert, strlen(cert)); - - return bSslPeerAccepted; -} -#endif - - -/*********************************** -ConnectionDescriptor::AcceptSslPeer -***********************************/ - -#ifdef WITH_SSL -void ConnectionDescriptor::AcceptSslPeer() -{ - bSslPeerAccepted = true; -} -#endif - - -/***************************************** -ConnectionDescriptor::_DispatchCiphertext -*****************************************/ - -#ifdef WITH_SSL -void ConnectionDescriptor::_DispatchCiphertext() -{ - assert (SslBox); - - - char BigBuf [SSLBOX_OUTPUT_CHUNKSIZE]; - bool did_work; - - do { - did_work = false; - - // try to drain ciphertext - while (SslBox->CanGetCiphertext()) { - int r = SslBox->GetCiphertext (BigBuf, sizeof(BigBuf)); - assert (r > 0); - _SendRawOutboundData (BigBuf, r); - did_work = true; - } - - // Pump the SslBox, in case it has queued outgoing plaintext - // This will return >0 if data was written, - // 0 if no data was written, and <0 if there was a fatal error. - bool pump; - do { - pump = false; - int w = SslBox->PutPlaintext (NULL, 0); - if (w > 0) { - did_work = true; - pump = true; - } - else if (w < 0) - ScheduleClose (false); - } while (pump); - - // try to put plaintext. INCOMPLETE, doesn't belong here? - // In SendOutboundData, we're spooling plaintext directly - // into SslBox. That may be wrong, we may need to buffer it - // up here! - /* - const char *ptr; - int ptr_length; - while (OutboundPlaintext.GetPage (&ptr, &ptr_length)) { - assert (ptr && (ptr_length > 0)); - int w = SslMachine.PutPlaintext (ptr, ptr_length); - if (w > 0) { - OutboundPlaintext.DiscardBytes (w); - did_work = true; - } - else - break; - } - */ - - } while (did_work); - -} -#endif - - - -/******************************* -ConnectionDescriptor::Heartbeat -*******************************/ - -void ConnectionDescriptor::Heartbeat() -{ - /* Only allow a certain amount of time to go by while waiting - * for a pending connect. If it expires, then kill the socket. - * For a connected socket, close it if its inactivity timer - * has expired. - */ - - if (bConnectPending) { - if ((MyEventMachine->GetCurrentLoopTime() - CreatedAt) >= PendingConnectTimeout) { - UnbindReasonCode = ETIMEDOUT; - ScheduleClose (false); - //bCloseNow = true; - } - } - else { - if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout)) { - UnbindReasonCode = ETIMEDOUT; - ScheduleClose (false); - //bCloseNow = true; - } - } -} - - -/**************************************** -LoopbreakDescriptor::LoopbreakDescriptor -****************************************/ - -LoopbreakDescriptor::LoopbreakDescriptor (SOCKET sd, EventMachine_t *parent_em): - EventableDescriptor (sd, parent_em) -{ - /* This is really bad and ugly. Change someday if possible. - * We have to know about an event-machine (probably the one that owns us), - * so we can pass newly-created connections to it. - */ - - bCallbackUnbind = false; - - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - #ifdef HAVE_KQUEUE - MyEventMachine->ArmKqueueReader (this); - #endif -} - - - - -/************************* -LoopbreakDescriptor::Read -*************************/ - -void LoopbreakDescriptor::Read() -{ - // TODO, refactor, this code is probably in the wrong place. - assert (MyEventMachine); - MyEventMachine->_ReadLoopBreaker(); -} - - -/************************** -LoopbreakDescriptor::Write -**************************/ - -void LoopbreakDescriptor::Write() -{ - // Why are we here? - throw std::runtime_error ("bad code path in loopbreak"); -} - -/************************************** -AcceptorDescriptor::AcceptorDescriptor -**************************************/ - -AcceptorDescriptor::AcceptorDescriptor (SOCKET sd, EventMachine_t *parent_em): - EventableDescriptor (sd, parent_em) -{ - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - #ifdef HAVE_KQUEUE - MyEventMachine->ArmKqueueReader (this); - #endif -} - - -/*************************************** -AcceptorDescriptor::~AcceptorDescriptor -***************************************/ - -AcceptorDescriptor::~AcceptorDescriptor() -{ -} - -/**************************************** -STATIC: AcceptorDescriptor::StopAcceptor -****************************************/ - -void AcceptorDescriptor::StopAcceptor (const uintptr_t binding) -{ - // TODO: This is something of a hack, or at least it's a static method of the wrong class. - AcceptorDescriptor *ad = dynamic_cast (Bindable_t::GetObject (binding)); - if (ad) - ad->ScheduleClose (false); - else - throw std::runtime_error ("failed to close nonexistent acceptor"); -} - - -/************************ -AcceptorDescriptor::Read -************************/ - -void AcceptorDescriptor::Read() -{ - /* Accept up to a certain number of sockets on the listening connection. - * Don't try to accept all that are present, because this would allow a DoS attack - * in which no data were ever read or written. We should accept more than one, - * if available, to keep the partially accepted sockets from backing up in the kernel. - */ - - /* Make sure we use non-blocking i/o on the acceptor socket, since we're selecting it - * for readability. According to Stevens UNP, it's possible for an acceptor to select readable - * and then block when we call accept. For example, the other end resets the connection after - * the socket selects readable and before we call accept. The kernel will remove the dead - * socket from the accept queue. If the accept queue is now empty, accept will block. - */ - - - struct sockaddr_in6 pin; - socklen_t addrlen = sizeof (pin); - int accept_count = EventMachine_t::GetSimultaneousAcceptCount(); - - for (int i=0; i < accept_count; i++) { -#if defined(HAVE_CONST_SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) - SOCKET sd = accept4 (GetSocket(), (struct sockaddr*)&pin, &addrlen, SOCK_CLOEXEC); - if (sd == INVALID_SOCKET) { - // We may be running in a kernel where - // SOCK_CLOEXEC is not supported - fall back: - sd = accept (GetSocket(), (struct sockaddr*)&pin, &addrlen); - } -#else - SOCKET sd = accept (GetSocket(), (struct sockaddr*)&pin, &addrlen); -#endif - if (sd == INVALID_SOCKET) { - // This breaks the loop when we've accepted everything on the kernel queue, - // up to 10 new connections. But what if the *first* accept fails? - // Does that mean anything serious is happening, beyond the situation - // described in the note above? - break; - } - - // Set the newly-accepted socket non-blocking and to close on exec. - // On Windows, this may fail because, weirdly, Windows inherits the non-blocking - // attribute that we applied to the acceptor socket into the accepted one. - if (!SetFdCloexec(sd) || !SetSocketNonblocking (sd)) { - //int val = fcntl (sd, F_GETFL, 0); - //if (fcntl (sd, F_SETFL, val | O_NONBLOCK) == -1) { - shutdown (sd, 1); - close (sd); - continue; - } - - // Disable slow-start (Nagle algorithm). Eventually make this configurable. - int one = 1; - setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof(one)); - - - ConnectionDescriptor *cd = new ConnectionDescriptor (sd, MyEventMachine); - if (!cd) - throw std::runtime_error ("no newly accepted connection"); - cd->SetServerMode(); - if (EventCallback) { - (*EventCallback) (GetBinding(), EM_CONNECTION_ACCEPTED, NULL, cd->GetBinding()); - } - #ifdef HAVE_EPOLL - cd->GetEpollEvent()->events = 0; - if (cd->SelectForRead()) - cd->GetEpollEvent()->events |= EPOLLIN; - if (cd->SelectForWrite()) - cd->GetEpollEvent()->events |= EPOLLOUT; - #endif - assert (MyEventMachine); - MyEventMachine->Add (cd); - #ifdef HAVE_KQUEUE - bKqueueArmWrite = cd->SelectForWrite(); - if (bKqueueArmWrite) - MyEventMachine->Modify (cd); - if (cd->SelectForRead()) - MyEventMachine->ArmKqueueReader (cd); - #endif - } - -} - - -/************************* -AcceptorDescriptor::Write -*************************/ - -void AcceptorDescriptor::Write() -{ - // Why are we here? - throw std::runtime_error ("bad code path in acceptor"); -} - - -/***************************** -AcceptorDescriptor::Heartbeat -*****************************/ - -void AcceptorDescriptor::Heartbeat() -{ - // No-op -} - - -/************************************** -DatagramDescriptor::DatagramDescriptor -**************************************/ - -DatagramDescriptor::DatagramDescriptor (SOCKET sd, EventMachine_t *parent_em): - EventableDescriptor (sd, parent_em), - OutboundDataSize (0) -{ - memset (&ReturnAddress, 0, sizeof(ReturnAddress)); - - /* Provisionally added 19Oct07. All datagram sockets support broadcasting. - * Until now, sending to a broadcast address would give EACCES (permission denied) - * on systems like Linux and BSD that require the SO_BROADCAST socket-option in order - * to accept a packet to a broadcast address. Solaris doesn't require it. I think - * Windows DOES require it but I'm not sure. - * - * Ruby does NOT do what we're doing here. In Ruby, you have to explicitly set SO_BROADCAST - * on a UDP socket in order to enable broadcasting. The reason for requiring the option - * in the first place is so that applications don't send broadcast datagrams by mistake. - * I imagine that could happen if a user of an application typed in an address that happened - * to be a broadcast address on that particular subnet. - * - * This is provisional because someone may eventually come up with a good reason not to - * do it for all UDP sockets. If that happens, then we'll need to add a usercode-level API - * to set the socket option, just like Ruby does. AND WE'LL ALSO BREAK CODE THAT DOESN'T - * EXPLICITLY SET THE OPTION. - */ - - int oval = 1; - setsockopt (GetSocket(), SOL_SOCKET, SO_BROADCAST, (char*)&oval, sizeof(oval)); - - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - #ifdef HAVE_KQUEUE - MyEventMachine->ArmKqueueReader (this); - #endif -} - - -/*************************************** -DatagramDescriptor::~DatagramDescriptor -***************************************/ - -DatagramDescriptor::~DatagramDescriptor() -{ - // Run down any stranded outbound data. - for (size_t i=0; i < OutboundPages.size(); i++) - OutboundPages[i].Free(); -} - - -/***************************** -DatagramDescriptor::Heartbeat -*****************************/ - -void DatagramDescriptor::Heartbeat() -{ - // Close it if its inactivity timer has expired. - - if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout)) - ScheduleClose (false); - //bCloseNow = true; -} - - -/************************ -DatagramDescriptor::Read -************************/ - -void DatagramDescriptor::Read() -{ - SOCKET sd = GetSocket(); - assert (sd != INVALID_SOCKET); - LastActivity = MyEventMachine->GetCurrentLoopTime(); - - // This is an extremely large read buffer. - // In many cases you wouldn't expect to get any more than 4K. - char readbuffer [16 * 1024]; - - for (int i=0; i < 10; i++) { - // Don't read just one buffer and then move on. This is faster - // if there is a lot of incoming. - // But don't read indefinitely. Give other sockets a chance to run. - // NOTICE, we're reading one less than the buffer size. - // That's so we can put a guard byte at the end of what we send - // to user code. - - struct sockaddr_in6 sin; - socklen_t slen = sizeof (sin); - memset (&sin, 0, slen); - - int r = recvfrom (sd, readbuffer, sizeof(readbuffer) - 1, 0, (struct sockaddr*)&sin, &slen); - //cerr << ""; - - // In UDP, a zero-length packet is perfectly legal. - if (r >= 0) { - - // Add a null-terminator at the the end of the buffer - // that we will send to the callback. - // DO NOT EVER CHANGE THIS. We want to explicitly allow users - // to be able to depend on this behavior, so they will have - // the option to do some things faster. Additionally it's - // a security guard against buffer overflows. - readbuffer [r] = 0; - - - // Set up a "temporary" return address so that callers can "reply" to us - // from within the callback we are about to invoke. That means that ordinary - // calls to "send_data_to_connection" (which is of course misnamed in this - // case) will result in packets being sent back to the same place that sent - // us this one. - // There is a different call (evma_send_datagram) for cases where the caller - // actually wants to send a packet somewhere else. - - memset (&ReturnAddress, 0, sizeof(ReturnAddress)); - memcpy (&ReturnAddress, &sin, slen); - - _GenericInboundDispatch(readbuffer, r); - - } - else { - // Basically a would-block, meaning we've read everything there is to read. - break; - } - - } - - -} - - -/************************* -DatagramDescriptor::Write -*************************/ - -void DatagramDescriptor::Write() -{ - /* It's possible for a socket to select writable and then no longer - * be writable by the time we get around to writing. The kernel might - * have used up its available output buffers between the select call - * and when we get here. So this condition is not an error. - * This code is very reminiscent of ConnectionDescriptor::_WriteOutboundData, - * but differs in the that the outbound data pages (received from the - * user) are _message-structured._ That is, we send each of them out - * one message at a time. - * TODO, we are currently suppressing the EMSGSIZE error!!! - */ - - SOCKET sd = GetSocket(); - assert (sd != INVALID_SOCKET); - LastActivity = MyEventMachine->GetCurrentLoopTime(); - - assert (OutboundPages.size() > 0); - - // Send out up to 10 packets, then cycle the machine. - for (int i = 0; i < 10; i++) { - if (OutboundPages.size() <= 0) - break; - OutboundPage *op = &(OutboundPages[0]); - - // The nasty cast to (char*) is needed because Windows is brain-dead. - int s = sendto (sd, (char*)op->Buffer, op->Length, 0, (struct sockaddr*)&(op->From), - (op->From.sin6_family == AF_INET6 ? sizeof (struct sockaddr_in6) : sizeof (struct sockaddr_in))); -#ifdef OS_WIN32 - int e = WSAGetLastError(); -#else - int e = errno; -#endif - - OutboundDataSize -= op->Length; - op->Free(); - OutboundPages.pop_front(); - - if (s == SOCKET_ERROR) { - #ifdef OS_UNIX - if ((e != EINPROGRESS) && (e != EWOULDBLOCK) && (e != EINTR)) { - #endif - #ifdef OS_WIN32 - if ((e != WSAEINPROGRESS) && (e != WSAEWOULDBLOCK)) { - #endif - UnbindReasonCode = e; - Close(); - break; - } - } - } - - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - if (SelectForWrite()) - EpollEvent.events |= EPOLLOUT; - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - #ifdef HAVE_KQUEUE - bKqueueArmWrite = SelectForWrite(); - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif -} - - -/********************************** -DatagramDescriptor::SelectForWrite -**********************************/ - -bool DatagramDescriptor::SelectForWrite() -{ - /* Changed 15Nov07, per bug report by Mark Zvillius. - * The outbound data size will be zero if there are zero-length outbound packets, - * so we now select writable in case the outbound page buffer is not empty. - * Note that the superclass ShouldDelete method still checks for outbound data size, - * which may be wrong. - */ - //return (GetOutboundDataSize() > 0); (Original) - return (OutboundPages.size() > 0); -} - - -/************************************ -DatagramDescriptor::SendOutboundData -************************************/ - -int DatagramDescriptor::SendOutboundData (const char *data, unsigned long length) -{ - // This is almost an exact clone of ConnectionDescriptor::_SendRawOutboundData. - // That means most of it could be factored to a common ancestor. Note that - // empty datagrams are meaningful, which isn't the case for TCP streams. - - if (IsCloseScheduled()) - return 0; - - if (!data && (length > 0)) - throw std::runtime_error ("bad outbound data"); - char *buffer = (char *) malloc (length + 1); - if (!buffer) - throw std::runtime_error ("no allocation for outbound data"); - memcpy (buffer, data, length); - buffer [length] = 0; - OutboundPages.push_back (OutboundPage (buffer, length, ReturnAddress)); - OutboundDataSize += length; - - #ifdef HAVE_EPOLL - EpollEvent.events = (EPOLLIN | EPOLLOUT); - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - #ifdef HAVE_KQUEUE - bKqueueArmWrite = true; - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - - return length; -} - - -/**************************************** -DatagramDescriptor::SendOutboundDatagram -****************************************/ - -int DatagramDescriptor::SendOutboundDatagram (const char *data, unsigned long length, const char *address, int port) -{ - // This is an exact clone of ConnectionDescriptor::SendOutboundData. - // That means it needs to move to a common ancestor. - // TODO: Refactor this so there's no overlap with SendOutboundData. - - if (IsCloseScheduled()) - //if (bCloseNow || bCloseAfterWriting) - return 0; - - if (!address || !*address || !port) - return 0; - - struct sockaddr_in6 addr_here; - size_t addr_here_len = sizeof addr_here; - if (0 != EventMachine_t::name2address (address, port, SOCK_DGRAM, (struct sockaddr *)&addr_here, &addr_here_len)) - return -1; - - if (!data && (length > 0)) - throw std::runtime_error ("bad outbound data"); - char *buffer = (char *) malloc (length + 1); - if (!buffer) - throw std::runtime_error ("no allocation for outbound data"); - memcpy (buffer, data, length); - buffer [length] = 0; - OutboundPages.push_back (OutboundPage (buffer, length, addr_here)); - OutboundDataSize += length; - - #ifdef HAVE_EPOLL - EpollEvent.events = (EPOLLIN | EPOLLOUT); - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - #ifdef HAVE_KQUEUE - bKqueueArmWrite = true; - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - - return length; -} - - -/********************************************** -ConnectionDescriptor::GetCommInactivityTimeout -**********************************************/ - -uint64_t ConnectionDescriptor::GetCommInactivityTimeout() -{ - return InactivityTimeout / 1000; -} - - -/********************************************** -ConnectionDescriptor::SetCommInactivityTimeout -**********************************************/ - -int ConnectionDescriptor::SetCommInactivityTimeout (uint64_t value) -{ - InactivityTimeout = value * 1000; - MyEventMachine->QueueHeartbeat(this); - return 1; -} - -/******************************* -DatagramDescriptor::GetPeername -*******************************/ - -bool DatagramDescriptor::GetPeername (struct sockaddr *s, socklen_t *len) -{ - bool ok = false; - if (s) { - *len = sizeof(ReturnAddress); - memset (s, 0, sizeof(ReturnAddress)); - memcpy (s, &ReturnAddress, sizeof(ReturnAddress)); - ok = true; - } - return ok; -} - - -/******************************************** -DatagramDescriptor::GetCommInactivityTimeout -********************************************/ - -uint64_t DatagramDescriptor::GetCommInactivityTimeout() -{ - return InactivityTimeout / 1000; -} - -/******************************************** -DatagramDescriptor::SetCommInactivityTimeout -********************************************/ - -int DatagramDescriptor::SetCommInactivityTimeout (uint64_t value) -{ - if (value > 0) { - InactivityTimeout = value * 1000; - MyEventMachine->QueueHeartbeat(this); - return 1; - } - return 0; -} - - -/************************************ -InotifyDescriptor::InotifyDescriptor -*************************************/ - -InotifyDescriptor::InotifyDescriptor (EventMachine_t *em): - EventableDescriptor(0, em) -{ - bCallbackUnbind = false; - - #ifndef HAVE_INOTIFY - throw std::runtime_error("no inotify support on this system"); - #else - - int fd = inotify_init(); - if (fd == -1) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "unable to create inotify descriptor: %s", strerror(errno)); - throw std::runtime_error (buf); - } - - MySocket = fd; - SetSocketNonblocking(MySocket); - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - - #endif -} - - -/************************************* -InotifyDescriptor::~InotifyDescriptor -**************************************/ - -InotifyDescriptor::~InotifyDescriptor() -{ - close(MySocket); - MySocket = INVALID_SOCKET; -} - -/*********************** -InotifyDescriptor::Read -************************/ - -void InotifyDescriptor::Read() -{ - assert (MyEventMachine); - MyEventMachine->_ReadInotifyEvents(); -} - - -/************************ -InotifyDescriptor::Write -*************************/ - -void InotifyDescriptor::Write() -{ - throw std::runtime_error("bad code path in inotify"); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.h deleted file mode 100644 index 4d7f7d4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ed.h +++ /dev/null @@ -1,457 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: ed.h -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#ifndef __EventableDescriptor__H_ -#define __EventableDescriptor__H_ - - -class EventMachine_t; // forward reference -#ifdef WITH_SSL -class SslBox_t; // forward reference -#endif - -bool SetSocketNonblocking (SOCKET); -bool SetFdCloexec (int); - -/************************* -class EventableDescriptor -*************************/ - -class EventableDescriptor: public Bindable_t -{ - public: - EventableDescriptor (SOCKET, EventMachine_t*); - virtual ~EventableDescriptor() NO_EXCEPT_FALSE; - - SOCKET GetSocket() {return MySocket;} - void SetSocketInvalid() { MySocket = INVALID_SOCKET; } - void Close(); - - virtual void Read() = 0; - virtual void Write() = 0; - virtual void Heartbeat() = 0; - - // These methods tell us whether the descriptor - // should be selected or polled for read/write. - virtual bool SelectForRead() = 0; - virtual bool SelectForWrite() = 0; - - // are we scheduled for a close, or in an error state, or already closed? - bool ShouldDelete(); - // Do we have any data to write? This is used by ShouldDelete. - virtual int GetOutboundDataSize() {return 0;} - virtual bool IsWatchOnly(){ return bWatchOnly; } - - virtual void ScheduleClose (bool after_writing); - bool IsCloseScheduled(); - virtual void HandleError(){ ScheduleClose (false); } - - void SetEventCallback (EMCallback); - - virtual bool GetPeername (struct sockaddr*, socklen_t*) = 0; - virtual bool GetSockname (struct sockaddr*, socklen_t*) = 0; - virtual bool GetSubprocessPid (pid_t*) {return false;} - - virtual void StartTls() {} - virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int) {} - - #ifdef WITH_SSL - virtual X509 *GetPeerCert() {return NULL;} - virtual int GetCipherBits() {return -1;} - virtual const char *GetCipherName() {return NULL;} - virtual const char *GetCipherProtocol() {return NULL;} - virtual const char *GetSNIHostname() {return NULL;} - #endif - - virtual uint64_t GetCommInactivityTimeout() {return 0;} - virtual int SetCommInactivityTimeout (uint64_t) {return 0;} - uint64_t GetPendingConnectTimeout(); - int SetPendingConnectTimeout (uint64_t value); - uint64_t GetLastActivity() { return LastActivity; } - - #ifdef HAVE_EPOLL - struct epoll_event *GetEpollEvent() { return &EpollEvent; } - #endif - - #ifdef HAVE_KQUEUE - bool GetKqueueArmWrite() { return bKqueueArmWrite; } - #endif - - virtual void StartProxy(const uintptr_t, const unsigned long, const unsigned long); - virtual void StopProxy(); - virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; }; - virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long); - virtual int SendOutboundData(const char*,unsigned long){ return -1; } - virtual bool IsPaused(){ return bPaused; } - virtual bool Pause(){ bPaused = true; return bPaused; } - virtual bool Resume(){ bPaused = false; return bPaused; } - - void SetUnbindReasonCode(int code){ UnbindReasonCode = code; } - virtual int ReportErrorStatus(){ return 0; } - virtual bool IsConnectPending(){ return false; } - virtual uint64_t GetNextHeartbeat(); - - private: - bool bCloseNow; - bool bCloseAfterWriting; - - protected: - SOCKET MySocket; - bool bAttached; - bool bWatchOnly; - - EMCallback EventCallback; - void _GenericInboundDispatch (const char *buffer, unsigned long size); - bool _GenericGetPeername (struct sockaddr*, socklen_t*); - bool _GenericGetSockname (struct sockaddr*, socklen_t*); - - uint64_t CreatedAt; - bool bCallbackUnbind; - int UnbindReasonCode; - - unsigned long BytesToProxy; - EventableDescriptor *ProxyTarget; - EventableDescriptor *ProxiedFrom; - unsigned long ProxiedBytes; - - unsigned long MaxOutboundBufSize; - - #ifdef HAVE_EPOLL - struct epoll_event EpollEvent; - #endif - - #ifdef HAVE_KQUEUE - bool bKqueueArmWrite; - #endif - - EventMachine_t *MyEventMachine; - uint64_t PendingConnectTimeout; - uint64_t InactivityTimeout; - uint64_t LastActivity; - uint64_t NextHeartbeat; - bool bPaused; -}; - - - -/************************* -class LoopbreakDescriptor -*************************/ - -class LoopbreakDescriptor: public EventableDescriptor -{ - public: - LoopbreakDescriptor (SOCKET, EventMachine_t*); - virtual ~LoopbreakDescriptor() {} - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat() {} - - virtual bool SelectForRead() {return true;} - virtual bool SelectForWrite() {return false;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); } -}; - - -/************************** -class ConnectionDescriptor -**************************/ - -class ConnectionDescriptor: public EventableDescriptor -{ - public: - ConnectionDescriptor (SOCKET, EventMachine_t*); - virtual ~ConnectionDescriptor(); - - int SendOutboundData (const char*, unsigned long); - - void SetConnectPending (bool f); - virtual void ScheduleClose (bool after_writing); - virtual void HandleError(); - - void SetNotifyReadable (bool); - void SetNotifyWritable (bool); - void SetAttached (bool); - void SetWatchOnly (bool); - - bool Pause(); - bool Resume(); - - bool IsNotifyReadable(){ return bNotifyReadable; } - bool IsNotifyWritable(){ return bNotifyWritable; } - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat(); - - virtual bool SelectForRead(); - virtual bool SelectForWrite(); - - // Do we have any data to write? This is used by ShouldDelete. - virtual int GetOutboundDataSize() {return OutboundDataSize;} - - virtual void StartTls(); - virtual void SetTlsParms (const char *, const char *, bool, bool, const char *, const char *, const char *, const char *, int); - - #ifdef WITH_SSL - virtual X509 *GetPeerCert(); - virtual int GetCipherBits(); - virtual const char *GetCipherName(); - virtual const char *GetCipherProtocol(); - virtual const char *GetSNIHostname(); - virtual bool VerifySslPeer(const char*); - virtual void AcceptSslPeer(); - #endif - - void SetServerMode() {bIsServer = true;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); } - - virtual uint64_t GetCommInactivityTimeout(); - virtual int SetCommInactivityTimeout (uint64_t value); - - virtual int ReportErrorStatus(); - virtual bool IsConnectPending(){ return bConnectPending; } - - protected: - struct OutboundPage { - OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {} - void Free() {if (Buffer) free (const_cast(Buffer)); } - const char *Buffer; - int Length; - int Offset; - }; - - protected: - bool bConnectPending; - - bool bNotifyReadable; - bool bNotifyWritable; - - bool bReadAttemptedAfterClose; - bool bWriteAttemptedAfterClose; - - std::deque OutboundPages; - int OutboundDataSize; - - #ifdef WITH_SSL - SslBox_t *SslBox; - std::string CertChainFilename; - std::string PrivateKeyFilename; - std::string CipherList; - std::string EcdhCurve; - std::string DhParam; - int Protocols; - bool bHandshakeSignaled; - bool bSslVerifyPeer; - bool bSslFailIfNoPeerCert; - std::string SniHostName; - bool bSslPeerAccepted; - #endif - - #ifdef HAVE_KQUEUE - bool bGotExtraKqueueEvent; - #endif - - bool bIsServer; - - private: - void _UpdateEvents(); - void _UpdateEvents(bool, bool); - void _WriteOutboundData(); - void _DispatchInboundData (const char *buffer, unsigned long size); - void _DispatchCiphertext(); - int _SendRawOutboundData (const char *buffer, unsigned long size); - void _CheckHandshakeStatus(); - -}; - - -/************************ -class DatagramDescriptor -************************/ - -class DatagramDescriptor: public EventableDescriptor -{ - public: - DatagramDescriptor (SOCKET, EventMachine_t*); - virtual ~DatagramDescriptor(); - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat(); - - virtual bool SelectForRead() {return true;} - virtual bool SelectForWrite(); - - int SendOutboundData (const char*, unsigned long); - int SendOutboundDatagram (const char*, unsigned long, const char*, int); - - // Do we have any data to write? This is used by ShouldDelete. - virtual int GetOutboundDataSize() {return OutboundDataSize;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len); - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }; - - virtual uint64_t GetCommInactivityTimeout(); - virtual int SetCommInactivityTimeout (uint64_t value); - - protected: - struct OutboundPage { - OutboundPage (const char *b, int l, struct sockaddr_in6 f, int o=0): Buffer(b), Length(l), Offset(o), From(f) {} - void Free() {if (Buffer) free (const_cast(Buffer)); } - const char *Buffer; - int Length; - int Offset; - struct sockaddr_in6 From; - }; - - std::deque OutboundPages; - int OutboundDataSize; - - struct sockaddr_in6 ReturnAddress; -}; - - -/************************ -class AcceptorDescriptor -************************/ - -class AcceptorDescriptor: public EventableDescriptor -{ - public: - AcceptorDescriptor (SOCKET, EventMachine_t*); - virtual ~AcceptorDescriptor(); - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat(); - - virtual bool SelectForRead() {return true;} - virtual bool SelectForWrite() {return false;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); }; - - static void StopAcceptor (const uintptr_t binding); -}; - -/******************** -class PipeDescriptor -********************/ - -#ifdef OS_UNIX -class PipeDescriptor: public EventableDescriptor -{ - public: - PipeDescriptor (SOCKET, pid_t, EventMachine_t*); - virtual ~PipeDescriptor() NO_EXCEPT_FALSE; - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat(); - - virtual bool SelectForRead(); - virtual bool SelectForWrite(); - - int SendOutboundData (const char*, unsigned long); - virtual int GetOutboundDataSize() {return OutboundDataSize;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); } - - virtual bool GetSubprocessPid (pid_t*); - - protected: - struct OutboundPage { - OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {} - void Free() {if (Buffer) free (const_cast(Buffer)); } - const char *Buffer; - int Length; - int Offset; - }; - - protected: - bool bReadAttemptedAfterClose; - - std::deque OutboundPages; - int OutboundDataSize; - - pid_t SubprocessPid; - - private: - void _DispatchInboundData (const char *buffer, int size); -}; -#endif // OS_UNIX - - -/************************ -class KeyboardDescriptor -************************/ - -class KeyboardDescriptor: public EventableDescriptor -{ - public: - KeyboardDescriptor (EventMachine_t*); - virtual ~KeyboardDescriptor(); - - virtual void Read(); - virtual void Write(); - virtual void Heartbeat(); - - virtual bool SelectForRead() {return true;} - virtual bool SelectForWrite() {return false;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return _GenericGetPeername (s, len); } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return _GenericGetSockname (s, len); } - - protected: - bool bReadAttemptedAfterClose; - - private: - void _DispatchInboundData (const char *buffer, int size); -}; - - -/*********************** -class InotifyDescriptor -************************/ - -class InotifyDescriptor: public EventableDescriptor -{ - public: - InotifyDescriptor (EventMachine_t*); - virtual ~InotifyDescriptor(); - - void Read(); - void Write(); - - virtual void Heartbeat() {} - virtual bool SelectForRead() {return true;} - virtual bool SelectForWrite() {return false;} - - virtual bool GetPeername (struct sockaddr* s, socklen_t* len) { return false; } - virtual bool GetSockname (struct sockaddr* s, socklen_t* len) { return false; } -}; - -#endif // __EventableDescriptor__H_ diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.cpp deleted file mode 100644 index 2907485..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.cpp +++ /dev/null @@ -1,2396 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: em.cpp -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -// THIS ENTIRE FILE WILL EVENTUALLY BE FOR UNIX BUILDS ONLY. -//#ifdef OS_UNIX - -#include "project.h" - -/* The numer of max outstanding timers was once a const enum defined in em.h. - * Now we define it here so that users can change its value if necessary. - */ -static unsigned int MaxOutstandingTimers = 100000; - -/* The number of accept() done at once in a single tick when the acceptor - * socket becomes readable. - */ -static unsigned int SimultaneousAcceptCount = 10; - -/* Internal helper to create a socket with SOCK_CLOEXEC set, and fall - * back to fcntl'ing it if the headers/runtime don't support it. - */ -SOCKET EmSocket (int domain, int type, int protocol) -{ - SOCKET sd; -#ifdef HAVE_SOCKET_CLOEXEC - sd = socket (domain, type | SOCK_CLOEXEC, protocol); - if (sd == INVALID_SOCKET) { - sd = socket (domain, type, protocol); - if (sd < 0) { - return sd; - } - SetFdCloexec(sd); - } -#else - sd = socket (domain, type, protocol); - if (sd == INVALID_SOCKET) { - return sd; - } - SetFdCloexec(sd); -#endif - return sd; -} - - -/*************************************** -STATIC EventMachine_t::GetMaxTimerCount -***************************************/ - -int EventMachine_t::GetMaxTimerCount() -{ - return MaxOutstandingTimers; -} - - -/*************************************** -STATIC EventMachine_t::SetMaxTimerCount -***************************************/ - -void EventMachine_t::SetMaxTimerCount (int count) -{ - /* Allow a user to increase the maximum number of outstanding timers. - * If this gets "too high" (a metric that is of course platform dependent), - * bad things will happen like performance problems and possible overuse - * of memory. - * The actual timer mechanism is very efficient so it's hard to know what - * the practical max, but 100,000 shouldn't be too problematical. - */ - if (count < 100) - count = 100; - MaxOutstandingTimers = count; -} - -int EventMachine_t::GetSimultaneousAcceptCount() -{ - return SimultaneousAcceptCount; -} - -void EventMachine_t::SetSimultaneousAcceptCount (int count) -{ - if (count < 1) - count = 1; - SimultaneousAcceptCount = count; -} - - -/****************************** -EventMachine_t::EventMachine_t -******************************/ - -EventMachine_t::EventMachine_t (EMCallback event_callback, Poller_t poller): - NumCloseScheduled (0), - HeartbeatInterval(2000000), - EventCallback (event_callback), - LoopBreakerReader (INVALID_SOCKET), - LoopBreakerWriter (INVALID_SOCKET), - bTerminateSignalReceived (false), - Poller (poller), - epfd (-1), - kqfd (-1) - #ifdef HAVE_INOTIFY - , inotify (NULL) - #endif -{ - // Default time-slice is just smaller than one hundred mills. - Quantum.tv_sec = 0; - Quantum.tv_usec = 90000; - - // Override the requested poller back to default if needed. - #if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE) - Poller = Poller_Default; - #endif - - /* Initialize monotonic timekeeping on OS X before the first call to GetRealTime */ - #ifdef OS_DARWIN - (void) mach_timebase_info(&mach_timebase); - #endif - - #ifdef OS_WIN32 - TickCountTickover = 0; - LastTickCount = 0; - #endif - - // Make sure the current loop time is sane, in case we do any initializations of - // objects before we start running. - _UpdateTime(); - - /* We initialize the network library here (only on Windows of course) - * and initialize "loop breakers." Our destructor also does some network-level - * cleanup. There's thus an implicit assumption that any given instance of EventMachine_t - * will only call ::Run once. Is that a good assumption? Should we move some of these - * inits and de-inits into ::Run? - */ - #ifdef OS_WIN32 - WSADATA w; - WSAStartup (MAKEWORD (1, 1), &w); - #endif - - _InitializeLoopBreaker(); - SelectData = new SelectData_t(); -} - - -/******************************* -EventMachine_t::~EventMachine_t -*******************************/ - -EventMachine_t::~EventMachine_t() -{ - // Run down descriptors - size_t i; - for (i = 0; i < NewDescriptors.size(); i++) - delete NewDescriptors[i]; - for (i = 0; i < Descriptors.size(); i++) - delete Descriptors[i]; - - close (LoopBreakerReader); - close (LoopBreakerWriter); - - // Remove any file watch descriptors - while(!Files.empty()) { - std::map::iterator f = Files.begin(); - UnwatchFile (f->first); - } - - if (epfd != -1) - close (epfd); - if (kqfd != -1) - close (kqfd); - - delete SelectData; -} - - -/**************************** -EventMachine_t::ScheduleHalt -****************************/ - -void EventMachine_t::ScheduleHalt() -{ - /* This is how we stop the machine. - * This can be called by clients. Signal handlers will probably - * set the global flag. - * For now this means there can only be one EventMachine ever running at a time. - * - * IMPORTANT: keep this light, fast, and async-safe. Don't do anything frisky in here, - * because it may be called from signal handlers invoked from code that we don't - * control. At this writing (20Sep06), EM does NOT install any signal handlers of - * its own. - * - * We need a FAQ. And one of the questions is: how do I stop EM when Ctrl-C happens? - * The answer is to call evma_stop_machine, which calls here, from a SIGINT handler. - */ - bTerminateSignalReceived = true; - - /* Signal the loopbreaker so we break out of long-running select/epoll/kqueue and - * notice the halt boolean is set. Signalling the loopbreaker also uses a single - * signal-safe syscall. - */ - SignalLoopBreaker(); -} - -bool EventMachine_t::Stopping() -{ - return bTerminateSignalReceived; -} - -/******************************* -EventMachine_t::SetTimerQuantum -*******************************/ - -void EventMachine_t::SetTimerQuantum (int interval) -{ - /* We get a timer-quantum expressed in milliseconds. - */ - - if ((interval < 5) || (interval > 5*60*1000)) - throw std::runtime_error ("invalid timer-quantum"); - - Quantum.tv_sec = interval / 1000; - Quantum.tv_usec = (interval % 1000) * 1000; -} - - -/************************************* -(STATIC) EventMachine_t::SetuidString -*************************************/ - -#ifdef OS_UNIX -void EventMachine_t::SetuidString (const char *username) -{ - /* This method takes a caller-supplied username and tries to setuid - * to that user. There is no meaningful implementation (and no error) - * on Windows. On Unix, a failure to setuid the caller-supplied string - * causes a fatal abort, because presumably the program is calling here - * in order to fulfill a security requirement. If we fail silently, - * the user may continue to run with too much privilege. - * - * TODO, we need to decide on and document a way of generating C++ level errors - * that can be wrapped in documented Ruby exceptions, so users can catch - * and handle them. And distinguish it from errors that we WON'T let the Ruby - * user catch (like security-violations and resource-overallocation). - * A setuid failure here would be in the latter category. - */ - - if (!username || !*username) - throw std::runtime_error ("setuid_string failed: no username specified"); - - errno = 0; - struct passwd *p = getpwnam (username); - if (!p) { - if (errno) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "setuid_string failed: %s", strerror(errno)); - throw std::runtime_error (buf); - } else { - throw std::runtime_error ("setuid_string failed: unknown username"); - } - } - - if (setuid (p->pw_uid) != 0) - throw std::runtime_error ("setuid_string failed: no setuid"); - - // Success. -} -#else -void EventMachine_t::SetuidString (const char *username UNUSED) { } -#endif - -/**************************************** -(STATIC) EventMachine_t::SetRlimitNofile -****************************************/ - -#ifdef OS_UNIX -int EventMachine_t::SetRlimitNofile (int nofiles) -{ - struct rlimit rlim; - getrlimit (RLIMIT_NOFILE, &rlim); - if (nofiles >= 0) { - rlim.rlim_cur = nofiles; - if ((unsigned int)nofiles > rlim.rlim_max) - rlim.rlim_max = nofiles; - setrlimit (RLIMIT_NOFILE, &rlim); - // ignore the error return, for now at least. - // TODO, emit an error message someday when we have proper debug levels. - } - getrlimit (RLIMIT_NOFILE, &rlim); - return rlim.rlim_cur; -} -#else -int EventMachine_t::SetRlimitNofile (int nofiles UNUSED) { return 0; } -#endif - -/********************************* -EventMachine_t::SignalLoopBreaker -*********************************/ - -void EventMachine_t::SignalLoopBreaker() -{ - #ifdef OS_UNIX - (void)write (LoopBreakerWriter, "", 1); - #endif - #ifdef OS_WIN32 - sendto (LoopBreakerReader, "", 0, 0, (struct sockaddr*)&(LoopBreakerTarget), sizeof(LoopBreakerTarget)); - #endif -} - - -/************************************** -EventMachine_t::_InitializeLoopBreaker -**************************************/ - -void EventMachine_t::_InitializeLoopBreaker() -{ - /* A "loop-breaker" is a socket-descriptor that we can write to in order - * to break the main select loop. Primarily useful for things running on - * threads other than the main EM thread, so they can trigger processing - * of events that arise exogenously to the EM. - * Keep the loop-breaker pipe out of the main descriptor set, otherwise - * its events will get passed on to user code. - */ - - #ifdef OS_UNIX - int fd[2]; -#if defined (HAVE_CLOEXEC) && defined (HAVE_PIPE2) - int pipestatus = pipe2(fd, O_CLOEXEC); - if (pipestatus < 0) { - if (pipe(fd)) - throw std::runtime_error (strerror(errno)); - } -#else - if (pipe (fd)) - throw std::runtime_error (strerror(errno)); -#endif - if (!SetFdCloexec(fd[0]) || !SetFdCloexec(fd[1])) - throw std::runtime_error (strerror(errno)); - - LoopBreakerWriter = fd[1]; - LoopBreakerReader = fd[0]; - - /* 16Jan11: Make sure the pipe is non-blocking, so more than 65k loopbreaks - * in one tick do not fill up the pipe and block the process on write() */ - SetSocketNonblocking (LoopBreakerWriter); - #endif - - #ifdef OS_WIN32 - SOCKET sd = EmSocket (AF_INET, SOCK_DGRAM, 0); - if (sd == INVALID_SOCKET) - throw std::runtime_error ("no loop breaker socket"); - SetSocketNonblocking (sd); - - memset (&LoopBreakerTarget, 0, sizeof(LoopBreakerTarget)); - LoopBreakerTarget.sin_family = AF_INET; - LoopBreakerTarget.sin_addr.s_addr = inet_addr ("127.0.0.1"); - - srand ((int)time(NULL)); - int i; - for (i=0; i < 100; i++) { - int r = (rand() % 10000) + 20000; - LoopBreakerTarget.sin_port = htons (r); - if (bind (sd, (struct sockaddr*)&LoopBreakerTarget, sizeof(LoopBreakerTarget)) == 0) - break; - } - - if (i == 100) - throw std::runtime_error ("no loop breaker"); - LoopBreakerReader = sd; - #endif - - #ifdef HAVE_EPOLL - if (Poller == Poller_Epoll) { - epfd = epoll_create (MaxEpollDescriptors); - if (epfd == -1) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "unable to create epoll descriptor: %s", strerror(errno)); - throw std::runtime_error (buf); - } - int cloexec = fcntl (epfd, F_GETFD, 0); - assert (cloexec >= 0); - cloexec |= FD_CLOEXEC; - fcntl (epfd, F_SETFD, cloexec); - - assert (LoopBreakerReader >= 0); - LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this); - assert (ld); - Add (ld); - } - #endif - - #ifdef HAVE_KQUEUE - if (Poller == Poller_Kqueue) { - kqfd = kqueue(); - if (kqfd == -1) { - char buf[200]; - snprintf (buf, sizeof(buf)-1, "unable to create kqueue descriptor: %s", strerror(errno)); - throw std::runtime_error (buf); - } - // cloexec not needed. By definition, kqueues are not carried across forks. - - assert (LoopBreakerReader >= 0); - LoopbreakDescriptor *ld = new LoopbreakDescriptor (LoopBreakerReader, this); - assert (ld); - Add (ld); - } - #endif -} - -/*************************** -EventMachine_t::_UpdateTime -***************************/ - -void EventMachine_t::_UpdateTime() -{ - MyCurrentLoopTime = GetRealTime(); -} - -/*************************** -EventMachine_t::GetRealTime -***************************/ - -// Two great writeups of cross-platform monotonic time are at: -// http://www.python.org/dev/peps/pep-0418 -// http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking -// Uncomment the #pragma messages to confirm which compile-time option was used -uint64_t EventMachine_t::GetRealTime() -{ - uint64_t current_time; - - #if defined(HAVE_CONST_CLOCK_MONOTONIC_RAW) - // #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC_RAW" - // Linux 2.6.28 and above - struct timespec tv; - clock_gettime (CLOCK_MONOTONIC_RAW, &tv); - current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000)); - - #elif defined(HAVE_CONST_CLOCK_MONOTONIC) - // #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC" - // Linux, FreeBSD 5.0 and above, Solaris 8 and above, OpenBSD, NetBSD, DragonflyBSD - struct timespec tv; - clock_gettime (CLOCK_MONOTONIC, &tv); - current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000)); - - #elif defined(HAVE_GETHRTIME) - // #pragma message "GetRealTime: gethrtime" - // Solaris and HP-UX - current_time = (uint64_t)gethrtime() / 1000; - - #elif defined(OS_DARWIN) - // #pragma message "GetRealTime: mach_absolute_time" - // Mac OS X - // https://developer.apple.com/library/mac/qa/qa1398/_index.html - current_time = mach_absolute_time() * mach_timebase.numer / mach_timebase.denom / 1000; - - #elif defined(OS_UNIX) - // #pragma message "GetRealTime: gettimeofday" - // Unix fallback - struct timeval tv; - gettimeofday (&tv, NULL); - current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)(tv.tv_usec)); - - #elif defined(OS_WIN32) - // #pragma message "GetRealTime: GetTickCount" - // Future improvement: use GetTickCount64 in Windows Vista / Server 2008 - unsigned tick = GetTickCount(); - if (tick < LastTickCount) - TickCountTickover += 1; - LastTickCount = tick; - current_time = ((uint64_t)TickCountTickover << 32) + (uint64_t)tick; - current_time *= 1000; // convert to microseconds - - #else - // #pragma message "GetRealTime: time" - // Universal fallback - current_time = (uint64_t)time(NULL) * 1000000LL; - #endif - - return current_time; -} - -/*********************************** -EventMachine_t::_DispatchHeartbeats -***********************************/ - -void EventMachine_t::_DispatchHeartbeats() -{ - // Store the first processed heartbeat descriptor and bail out if - // we see it again. This fixes an infinite loop in case the system time - // is changed out from underneath MyCurrentLoopTime. - const EventableDescriptor *head = NULL; - - while (true) { - std::multimap::iterator i = Heartbeats.begin(); - if (i == Heartbeats.end()) - break; - if (i->first > MyCurrentLoopTime) - break; - - EventableDescriptor *ed = i->second; - if (ed == head) - break; - - ed->Heartbeat(); - QueueHeartbeat(ed); - - if (head == NULL) - head = ed; - } -} - -/****************************** -EventMachine_t::QueueHeartbeat -******************************/ - -void EventMachine_t::QueueHeartbeat(EventableDescriptor *ed) -{ - uint64_t heartbeat = ed->GetNextHeartbeat(); - - if (heartbeat) { - #ifndef HAVE_MAKE_PAIR - Heartbeats.insert (std::multimap::value_type (heartbeat, ed)); - #else - Heartbeats.insert (std::make_pair (heartbeat, ed)); - #endif - } -} - -/****************************** -EventMachine_t::ClearHeartbeat -******************************/ - -void EventMachine_t::ClearHeartbeat(uint64_t key, EventableDescriptor* ed) -{ - std::multimap::iterator it; - std::pair::iterator,std::multimap::iterator> ret; - ret = Heartbeats.equal_range (key); - for (it = ret.first; it != ret.second; ++it) { - if (it->second == ed) { - Heartbeats.erase (it); - break; - } - } -} - -/******************* -EventMachine_t::Run -*******************/ - -void EventMachine_t::Run() -{ - while (RunOnce()) ; -} - -/*********************** -EventMachine_t::RunOnce -***********************/ - -bool EventMachine_t::RunOnce() -{ - _UpdateTime(); - _RunTimers(); - - /* _Add must precede _Modify because the same descriptor might - * be on both lists during the same pass through the machine, - * and to modify a descriptor before adding it would fail. - */ - _AddNewDescriptors(); - _ModifyDescriptors(); - - switch (Poller) { - case Poller_Epoll: - _RunEpollOnce(); - break; - case Poller_Kqueue: - _RunKqueueOnce(); - break; - case Poller_Default: - _RunSelectOnce(); - break; - } - - _DispatchHeartbeats(); - _CleanupSockets(); - - if (bTerminateSignalReceived) - return false; - - return true; -} - - -/***************************** -EventMachine_t::_RunEpollOnce -*****************************/ - -void EventMachine_t::_RunEpollOnce() -{ - #ifdef HAVE_EPOLL - assert (epfd != -1); - int s; - - timeval tv = _TimeTilNextEvent(); - - #ifdef BUILD_FOR_RUBY - int ret = 0; - - #ifdef HAVE_RB_WAIT_FOR_SINGLE_FD - if ((ret = rb_wait_for_single_fd(epfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) { - #else - fd_set fdreads; - - FD_ZERO(&fdreads); - FD_SET(epfd, &fdreads); - - if ((ret = rb_thread_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) { - #endif - if (ret == -1) { - assert(errno != EINVAL); - assert(errno != EBADF); - } - return; - } - - TRAP_BEG; - s = epoll_wait (epfd, epoll_events, MaxEvents, 0); - TRAP_END; - #else - int duration = 0; - duration = duration + (tv.tv_sec * 1000); - duration = duration + (tv.tv_usec / 1000); - s = epoll_wait (epfd, epoll_events, MaxEvents, duration); - #endif - - if (s > 0) { - for (int i=0; i < s; i++) { - EventableDescriptor *ed = (EventableDescriptor*) epoll_events[i].data.ptr; - - if (ed->IsWatchOnly() && ed->GetSocket() == INVALID_SOCKET) - continue; - - assert(ed->GetSocket() != INVALID_SOCKET); - - if (epoll_events[i].events & EPOLLIN) - ed->Read(); - if (epoll_events[i].events & EPOLLOUT) - ed->Write(); - if (epoll_events[i].events & (EPOLLERR | EPOLLHUP)) - ed->HandleError(); - } - } - else if (s < 0) { - // epoll_wait can fail on error in a handful of ways. - // If this happens, then wait for a little while to avoid busy-looping. - // If the error was EINTR, we probably caught SIGCHLD or something, - // so keep the wait short. - timeval tv = {0, ((errno == EINTR) ? 5 : 50) * 1000}; - EmSelect (0, NULL, NULL, NULL, &tv); - } - #else - throw std::runtime_error ("epoll is not implemented on this platform"); - #endif -} - - -/****************************** -EventMachine_t::_RunKqueueOnce -******************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::_RunKqueueOnce() -{ - assert (kqfd != -1); - int k; - - timeval tv = _TimeTilNextEvent(); - - struct timespec ts; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - - #ifdef BUILD_FOR_RUBY - int ret = 0; - - #ifdef HAVE_RB_WAIT_FOR_SINGLE_FD - if ((ret = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) { - #else - fd_set fdreads; - - FD_ZERO(&fdreads); - FD_SET(kqfd, &fdreads); - - if ((ret = rb_thread_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) { - #endif - if (ret == -1) { - assert(errno != EINVAL); - assert(errno != EBADF); - } - return; - } - - TRAP_BEG; - ts.tv_sec = ts.tv_nsec = 0; - k = kevent (kqfd, NULL, 0, Karray, MaxEvents, &ts); - TRAP_END; - #else - k = kevent (kqfd, NULL, 0, Karray, MaxEvents, &ts); - #endif - - struct kevent *ke = Karray; - while (k > 0) { - switch (ke->filter) - { - case EVFILT_VNODE: - _HandleKqueueFileEvent (ke); - break; - - case EVFILT_PROC: - _HandleKqueuePidEvent (ke); - break; - - case EVFILT_READ: - case EVFILT_WRITE: - EventableDescriptor *ed = (EventableDescriptor*) (ke->udata); - assert (ed); - - if (ed->IsWatchOnly() && ed->GetSocket() == INVALID_SOCKET) - break; - - if (ke->filter == EVFILT_READ) - ed->Read(); - else if (ke->filter == EVFILT_WRITE) - ed->Write(); - else - std::cerr << "Discarding unknown kqueue event " << ke->filter << std::endl; - - break; - } - - --k; - ++ke; - } - - // TODO, replace this with rb_thread_blocking_region for 1.9 builds. - #ifdef BUILD_FOR_RUBY - if (!rb_thread_alone()) { - rb_thread_schedule(); - } - #endif -} -#else -void EventMachine_t::_RunKqueueOnce() -{ - throw std::runtime_error ("kqueue is not implemented on this platform"); -} -#endif - - -/********************************* -EventMachine_t::_TimeTilNextEvent -*********************************/ - -timeval EventMachine_t::_TimeTilNextEvent() -{ - // 29jul11: Changed calculation base from MyCurrentLoopTime to the - // real time. As MyCurrentLoopTime is set at the beginning of an - // iteration and this calculation is done at the end, evenmachine - // will potentially oversleep by the amount of time the iteration - // took to execute. - uint64_t next_event = 0; - uint64_t current_time = GetRealTime(); - - if (!Heartbeats.empty()) { - std::multimap::iterator heartbeats = Heartbeats.begin(); - next_event = heartbeats->first; - } - - if (!Timers.empty()) { - std::multimap::iterator timers = Timers.begin(); - if (next_event == 0 || timers->first < next_event) - next_event = timers->first; - } - - if (!NewDescriptors.empty() || !ModifiedDescriptors.empty()) { - next_event = current_time; - } - - timeval tv; - - if (NumCloseScheduled > 0 || bTerminateSignalReceived) { - tv.tv_sec = tv.tv_usec = 0; - } else if (next_event == 0) { - tv = Quantum; - } else { - if (next_event > current_time) { - uint64_t duration = next_event - current_time; - tv.tv_sec = duration / 1000000; - tv.tv_usec = duration % 1000000; - } else { - tv.tv_sec = tv.tv_usec = 0; - } - } - - return tv; -} - -/******************************* -EventMachine_t::_CleanupSockets -*******************************/ - -void EventMachine_t::_CleanupSockets() -{ - // TODO, rip this out and only delete the descriptors we know have died, - // rather than traversing the whole list. - // Modified 05Jan08 per suggestions by Chris Heath. It's possible that - // an EventableDescriptor will have a descriptor value of -1. That will - // happen if EventableDescriptor::Close was called on it. In that case, - // don't call epoll_ctl to remove the socket's filters from the epoll set. - // According to the epoll docs, this happens automatically when the - // descriptor is closed anyway. This is different from the case where - // the socket has already been closed but the descriptor in the ED object - // hasn't yet been set to INVALID_SOCKET. - // In kqueue, closing a descriptor automatically removes its event filters. - int i, j; - int nSockets = Descriptors.size(); - for (i=0, j=0; i < nSockets; i++) { - EventableDescriptor *ed = Descriptors[i]; - assert (ed); - if (ed->ShouldDelete()) { - #ifdef HAVE_EPOLL - if (Poller == Poller_Epoll) { - assert (epfd != -1); - if (ed->GetSocket() != INVALID_SOCKET) { - int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent()); - // ENOENT or EBADF are not errors because the socket may be already closed when we get here. - if (e && (errno != ENOENT) && (errno != EBADF) && (errno != EPERM)) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to delete epoll event: %s", strerror(errno)); - throw std::runtime_error (buf); - } - } - ModifiedDescriptors.erase(ed); - } - #endif - delete ed; - } - else - Descriptors [j++] = ed; - } - while ((size_t)j < Descriptors.size()) - Descriptors.pop_back(); -} - -/********************************* -EventMachine_t::_ModifyEpollEvent -*********************************/ - -#ifdef HAVE_EPOLL -void EventMachine_t::_ModifyEpollEvent (EventableDescriptor *ed) -{ - if (Poller == Poller_Epoll) { - assert (epfd != -1); - assert (ed); - assert (ed->GetSocket() != INVALID_SOCKET); - int e = epoll_ctl (epfd, EPOLL_CTL_MOD, ed->GetSocket(), ed->GetEpollEvent()); - if (e) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to modify epoll event: %s", strerror(errno)); - throw std::runtime_error (buf); - } - } -} -#else -void EventMachine_t::_ModifyEpollEvent (EventableDescriptor *ed UNUSED) { } -#endif - - -/************************** -SelectData_t::SelectData_t -**************************/ - -SelectData_t::SelectData_t() -{ - maxsocket = 0; - rb_fd_init (&fdreads); - rb_fd_init (&fdwrites); - rb_fd_init (&fderrors); -} - -SelectData_t::~SelectData_t() -{ - rb_fd_term (&fdreads); - rb_fd_term (&fdwrites); - rb_fd_term (&fderrors); -} - -#ifdef BUILD_FOR_RUBY -/***************** -_SelectDataSelect -*****************/ - -#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) -static VALUE _SelectDataSelect (void *v) -{ - SelectData_t *sd = (SelectData_t*)v; - sd->nSockets = rb_fd_select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv)); - return Qnil; -} -#endif - -/********************* -SelectData_t::_Select -*********************/ - -int SelectData_t::_Select() -{ - #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) - // added in ruby 1.9.3 - rb_thread_call_without_gvl ((void *(*)(void *))_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0); - return nSockets; - #elif defined(HAVE_TBR) - // added in ruby 1.9.1, deprecated in ruby 2.0.0 - rb_thread_blocking_region (_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0); - return nSockets; - #else - return EmSelect (maxsocket+1, &fdreads, &fdwrites, &fderrors, &tv); - #endif -} -#endif - -void SelectData_t::_Clear() -{ - maxsocket = 0; - rb_fd_zero (&fdreads); - rb_fd_zero (&fdwrites); - rb_fd_zero (&fderrors); -} - -/****************************** -EventMachine_t::_RunSelectOnce -******************************/ - -void EventMachine_t::_RunSelectOnce() -{ - // Crank the event machine once. - // If there are no descriptors to process, then sleep - // for a few hundred mills to avoid busy-looping. - // This is based on a select loop. Alternately provide epoll - // if we know we're running on a 2.6 kernel. - // epoll will be effective if we provide it as an alternative, - // however it has the same problem interoperating with Ruby - // threads that select does. - - // Get ready for select() - SelectData->_Clear(); - - // Always read the loop-breaker reader. - // Changed 23Aug06, provisionally implemented for Windows with a UDP socket - // running on localhost with a randomly-chosen port. (*Puke*) - // Windows has a version of the Unix pipe() library function, but it doesn't - // give you back descriptors that are selectable. - rb_fd_set (LoopBreakerReader, &(SelectData->fdreads)); - if (SelectData->maxsocket < LoopBreakerReader) - SelectData->maxsocket = LoopBreakerReader; - - // prepare the sockets for reading and writing - size_t i; - for (i = 0; i < Descriptors.size(); i++) { - EventableDescriptor *ed = Descriptors[i]; - assert (ed); - SOCKET sd = ed->GetSocket(); - if (ed->IsWatchOnly() && sd == INVALID_SOCKET) - continue; - assert (sd != INVALID_SOCKET); - - if (ed->SelectForRead()) - rb_fd_set (sd, &(SelectData->fdreads)); - if (ed->SelectForWrite()) - rb_fd_set (sd, &(SelectData->fdwrites)); - - #ifdef OS_WIN32 - /* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable. - Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html - */ - if (ed->IsConnectPending()) - rb_fd_set (sd, &(SelectData->fderrors)); - #endif - - if (SelectData->maxsocket < sd) - SelectData->maxsocket = sd; - } - - - { // read and write the sockets - //timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000. - //timeval tv = Quantum; - SelectData->tv = _TimeTilNextEvent(); - int s = SelectData->_Select(); - //rb_thread_blocking_region(xxx,(void*)&SelectData,RUBY_UBF_IO,0); - //int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv)); - //int s = SelectData.nSockets; - if (s > 0) { - /* Changed 01Jun07. We used to handle the Loop-breaker right here. - * Now we do it AFTER all the regular descriptors. There's an - * incredibly important and subtle reason for this. Code on - * loop breakers is sometimes used to cause the reactor core to - * cycle (for example, to allow outbound network buffers to drain). - * If a loop-breaker handler reschedules itself (say, after determining - * that the write buffers are still too full), then it will execute - * IMMEDIATELY if _ReadLoopBreaker is done here instead of after - * the other descriptors are processed. That defeats the whole purpose. - */ - for (i=0; i < Descriptors.size(); i++) { - EventableDescriptor *ed = Descriptors[i]; - assert (ed); - SOCKET sd = ed->GetSocket(); - if (ed->IsWatchOnly() && sd == INVALID_SOCKET) - continue; - assert (sd != INVALID_SOCKET); - - if (rb_fd_isset (sd, &(SelectData->fdwrites))) { - // Double-check SelectForWrite() still returns true. If not, one of the callbacks must have - // modified some value since we checked SelectForWrite() earlier in this method. - if (ed->SelectForWrite()) - ed->Write(); - } - if (rb_fd_isset (sd, &(SelectData->fdreads))) - ed->Read(); - if (rb_fd_isset (sd, &(SelectData->fderrors))) - ed->HandleError(); - } - - if (rb_fd_isset (LoopBreakerReader, &(SelectData->fdreads))) - _ReadLoopBreaker(); - } - else if (s < 0) { - switch (errno) { - case EBADF: - _CleanBadDescriptors(); - break; - case EINVAL: - throw std::runtime_error ("Somehow EM passed an invalid nfds or invalid timeout to select(2), please report this!"); - break; - default: - // select can fail on error in a handful of ways. - // If this happens, then wait for a little while to avoid busy-looping. - // If the error was EINTR, we probably caught SIGCHLD or something, - // so keep the wait short. - timeval tv = {0, ((errno == EINTR) ? 5 : 50) * 1000}; - EmSelect (0, NULL, NULL, NULL, &tv); - } - } - } -} - -void EventMachine_t::_CleanBadDescriptors() -{ - size_t i; - - for (i = 0; i < Descriptors.size(); i++) { - EventableDescriptor *ed = Descriptors[i]; - if (ed->ShouldDelete()) - continue; - - SOCKET sd = ed->GetSocket(); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - - rb_fdset_t fds; - rb_fd_init(&fds); - rb_fd_set(sd, &fds); - - int ret = rb_fd_select(sd + 1, &fds, NULL, NULL, &tv); - rb_fd_term(&fds); - - if (ret == -1) { - if (errno == EBADF) - ed->ScheduleClose(false); - } - } -} - -/******************************** -EventMachine_t::_ReadLoopBreaker -********************************/ - -void EventMachine_t::_ReadLoopBreaker() -{ - /* The loop breaker has selected readable. - * Read it ONCE (it may block if we try to read it twice) - * and send a loop-break event back to user code. - */ - char buffer [1024]; - (void)read (LoopBreakerReader, buffer, sizeof(buffer)); - if (EventCallback) - (*EventCallback)(0, EM_LOOPBREAK_SIGNAL, "", 0); -} - - -/************************** -EventMachine_t::_RunTimers -**************************/ - -void EventMachine_t::_RunTimers() -{ - // These are caller-defined timer handlers. - // We rely on the fact that multimaps sort by their keys to avoid - // inspecting the whole list every time we come here. - // Just keep inspecting and processing the list head until we hit - // one that hasn't expired yet. - - while (true) { - std::multimap::iterator i = Timers.begin(); - if (i == Timers.end()) - break; - if (i->first > MyCurrentLoopTime) - break; - if (EventCallback) - (*EventCallback) (0, EM_TIMER_FIRED, NULL, i->second.GetBinding()); - Timers.erase (i); - } -} - - - -/*********************************** -EventMachine_t::InstallOneshotTimer -***********************************/ - -const uintptr_t EventMachine_t::InstallOneshotTimer (uint64_t milliseconds) -{ - if (Timers.size() > MaxOutstandingTimers) - return false; - - uint64_t fire_at = GetRealTime(); - fire_at += ((uint64_t)milliseconds) * 1000LL; - - Timer_t t; - #ifndef HAVE_MAKE_PAIR - std::multimap::iterator i = Timers.insert (std::multimap::value_type (fire_at, t)); - #else - std::multimap::iterator i = Timers.insert (std::make_pair (fire_at, t)); - #endif - return i->second.GetBinding(); -} - - -/******************************* -EventMachine_t::ConnectToServer -*******************************/ - -const uintptr_t EventMachine_t::ConnectToServer (const char *bind_addr, int bind_port, const char *server, int port) -{ - /* We want to spend no more than a few seconds waiting for a connection - * to a remote host. So we use a nonblocking connect. - * Linux disobeys the usual rules for nonblocking connects. - * Per Stevens (UNP p.410), you expect a nonblocking connect to select - * both readable and writable on error, and not to return EINPROGRESS - * if the connect can be fulfilled immediately. Linux violates both - * of these expectations. - * Any kind of nonblocking connect on Linux returns EINPROGRESS. - * The socket will then return writable when the disposition of the - * connect is known, but it will not also be readable in case of - * error! Weirdly, it will be readable in case there is data to read!!! - * (Which can happen with protocols like SSH and SMTP.) - * I suppose if you were so inclined you could consider this logical, - * but it's not the way Unix has historically done it. - * So we ignore the readable flag and read getsockopt to see if there - * was an error connecting. A select timeout works as expected. - * In regard to getsockopt: Linux does the Berkeley-style thing, - * not the Solaris-style, and returns zero with the error code in - * the error parameter. - * Return the binding-text of the newly-created pending connection, - * or NULL if there was a problem. - */ - - if (!server || !*server || !port) - throw std::runtime_error ("invalid server or port"); - - struct sockaddr_storage bind_as; - size_t bind_as_len = sizeof bind_as; - int gai = name2address (server, port, SOCK_STREAM, (struct sockaddr *)&bind_as, &bind_as_len); - if (gai != 0) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to resolve address: %s", gai_strerror(gai)); - throw std::runtime_error (buf); - } - - SOCKET sd = EmSocket (bind_as.ss_family, SOCK_STREAM, 0); - if (sd == INVALID_SOCKET) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to create new socket: %s", strerror(errno)); - throw std::runtime_error (buf); - } - - // From here on, ALL error returns must close the socket. - // Set the new socket nonblocking. - if (!SetSocketNonblocking (sd)) { - close (sd); - throw std::runtime_error ("unable to set socket as non-blocking"); - } - // Disable slow-start (Nagle algorithm). - int one = 1; - setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char*) &one, sizeof(one)); - // Set reuseaddr to improve performance on restarts - setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char*) &one, sizeof(one)); - - if (bind_addr) { - struct sockaddr_storage bind_to; - size_t bind_to_len = sizeof bind_to; - gai = name2address (bind_addr, bind_port, SOCK_STREAM, (struct sockaddr *)&bind_to, &bind_to_len); - if (gai != 0) { - close (sd); - char buf [200]; - snprintf (buf, sizeof(buf)-1, "invalid bind address: %s", gai_strerror(gai)); - throw std::runtime_error (buf); - } - if (bind (sd, (struct sockaddr *)&bind_to, bind_to_len) < 0) { - close (sd); - throw std::runtime_error ("couldn't bind to address"); - } - } - - uintptr_t out = 0; - - #ifdef OS_UNIX - int e_reason = 0; - if (connect (sd, (struct sockaddr *)&bind_as, bind_as_len) == 0) { - // This is a connect success, which Linux appears - // never to give when the socket is nonblocking, - // even if the connection is intramachine or to - // localhost. - - /* Changed this branch 08Aug06. Evidently some kernels - * (FreeBSD for example) will actually return success from - * a nonblocking connect. This is a pretty simple case, - * just set up the new connection and clear the pending flag. - * Thanks to Chris Ochs for helping track this down. - * This branch never gets taken on Linux or (oddly) OSX. - * The original behavior was to throw an unimplemented, - * which the user saw as a fatal exception. Very unfriendly. - * - * Tweaked 10Aug06. Even though the connect disposition is - * known, we still set the connect-pending flag. That way - * some needed initialization will happen in the ConnectionDescriptor. - * (To wit, the ConnectionCompleted event gets sent to the client.) - */ - ConnectionDescriptor *cd = new ConnectionDescriptor (sd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - cd->SetConnectPending (true); - Add (cd); - out = cd->GetBinding(); - } - else if (errno == EINPROGRESS) { - // Errno will generally always be EINPROGRESS, but on Linux - // we have to look at getsockopt to be sure what really happened. - int error = 0; - socklen_t len; - len = sizeof(error); - int o = getsockopt (sd, SOL_SOCKET, SO_ERROR, &error, &len); - if ((o == 0) && (error == 0)) { - // Here, there's no disposition. - // Put the connection on the stack and wait for it to complete - // or time out. - ConnectionDescriptor *cd = new ConnectionDescriptor (sd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - cd->SetConnectPending (true); - Add (cd); - out = cd->GetBinding(); - } else { - // Fall through to the !out case below. - e_reason = error; - } - } - else { - // The error from connect was something other then EINPROGRESS (EHOSTDOWN, etc). - // Fall through to the !out case below - e_reason = errno; - } - - if (!out) { - /* This could be connection refused or some such thing. - * We will come here on Linux if a localhost connection fails. - * Changed 16Jul06: Originally this branch was a no-op, and - * we'd drop down to the end of the method, close the socket, - * and return NULL, which would cause the caller to GET A - * FATAL EXCEPTION. Now we keep the socket around but schedule an - * immediate close on it, so the caller will get a close-event - * scheduled on it. This was only an issue for localhost connections - * to non-listening ports. We may eventually need to revise this - * revised behavior, in case it causes problems like making it hard - * for people to know that a failure occurred. - */ - ConnectionDescriptor *cd = new ConnectionDescriptor (sd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - cd->SetUnbindReasonCode (e_reason); - cd->ScheduleClose (false); - Add (cd); - out = cd->GetBinding(); - } - #endif - - #ifdef OS_WIN32 - if (connect (sd, (struct sockaddr *)&bind_as, bind_as_len) == 0) { - // This is a connect success, which Windows appears - // never to give when the socket is nonblocking, - // even if the connection is intramachine or to - // localhost. - throw std::runtime_error ("unimplemented"); - } - else if (WSAGetLastError() == WSAEWOULDBLOCK) { - // Here, there's no disposition. - // Windows appears not to surface refused connections or - // such stuff at this point. - // Put the connection on the stack and wait for it to complete - // or time out. - ConnectionDescriptor *cd = new ConnectionDescriptor (sd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - cd->SetConnectPending (true); - Add (cd); - out = cd->GetBinding(); - } - else { - // The error from connect was something other then WSAEWOULDBLOCK. - } - - #endif - - if (!out) - close (sd); - return out; -} - -/*********************************** -EventMachine_t::ConnectToUnixServer -***********************************/ - -#ifdef OS_UNIX -const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server) -{ - /* Connect to a Unix-domain server, which by definition is running - * on the same host. - * There is no meaningful implementation on Windows. - * There's no need to do a nonblocking connect, since the connection - * is always local and can always be fulfilled immediately. - */ - - uintptr_t out = 0; - - if (!server || !*server) - return 0; - - sockaddr_un pun; - memset (&pun, 0, sizeof(pun)); - pun.sun_family = AF_LOCAL; - - // You ordinarily expect the server name field to be at least 1024 bytes long, - // but on Linux it can be MUCH shorter. - if (strlen(server) >= sizeof(pun.sun_path)) - throw std::runtime_error ("unix-domain server name is too long"); - - - strcpy (pun.sun_path, server); - - SOCKET fd = EmSocket (AF_LOCAL, SOCK_STREAM, 0); - if (fd == INVALID_SOCKET) - return 0; - - // From here on, ALL error returns must close the socket. - // NOTE: At this point, the socket is still a blocking socket. - if (connect (fd, (struct sockaddr*)&pun, sizeof(pun)) != 0) { - close (fd); - return 0; - } - - // Set the newly-connected socket nonblocking. - if (!SetSocketNonblocking (fd)) { - close (fd); - return 0; - } - - // Set up a connection descriptor and add it to the event-machine. - // Observe, even though we know the connection status is connect-success, - // we still set the "pending" flag, so some needed initializations take - // place. - ConnectionDescriptor *cd = new ConnectionDescriptor (fd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - cd->SetConnectPending (true); - Add (cd); - out = cd->GetBinding(); - - if (!out) - close (fd); - - return out; -} -#else -const uintptr_t EventMachine_t::ConnectToUnixServer (const char *server UNUSED) -{ - throw std::runtime_error ("unix-domain connection unavailable on this platform"); -} -#endif - -/************************ -EventMachine_t::AttachFD -************************/ - -const uintptr_t EventMachine_t::AttachFD (SOCKET fd, bool watch_mode) -{ - #ifdef OS_UNIX - if (fcntl(fd, F_GETFL, 0) < 0) { - if (errno) { - throw std::runtime_error (strerror(errno)); - } else { - throw std::runtime_error ("invalid file descriptor"); - } - } - #endif - - #ifdef OS_WIN32 - // TODO: add better check for invalid file descriptors (see ioctlsocket or getsockopt) - if (fd == INVALID_SOCKET) - throw std::runtime_error ("invalid file descriptor"); - #endif - - {// Check for duplicate descriptors - size_t i; - for (i = 0; i < Descriptors.size(); i++) { - EventableDescriptor *ed = Descriptors[i]; - assert (ed); - if (ed->GetSocket() == fd) - throw std::runtime_error ("adding existing descriptor"); - } - - for (i = 0; i < NewDescriptors.size(); i++) { - EventableDescriptor *ed = NewDescriptors[i]; - assert (ed); - if (ed->GetSocket() == fd) - throw std::runtime_error ("adding existing new descriptor"); - } - } - - if (!watch_mode) - SetSocketNonblocking(fd); - - ConnectionDescriptor *cd = new ConnectionDescriptor (fd, this); - if (!cd) - throw std::runtime_error ("no connection allocated"); - - cd->SetAttached(true); - cd->SetWatchOnly(watch_mode); - cd->SetConnectPending (false); - - Add (cd); - - const uintptr_t out = cd->GetBinding(); - return out; -} - -/************************ -EventMachine_t::DetachFD -************************/ - -int EventMachine_t::DetachFD (EventableDescriptor *ed) -{ - if (!ed) - throw std::runtime_error ("detaching bad descriptor"); - - SOCKET fd = ed->GetSocket(); - - #ifdef HAVE_EPOLL - if (Poller == Poller_Epoll) { - if (ed->GetSocket() != INVALID_SOCKET) { - assert (epfd != -1); - int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent()); - // ENOENT or EBADF are not errors because the socket may be already closed when we get here. - if (e && (errno != ENOENT) && (errno != EBADF)) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to delete epoll event: %s", strerror(errno)); - throw std::runtime_error (buf); - } - } - } - #endif - - #ifdef HAVE_KQUEUE - if (Poller == Poller_Kqueue) { - // remove any read/write events for this fd - struct kevent k; -#ifdef __NetBSD__ - EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t)ed); -#else - EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, ed); -#endif - int t = kevent (kqfd, &k, 1, NULL, 0, NULL); - if (t < 0 && (errno != ENOENT) && (errno != EBADF)) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to delete kqueue event: %s", strerror(errno)); - throw std::runtime_error (buf); - } - } - #endif - - // Prevent the descriptor from being modified, in case DetachFD was called from a timer or next_tick - ModifiedDescriptors.erase (ed); - - // Prevent the descriptor from being added, in case DetachFD was called in the same tick as AttachFD - for (size_t i = 0; i < NewDescriptors.size(); i++) { - if (ed == NewDescriptors[i]) { - NewDescriptors.erase(NewDescriptors.begin() + i); - break; - } - } - - // Set MySocket = INVALID_SOCKET so ShouldDelete() is true (and the descriptor gets deleted and removed), - // and also to prevent anyone from calling close() on the detached fd - ed->SetSocketInvalid(); - - return fd; -} - -/************ -name2address -************/ - -int EventMachine_t::name2address (const char *server, int port, int socktype, struct sockaddr *addr, size_t *addr_len) -{ - if (!server || !*server) - server = "0.0.0.0"; - - struct addrinfo *ai; - struct addrinfo hints; - memset (&hints, 0, sizeof(hints)); - hints.ai_socktype = socktype; - hints.ai_family = AF_UNSPEC; - hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; - - char portstr[12]; - snprintf(portstr, sizeof(portstr), "%u", port); - - int gai = getaddrinfo (server, portstr, &hints, &ai); - if (gai == 0) { - assert (ai->ai_addrlen <= *addr_len); - memcpy (addr, ai->ai_addr, ai->ai_addrlen); - *addr_len = ai->ai_addrlen; - freeaddrinfo(ai); - } - - return gai; -} - - -/******************************* -EventMachine_t::CreateTcpServer -*******************************/ - -const uintptr_t EventMachine_t::CreateTcpServer (const char *server, int port) -{ - /* Create a TCP-acceptor (server) socket and add it to the event machine. - * Return the binding of the new acceptor to the caller. - * This binding will be referenced when the new acceptor sends events - * to indicate accepted connections. - */ - - - struct sockaddr_storage bind_here; - size_t bind_here_len = sizeof bind_here; - if (0 != name2address (server, port, SOCK_STREAM, (struct sockaddr *)&bind_here, &bind_here_len)) - return 0; - - SOCKET sd_accept = EmSocket (bind_here.ss_family, SOCK_STREAM, 0); - if (sd_accept == INVALID_SOCKET) { - goto fail; - } - - { // set reuseaddr to improve performance on restarts. - int oval = 1; - if (setsockopt (sd_accept, SOL_SOCKET, SO_REUSEADDR, (char*)&oval, sizeof(oval)) < 0) { - //__warning ("setsockopt failed while creating listener",""); - goto fail; - } - } - - { // set CLOEXEC. Only makes sense on Unix - #ifdef OS_UNIX - int cloexec = fcntl (sd_accept, F_GETFD, 0); - assert (cloexec >= 0); - cloexec |= FD_CLOEXEC; - fcntl (sd_accept, F_SETFD, cloexec); - #endif - } - - - if (bind (sd_accept, (struct sockaddr *)&bind_here, bind_here_len)) { - //__warning ("binding failed"); - goto fail; - } - - if (listen (sd_accept, 100)) { - //__warning ("listen failed"); - goto fail; - } - - return AttachSD(sd_accept); - - fail: - if (sd_accept != INVALID_SOCKET) - close (sd_accept); - return 0; -} - - -/********************************** -EventMachine_t::OpenDatagramSocket -**********************************/ - -const uintptr_t EventMachine_t::OpenDatagramSocket (const char *address, int port) -{ - uintptr_t output_binding = 0; - - struct sockaddr_storage bind_here; - size_t bind_here_len = sizeof bind_here; - if (0 != name2address (address, port, SOCK_DGRAM, (struct sockaddr *)&bind_here, &bind_here_len)) - return 0; - - // from here on, early returns must close the socket! - SOCKET sd = EmSocket (bind_here.ss_family, SOCK_DGRAM, 0); - if (sd == INVALID_SOCKET) - goto fail; - - { // set the SO_REUSEADDR on the socket before we bind, otherwise it won't work for a second one - int oval = 1; - if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char*)&oval, sizeof(oval)) < 0) - goto fail; - } - - // Set the new socket nonblocking. - if (!SetSocketNonblocking (sd)) - goto fail; - - if (bind (sd, (struct sockaddr *)&bind_here, bind_here_len) != 0) - goto fail; - - { // Looking good. - DatagramDescriptor *ds = new DatagramDescriptor (sd, this); - if (!ds) - throw std::runtime_error ("unable to allocate datagram-socket"); - Add (ds); - output_binding = ds->GetBinding(); - } - - return output_binding; - - fail: - if (sd != INVALID_SOCKET) - close (sd); - return 0; -} - - - -/******************* -EventMachine_t::Add -*******************/ - -void EventMachine_t::Add (EventableDescriptor *ed) -{ - if (!ed) - throw std::runtime_error ("added bad descriptor"); - ed->SetEventCallback (EventCallback); - NewDescriptors.push_back (ed); -} - - -/******************************* -EventMachine_t::ArmKqueueWriter -*******************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed) -{ - if (Poller == Poller_Kqueue) { - if (!ed) - throw std::runtime_error ("added bad descriptor"); - struct kevent k; -#ifdef __NetBSD__ - EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, (intptr_t)ed); -#else - EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, ed); -#endif - int t = kevent (kqfd, &k, 1, NULL, 0, NULL); - if (t < 0) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "arm kqueue writer failed on %d: %s", ed->GetSocket(), strerror(errno)); - throw std::runtime_error (buf); - } - } -} -#else -void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed UNUSED) { } -#endif - -/******************************* -EventMachine_t::ArmKqueueReader -*******************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed) -{ - if (Poller == Poller_Kqueue) { - if (!ed) - throw std::runtime_error ("added bad descriptor"); - struct kevent k; -#ifdef __NetBSD__ - EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed); -#else - EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed); -#endif - int t = kevent (kqfd, &k, 1, NULL, 0, NULL); - if (t < 0) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "arm kqueue reader failed on %d: %s", ed->GetSocket(), strerror(errno)); - throw std::runtime_error (buf); - } - } -} -#else -void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed UNUSED) { } -#endif - -/********************************** -EventMachine_t::_AddNewDescriptors -**********************************/ - -void EventMachine_t::_AddNewDescriptors() -{ - /* Avoid adding descriptors to the main descriptor list - * while we're actually traversing the list. - * Any descriptors that are added as a result of processing timers - * or acceptors should go on a temporary queue and then added - * while we're not traversing the main list. - * Also, it (rarely) happens that a newly-created descriptor - * is immediately scheduled to close. It might be a good - * idea not to bother scheduling these for I/O but if - * we do that, we might bypass some important processing. - */ - - for (size_t i = 0; i < NewDescriptors.size(); i++) { - EventableDescriptor *ed = NewDescriptors[i]; - if (ed == NULL) - throw std::runtime_error ("adding bad descriptor"); - - #if HAVE_EPOLL - if (Poller == Poller_Epoll) { - assert (epfd != -1); - int e = epoll_ctl (epfd, EPOLL_CTL_ADD, ed->GetSocket(), ed->GetEpollEvent()); - if (e) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to add new descriptor: %s", strerror(errno)); - throw std::runtime_error (buf); - } - } - #endif - - #if HAVE_KQUEUE - /* - if (Poller == Poller_Kqueue) { - // INCOMPLETE. Some descriptors don't want to be readable. - assert (kqfd != -1); - struct kevent k; -#ifdef __NetBSD__ - EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed); -#else - EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed); -#endif - int t = kevent (kqfd, &k, 1, NULL, 0, NULL); - assert (t == 0); - } - */ - #endif - - QueueHeartbeat(ed); - Descriptors.push_back (ed); - } - NewDescriptors.clear(); -} - - -/********************************** -EventMachine_t::_ModifyDescriptors -**********************************/ - -void EventMachine_t::_ModifyDescriptors() -{ - /* For implementations which don't level check every descriptor on - * every pass through the machine, as select does. - * If we're not selecting, then descriptors need a way to signal to the - * machine that their readable or writable status has changed. - * That's what the ::Modify call is for. We do it this way to avoid - * modifying descriptors during the loop traversal, where it can easily - * happen that an object (like a UDP socket) gets data written on it by - * the application during #post_init. That would take place BEFORE the - * descriptor even gets added to the epoll descriptor, so the modify - * operation will crash messily. - * Another really messy possibility is for a descriptor to put itself - * on the Modified list, and then get deleted before we get here. - * Remember, deletes happen after the I/O traversal and before the - * next pass through here. So we have to make sure when we delete a - * descriptor to remove it from the Modified list. - */ - - #ifdef HAVE_EPOLL - if (Poller == Poller_Epoll) { - std::set::iterator i = ModifiedDescriptors.begin(); - while (i != ModifiedDescriptors.end()) { - assert (*i); - _ModifyEpollEvent (*i); - ++i; - } - } - #endif - - #ifdef HAVE_KQUEUE - if (Poller == Poller_Kqueue) { - std::set::iterator i = ModifiedDescriptors.begin(); - while (i != ModifiedDescriptors.end()) { - assert (*i); - if ((*i)->GetKqueueArmWrite()) - ArmKqueueWriter (*i); - ++i; - } - } - #endif - - ModifiedDescriptors.clear(); -} - - -/********************** -EventMachine_t::Modify -**********************/ - -void EventMachine_t::Modify (EventableDescriptor *ed) -{ - if (!ed) - throw std::runtime_error ("modified bad descriptor"); - ModifiedDescriptors.insert (ed); -} - - -/*********************** -EventMachine_t::Deregister -***********************/ - -void EventMachine_t::Deregister (EventableDescriptor *ed) -{ - if (!ed) - throw std::runtime_error ("modified bad descriptor"); - #ifdef HAVE_EPOLL - // cut/paste from _CleanupSockets(). The error handling could be - // refactored out of there, but it is cut/paste all over the - // file already. - if (Poller == Poller_Epoll) { - assert (epfd != -1); - assert (ed->GetSocket() != INVALID_SOCKET); - int e = epoll_ctl (epfd, EPOLL_CTL_DEL, ed->GetSocket(), ed->GetEpollEvent()); - // ENOENT or EBADF are not errors because the socket may be already closed when we get here. - if (e && (errno != ENOENT) && (errno != EBADF) && (errno != EPERM)) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "unable to delete epoll event: %s", strerror(errno)); - throw std::runtime_error (buf); - } - ModifiedDescriptors.erase(ed); - } - #endif - - #ifdef HAVE_KQUEUE - if (Poller == Poller_Kqueue) { - assert (ed->GetSocket() != INVALID_SOCKET); - - ModifiedDescriptors.erase(ed); - } - #endif -} - - -/************************************** -EventMachine_t::CreateUnixDomainServer -**************************************/ - -#ifdef OS_UNIX -const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename) -{ - /* Create a UNIX-domain acceptor (server) socket and add it to the event machine. - * Return the binding of the new acceptor to the caller. - * This binding will be referenced when the new acceptor sends events - * to indicate accepted connections. - * THERE IS NO MEANINGFUL IMPLEMENTATION ON WINDOWS. - */ - - struct sockaddr_un s_sun; - - SOCKET sd_accept = EmSocket (AF_LOCAL, SOCK_STREAM, 0); - if (sd_accept == INVALID_SOCKET) { - goto fail; - } - - if (!filename || !*filename) - goto fail; - unlink (filename); - - bzero (&s_sun, sizeof(s_sun)); - s_sun.sun_family = AF_LOCAL; - strncpy (s_sun.sun_path, filename, sizeof(s_sun.sun_path)-1); - - // don't bother with reuseaddr for a local socket. - - { // set CLOEXEC. Only makes sense on Unix - #ifdef OS_UNIX - int cloexec = fcntl (sd_accept, F_GETFD, 0); - assert (cloexec >= 0); - cloexec |= FD_CLOEXEC; - fcntl (sd_accept, F_SETFD, cloexec); - #endif - } - - if (bind (sd_accept, (struct sockaddr*)&s_sun, sizeof(s_sun))) { - //__warning ("binding failed"); - goto fail; - } - - if (listen (sd_accept, 100)) { - //__warning ("listen failed"); - goto fail; - } - - return AttachSD(sd_accept); - - fail: - if (sd_accept != INVALID_SOCKET) - close (sd_accept); - return 0; -} -#else -const uintptr_t EventMachine_t::CreateUnixDomainServer (const char *filename UNUSED) -{ - throw std::runtime_error ("unix-domain server unavailable on this platform"); -} -#endif - - -/************************************** -EventMachine_t::AttachSD -**************************************/ - -const uintptr_t EventMachine_t::AttachSD (SOCKET sd_accept) -{ - uintptr_t output_binding = 0; - - { - // Set the acceptor non-blocking. - // THIS IS CRUCIALLY IMPORTANT because we read it in a select loop. - if (!SetSocketNonblocking (sd_accept)) { - //int val = fcntl (sd_accept, F_GETFL, 0); - //if (fcntl (sd_accept, F_SETFL, val | O_NONBLOCK) == -1) { - goto fail; - } - } - - { // Looking good. - AcceptorDescriptor *ad = new AcceptorDescriptor (sd_accept, this); - if (!ad) - throw std::runtime_error ("unable to allocate acceptor"); - Add (ad); - output_binding = ad->GetBinding(); - } - - return output_binding; - - fail: - if (sd_accept != INVALID_SOCKET) - close (sd_accept); - return 0; -} - - -/************************** -EventMachine_t::Socketpair -**************************/ - -#ifdef OS_UNIX -const uintptr_t EventMachine_t::Socketpair (char * const * cmd_strings) -{ - // Make sure the incoming array of command strings is sane. - if (!cmd_strings) - return 0; - int j; - for (j=0; j < 2048 && cmd_strings[j]; j++) - ; - if ((j==0) || (j==2048)) - return 0; - - uintptr_t output_binding = 0; - - int sv[2]; - if (socketpair (AF_LOCAL, SOCK_STREAM, 0, sv) < 0) - return 0; - // from here, all early returns must close the pair of sockets. - - // Set the parent side of the socketpair nonblocking. - // We don't care about the child side, and most child processes will expect their - // stdout to be blocking. Thanks to Duane Johnson and Bill Kelly for pointing this out. - // Obviously DON'T set CLOEXEC. - if (!SetSocketNonblocking (sv[0])) { - close (sv[0]); - close (sv[1]); - return 0; - } - - pid_t f = fork(); - if (f > 0) { - close (sv[1]); - PipeDescriptor *pd = new PipeDescriptor (sv[0], f, this); - if (!pd) - throw std::runtime_error ("unable to allocate pipe"); - Add (pd); - output_binding = pd->GetBinding(); - } - else if (f == 0) { - close (sv[0]); - dup2 (sv[1], STDIN_FILENO); - close (sv[1]); - dup2 (STDIN_FILENO, STDOUT_FILENO); - execvp (cmd_strings[0], cmd_strings+1); - exit (-1); // end the child process if the exec doesn't work. - } - else - throw std::runtime_error ("no fork"); - - return output_binding; -} -#else -const uintptr_t EventMachine_t::Socketpair (char * const * cmd_strings UNUSED) -{ - throw std::runtime_error ("socketpair is currently unavailable on this platform"); -} -#endif - - - -/**************************** -EventMachine_t::OpenKeyboard -****************************/ - -const uintptr_t EventMachine_t::OpenKeyboard() -{ - KeyboardDescriptor *kd = new KeyboardDescriptor (this); - if (!kd) - throw std::runtime_error ("no keyboard-object allocated"); - Add (kd); - return kd->GetBinding(); -} - - -/********************************** -EventMachine_t::GetConnectionCount -**********************************/ - -int EventMachine_t::GetConnectionCount () -{ - int i = 0; - // Subtract one for epoll or kqueue because of the LoopbreakDescriptor - if (Poller == Poller_Epoll || Poller == Poller_Kqueue) - i = 1; - - return Descriptors.size() + NewDescriptors.size() - i; -} - - -/************************ -EventMachine_t::WatchPid -************************/ - -#ifdef HAVE_KQUEUE -const uintptr_t EventMachine_t::WatchPid (int pid) -{ - if (Poller != Poller_Kqueue) - throw std::runtime_error("must enable kqueue (EM.kqueue=true) for pid watching support"); - - struct kevent event; - int kqres; - - EV_SET(&event, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT | NOTE_FORK, 0, 0); - - // Attempt to register the event - kqres = kevent(kqfd, &event, 1, NULL, 0, NULL); - if (kqres == -1) { - char errbuf[200]; - sprintf(errbuf, "failed to register file watch descriptor with kqueue: %s", strerror(errno)); - throw std::runtime_error(errbuf); - } - Bindable_t* b = new Bindable_t(); - Pids.insert(std::make_pair (pid, b)); - - return b->GetBinding(); -} -#else -const uintptr_t EventMachine_t::WatchPid (int pid UNUSED) -{ - throw std::runtime_error("no pid watching support on this system"); -} -#endif - -/************************** -EventMachine_t::UnwatchPid -**************************/ - -void EventMachine_t::UnwatchPid (int pid) -{ - Bindable_t *b = Pids[pid]; - assert(b); - Pids.erase(pid); - - #ifdef HAVE_KQUEUE - struct kevent k; - - EV_SET(&k, pid, EVFILT_PROC, EV_DELETE, 0, 0, 0); - /*int t =*/ kevent (kqfd, &k, 1, NULL, 0, NULL); - // t==-1 if the process already exited; ignore this for now - #endif - - if (EventCallback) - (*EventCallback)(b->GetBinding(), EM_CONNECTION_UNBOUND, NULL, 0); - - delete b; -} - -void EventMachine_t::UnwatchPid (const uintptr_t sig) -{ - for(std::map::iterator i=Pids.begin(); i != Pids.end(); i++) - { - if (i->second->GetBinding() == sig) { - UnwatchPid (i->first); - return; - } - } - - throw std::runtime_error("attempted to remove invalid pid signature"); -} - - -/************************* -EventMachine_t::WatchFile -*************************/ - -const uintptr_t EventMachine_t::WatchFile (const char *fpath) -{ - struct stat sb; - int sres; - int wd = -1; - - sres = stat(fpath, &sb); - - if (sres == -1) { - char errbuf[300]; - sprintf(errbuf, "error registering file %s for watching: %s", fpath, strerror(errno)); - throw std::runtime_error(errbuf); - } - - #ifdef HAVE_INOTIFY - if (!inotify) { - inotify = new InotifyDescriptor(this); - assert (inotify); - Add(inotify); - } - - wd = inotify_add_watch(inotify->GetSocket(), fpath, - IN_MODIFY | IN_DELETE_SELF | IN_MOVE_SELF | IN_CREATE | IN_DELETE | IN_MOVE) ; - if (wd == -1) { - char errbuf[300]; - sprintf(errbuf, "failed to open file %s for registering with inotify: %s", fpath, strerror(errno)); - throw std::runtime_error(errbuf); - } - #endif - - #ifdef HAVE_KQUEUE - if (Poller != Poller_Kqueue) - throw std::runtime_error("must enable kqueue (EM.kqueue=true) for file watching support"); - - // With kqueue we have to open the file first and use the resulting fd to register for events - wd = open(fpath, O_RDONLY); - if (wd == -1) { - char errbuf[300]; - sprintf(errbuf, "failed to open file %s for registering with kqueue: %s", fpath, strerror(errno)); - throw std::runtime_error(errbuf); - } - _RegisterKqueueFileEvent(wd); - #endif - - if (wd != -1) { - Bindable_t* b = new Bindable_t(); - Files.insert(std::make_pair (wd, b)); - - return b->GetBinding(); - } - - throw std::runtime_error("no file watching support on this system"); // is this the right thing to do? -} - - -/*************************** -EventMachine_t::UnwatchFile -***************************/ - -void EventMachine_t::UnwatchFile (int wd) -{ - Bindable_t *b = Files[wd]; - assert(b); - Files.erase(wd); - - #ifdef HAVE_INOTIFY - inotify_rm_watch(inotify->GetSocket(), wd); - #elif HAVE_KQUEUE - // With kqueue, closing the monitored fd automatically clears all registered events for it - close(wd); - #endif - - if (EventCallback) - (*EventCallback)(b->GetBinding(), EM_CONNECTION_UNBOUND, NULL, 0); - - delete b; -} - -void EventMachine_t::UnwatchFile (const uintptr_t sig) -{ - for(std::map::iterator i=Files.begin(); i != Files.end(); i++) - { - if (i->second->GetBinding() == sig) { - UnwatchFile (i->first); - return; - } - } - throw std::runtime_error("attempted to remove invalid watch signature"); -} - - -/*********************************** -EventMachine_t::_ReadInotify_Events -************************************/ - -void EventMachine_t::_ReadInotifyEvents() -{ - #ifdef HAVE_INOTIFY - char buffer[1024]; - - assert(EventCallback); - - for (;;) { - int returned = read(inotify->GetSocket(), buffer, sizeof(buffer)); - assert(!(returned == 0 || (returned == -1 && errno == EINVAL))); - if (returned <= 0) { - break; - } - int current = 0; - while (current < returned) { - struct inotify_event* event = (struct inotify_event*)(buffer+current); - std::map::const_iterator bindable = Files.find(event->wd); - if (bindable != Files.end()) { - if (event->mask & (IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVE)){ - (*EventCallback)(bindable->second->GetBinding(), EM_CONNECTION_READ, "modified", 8); - } - if (event->mask & IN_MOVE_SELF){ - (*EventCallback)(bindable->second->GetBinding(), EM_CONNECTION_READ, "moved", 5); - } - if (event->mask & IN_DELETE_SELF) { - (*EventCallback)(bindable->second->GetBinding(), EM_CONNECTION_READ, "deleted", 7); - UnwatchFile ((int)event->wd); - } - } - current += sizeof(struct inotify_event) + event->len; - } - } - #endif -} - - -/************************************* -EventMachine_t::_HandleKqueuePidEvent -*************************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::_HandleKqueuePidEvent(struct kevent *event) -{ - assert(EventCallback); - - if (event->fflags & NOTE_FORK) - (*EventCallback)(Pids [(int) event->ident]->GetBinding(), EM_CONNECTION_READ, "fork", 4); - if (event->fflags & NOTE_EXIT) { - (*EventCallback)(Pids [(int) event->ident]->GetBinding(), EM_CONNECTION_READ, "exit", 4); - // stop watching the pid if it died - UnwatchPid ((int)event->ident); - } -} -#endif - - -/************************************** -EventMachine_t::_HandleKqueueFileEvent -***************************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::_HandleKqueueFileEvent(struct kevent *event) -{ - assert(EventCallback); - - if (event->fflags & NOTE_WRITE) - (*EventCallback)(Files [(int) event->ident]->GetBinding(), EM_CONNECTION_READ, "modified", 8); - if (event->fflags & NOTE_RENAME) - (*EventCallback)(Files [(int) event->ident]->GetBinding(), EM_CONNECTION_READ, "moved", 5); - if (event->fflags & NOTE_DELETE) { - (*EventCallback)(Files [(int) event->ident]->GetBinding(), EM_CONNECTION_READ, "deleted", 7); - UnwatchFile ((int)event->ident); - } -} -#endif - - -/**************************************** -EventMachine_t::_RegisterKqueueFileEvent -*****************************************/ - -#ifdef HAVE_KQUEUE -void EventMachine_t::_RegisterKqueueFileEvent(int fd) -{ - struct kevent newevent; - int kqres; - - // Setup the event with our fd and proper flags - EV_SET(&newevent, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_DELETE | NOTE_RENAME | NOTE_WRITE, 0, 0); - - // Attempt to register the event - kqres = kevent(kqfd, &newevent, 1, NULL, 0, NULL); - if (kqres == -1) { - char errbuf[200]; - sprintf(errbuf, "failed to register file watch descriptor with kqueue: %s", strerror(errno)); - close(fd); - throw std::runtime_error(errbuf); - } -} -#endif - - -/************************************ -EventMachine_t::GetHeartbeatInterval -*************************************/ - -float EventMachine_t::GetHeartbeatInterval() -{ - return ((float)HeartbeatInterval / 1000000); -} - - -/************************************ -EventMachine_t::SetHeartbeatInterval -*************************************/ - -int EventMachine_t::SetHeartbeatInterval(float interval) -{ - int iv = (int)(interval * 1000000); - if (iv > 0) { - HeartbeatInterval = iv; - return 1; - } - return 0; -} -//#endif // OS_UNIX diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.h deleted file mode 100644 index 874a127..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/em.h +++ /dev/null @@ -1,308 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: em.h -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#ifndef __EventMachine__H_ -#define __EventMachine__H_ - -#ifdef BUILD_FOR_RUBY - #include - #ifdef HAVE_RB_THREAD_FD_SELECT - #define EmSelect rb_thread_fd_select - #else - // ruby 1.9.1 and below - #define EmSelect rb_thread_select - #endif - - #ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL - #include - #endif - - #ifdef HAVE_RB_WAIT_FOR_SINGLE_FD - #include - #endif - - #if defined(HAVE_RB_TRAP_IMMEDIATE) - #include - #elif defined(HAVE_RB_ENABLE_INTERRUPT) - extern "C" { - void rb_enable_interrupt(void); - void rb_disable_interrupt(void); - } - - #define TRAP_BEG rb_enable_interrupt() - #define TRAP_END do { rb_disable_interrupt(); rb_thread_check_ints(); } while(0) - #else - #define TRAP_BEG - #define TRAP_END - #endif - - // 1.9.0 compat - #ifndef RUBY_UBF_IO - #define RUBY_UBF_IO RB_UBF_DFL - #endif - #ifndef RSTRING_PTR - #define RSTRING_PTR(str) RSTRING(str)->ptr - #endif - #ifndef RSTRING_LEN - #define RSTRING_LEN(str) RSTRING(str)->len - #endif - #ifndef RSTRING_LENINT - #define RSTRING_LENINT(str) RSTRING_LEN(str) - #endif -#else - #define EmSelect select -#endif - -#if !defined(HAVE_TYPE_RB_FDSET_T) -#define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n))) -// These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3, -// with this change: any macros that read or write the nth element of an -// fdset first call fd_check to make sure n is in bounds. -typedef fd_set rb_fdset_t; -#define rb_fd_zero(f) FD_ZERO(f) -#define rb_fd_set(n, f) do { if (fd_check(n)) FD_SET((n), (f)); } while(0) -#define rb_fd_clr(n, f) do { if (fd_check(n)) FD_CLR((n), (f)); } while(0) -#define rb_fd_isset(n, f) (fd_check(n) ? FD_ISSET((n), (f)) : 0) -#define rb_fd_copy(d, s, n) (*(d) = *(s)) -#define rb_fd_dup(d, s) (*(d) = *(s)) -#define rb_fd_resize(n, f) ((void)(f)) -#define rb_fd_ptr(f) (f) -#define rb_fd_init(f) FD_ZERO(f) -#define rb_fd_init_copy(d, s) (*(d) = *(s)) -#define rb_fd_term(f) ((void)(f)) -#define rb_fd_max(f) FD_SETSIZE -#define rb_fd_select(n, rfds, wfds, efds, timeout) \ - select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout)) -#define rb_thread_fd_select(n, rfds, wfds, efds, timeout) \ - rb_thread_select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout)) -#endif - - -// This Solaris fix is adapted from eval_intern.h in Ruby 1.9.3: -// Solaris sys/select.h switches select to select_large_fdset to support larger -// file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment. -// But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically. -// So following definition is required to use select_large_fdset. -#ifdef HAVE_SELECT_LARGE_FDSET -#define select(n, r, w, e, t) select_large_fdset((n), (r), (w), (e), (t)) -extern "C" { - int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval *); -} -#endif - -class EventableDescriptor; -class InotifyDescriptor; -struct SelectData_t; - -/************* -enum Poller_t -*************/ -enum Poller_t { - Poller_Default, // typically Select - Poller_Epoll, - Poller_Kqueue -}; - - -/******************** -class EventMachine_t -********************/ - -class EventMachine_t -{ - public: - static int GetMaxTimerCount(); - static void SetMaxTimerCount (int); - - static int GetSimultaneousAcceptCount(); - static void SetSimultaneousAcceptCount (int); - - public: - EventMachine_t (EMCallback, Poller_t); - virtual ~EventMachine_t(); - - bool RunOnce(); - void Run(); - void ScheduleHalt(); - bool Stopping(); - void SignalLoopBreaker(); - const uintptr_t InstallOneshotTimer (uint64_t); - const uintptr_t ConnectToServer (const char *, int, const char *, int); - const uintptr_t ConnectToUnixServer (const char *); - - const uintptr_t CreateTcpServer (const char *, int); - const uintptr_t OpenDatagramSocket (const char *, int); - const uintptr_t CreateUnixDomainServer (const char*); - const uintptr_t AttachSD (SOCKET); - const uintptr_t OpenKeyboard(); - //const char *Popen (const char*, const char*); - const uintptr_t Socketpair (char* const*); - - void Add (EventableDescriptor*); - void Modify (EventableDescriptor*); - void Deregister (EventableDescriptor*); - - const uintptr_t AttachFD (SOCKET, bool); - int DetachFD (EventableDescriptor*); - - void ArmKqueueWriter (EventableDescriptor*); - void ArmKqueueReader (EventableDescriptor*); - - void SetTimerQuantum (int); - static void SetuidString (const char*); - static int SetRlimitNofile (int); - - pid_t SubprocessPid; - int SubprocessExitStatus; - - int GetConnectionCount(); - float GetHeartbeatInterval(); - int SetHeartbeatInterval(float); - - const uintptr_t WatchFile (const char*); - void UnwatchFile (int); - void UnwatchFile (const uintptr_t); - - #ifdef HAVE_KQUEUE - void _HandleKqueueFileEvent (struct kevent*); - void _RegisterKqueueFileEvent(int); - #endif - - const uintptr_t WatchPid (int); - void UnwatchPid (int); - void UnwatchPid (const uintptr_t); - - #ifdef HAVE_KQUEUE - void _HandleKqueuePidEvent (struct kevent*); - #endif - - uint64_t GetCurrentLoopTime() { return MyCurrentLoopTime; } - - void QueueHeartbeat(EventableDescriptor*); - void ClearHeartbeat(uint64_t, EventableDescriptor*); - - uint64_t GetRealTime(); - - Poller_t GetPoller() { return Poller; } - - static int name2address (const char *server, int port, int socktype, struct sockaddr *addr, size_t *addr_len); - - private: - void _RunTimers(); - void _UpdateTime(); - void _AddNewDescriptors(); - void _ModifyDescriptors(); - void _InitializeLoopBreaker(); - void _CleanupSockets(); - - void _RunSelectOnce(); - void _RunEpollOnce(); - void _RunKqueueOnce(); - - void _ModifyEpollEvent (EventableDescriptor*); - void _DispatchHeartbeats(); - timeval _TimeTilNextEvent(); - void _CleanBadDescriptors(); - - public: - void _ReadLoopBreaker(); - void _ReadInotifyEvents(); - int NumCloseScheduled; - - private: - enum { - MaxEpollDescriptors = 64*1024, - MaxEvents = 4096 - }; - int HeartbeatInterval; - EMCallback EventCallback; - - class Timer_t: public Bindable_t { - }; - - std::multimap Timers; - std::multimap Heartbeats; - std::map Files; - std::map Pids; - std::vector Descriptors; - std::vector NewDescriptors; - std::set ModifiedDescriptors; - - SOCKET LoopBreakerReader; - SOCKET LoopBreakerWriter; - #ifdef OS_WIN32 - struct sockaddr_in LoopBreakerTarget; - #endif - - timeval Quantum; - - uint64_t MyCurrentLoopTime; - - #ifdef OS_WIN32 - unsigned TickCountTickover; - unsigned LastTickCount; - #endif - - #ifdef OS_DARWIN - mach_timebase_info_data_t mach_timebase; - #endif - - private: - bool bTerminateSignalReceived; - SelectData_t *SelectData; - - Poller_t Poller; - - int epfd; // Epoll file-descriptor - #ifdef HAVE_EPOLL - struct epoll_event epoll_events [MaxEvents]; - #endif - - int kqfd; // Kqueue file-descriptor - #ifdef HAVE_KQUEUE - struct kevent Karray [MaxEvents]; - #endif - - #ifdef HAVE_INOTIFY - InotifyDescriptor *inotify; // pollable descriptor for our inotify instance - #endif -}; - - -/******************* -struct SelectData_t -*******************/ - -struct SelectData_t -{ - SelectData_t(); - ~SelectData_t(); - - int _Select(); - void _Clear(); - - SOCKET maxsocket; - rb_fdset_t fdreads; - rb_fdset_t fdwrites; - rb_fdset_t fderrors; - timeval tv; - int nSockets; -}; - -#endif // __EventMachine__H_ diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/eventmachine.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/eventmachine.h deleted file mode 100644 index 5100e20..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/eventmachine.h +++ /dev/null @@ -1,143 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: eventmachine.h -Date: 15Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#ifndef __EVMA_EventMachine__H_ -#define __EVMA_EventMachine__H_ - -#if __cplusplus -extern "C" { -#endif - - enum { // Event names - EM_TIMER_FIRED = 100, - EM_CONNECTION_READ = 101, - EM_CONNECTION_UNBOUND = 102, - EM_CONNECTION_ACCEPTED = 103, - EM_CONNECTION_COMPLETED = 104, - EM_LOOPBREAK_SIGNAL = 105, - EM_CONNECTION_NOTIFY_READABLE = 106, - EM_CONNECTION_NOTIFY_WRITABLE = 107, - EM_SSL_HANDSHAKE_COMPLETED = 108, - EM_SSL_VERIFY = 109, - EM_PROXY_TARGET_UNBOUND = 110, - EM_PROXY_COMPLETED = 111 - }; - - enum { // SSL/TLS Protocols - EM_PROTO_SSLv2 = 2, - EM_PROTO_SSLv3 = 4, - EM_PROTO_TLSv1 = 8, - EM_PROTO_TLSv1_1 = 16, - EM_PROTO_TLSv1_2 = 32 - }; - - void evma_initialize_library (EMCallback); - bool evma_run_machine_once(); - void evma_run_machine(); - void evma_release_library(); - const uintptr_t evma_install_oneshot_timer (uint64_t milliseconds); - const uintptr_t evma_connect_to_server (const char *bind_addr, int bind_port, const char *server, int port); - const uintptr_t evma_connect_to_unix_server (const char *server); - - const uintptr_t evma_attach_fd (int file_descriptor, int watch_mode); - int evma_detach_fd (const uintptr_t binding); - int evma_get_file_descriptor (const uintptr_t binding); - int evma_is_notify_readable (const uintptr_t binding); - void evma_set_notify_readable (const uintptr_t binding, int mode); - int evma_is_notify_writable (const uintptr_t binding); - void evma_set_notify_writable (const uintptr_t binding, int mode); - - int evma_pause(const uintptr_t binding); - int evma_is_paused(const uintptr_t binding); - int evma_resume(const uintptr_t binding); - - int evma_num_close_scheduled(); - - void evma_stop_tcp_server (const uintptr_t binding); - const uintptr_t evma_create_tcp_server (const char *address, int port); - const uintptr_t evma_create_unix_domain_server (const char *filename); - const uintptr_t evma_attach_sd (int sd); - const uintptr_t evma_open_datagram_socket (const char *server, int port); - const uintptr_t evma_open_keyboard(); - void evma_set_tls_parms (const uintptr_t binding, const char *privatekey_filename, const char *certchain_filenane, int verify_peer, int fail_if_no_peer_cert, const char *sni_hostname, const char *cipherlist, const char *ecdh_curve, const char *dhparam, int protocols); - void evma_start_tls (const uintptr_t binding); - - #ifdef WITH_SSL - X509 *evma_get_peer_cert (const uintptr_t binding); - int evma_get_cipher_bits (const uintptr_t binding); - const char *evma_get_cipher_name (const uintptr_t binding); - const char *evma_get_cipher_protocol (const uintptr_t binding); - const char *evma_get_sni_hostname (const uintptr_t binding); - void evma_accept_ssl_peer (const uintptr_t binding); - #endif - - int evma_get_peername (const uintptr_t binding, struct sockaddr*, socklen_t*); - int evma_get_sockname (const uintptr_t binding, struct sockaddr*, socklen_t*); - int evma_get_subprocess_pid (const uintptr_t binding, pid_t*); - int evma_get_subprocess_status (const uintptr_t binding, int*); - int evma_get_connection_count(); - int evma_send_data_to_connection (const uintptr_t binding, const char *data, int data_length); - int evma_send_datagram (const uintptr_t binding, const char *data, int data_length, const char *address, int port); - float evma_get_comm_inactivity_timeout (const uintptr_t binding); - int evma_set_comm_inactivity_timeout (const uintptr_t binding, float value); - float evma_get_pending_connect_timeout (const uintptr_t binding); - int evma_set_pending_connect_timeout (const uintptr_t binding, float value); - int evma_get_outbound_data_size (const uintptr_t binding); - uint64_t evma_get_last_activity_time (const uintptr_t binding); - int evma_send_file_data_to_connection (const uintptr_t binding, const char *filename); - - void evma_close_connection (const uintptr_t binding, int after_writing); - int evma_report_connection_error_status (const uintptr_t binding); - void evma_signal_loopbreak(); - void evma_set_timer_quantum (int); - int evma_get_max_timer_count(); - void evma_set_max_timer_count (int); - int evma_get_simultaneous_accept_count(); - void evma_set_simultaneous_accept_count (int); - void evma_setuid_string (const char *username); - void evma_stop_machine(); - bool evma_stopping(); - float evma_get_heartbeat_interval(); - int evma_set_heartbeat_interval(float); - - const uintptr_t evma_popen (char * const*cmd_strings); - - const uintptr_t evma_watch_filename (const char *fname); - void evma_unwatch_filename (const uintptr_t binding); - - const uintptr_t evma_watch_pid (int); - void evma_unwatch_pid (const uintptr_t binding); - - void evma_start_proxy(const uintptr_t from, const uintptr_t to, const unsigned long bufsize, const unsigned long length); - void evma_stop_proxy(const uintptr_t from); - unsigned long evma_proxied_bytes(const uintptr_t from); - - int evma_set_rlimit_nofile (int n_files); - - void evma_set_epoll (int use); - void evma_set_kqueue (int use); - - uint64_t evma_get_current_loop_time(); -#if __cplusplus -} -#endif - - -#endif // __EventMachine__H_ - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/extconf.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/extconf.rb deleted file mode 100644 index 676b4c4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/extconf.rb +++ /dev/null @@ -1,270 +0,0 @@ -require 'fileutils' -require 'mkmf' - -# Eager check devs tools -have_devel? if respond_to?(:have_devel?) - -def check_libs libs = [], fatal = false - libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) } -end - -def check_heads heads = [], fatal = false - heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)} -end - -def add_define(name) - $defs.push("-D#{name}") -end - -## -# OpenSSL: - -# override append_library, so it actually appends (instead of prepending) -# this fixes issues with linking ssl, since libcrypto depends on symbols in libssl -def append_library(libs, lib) - libs + " " + format(LIBARG, lib) -end - -SSL_HEADS = %w(openssl/ssl.h openssl/err.h) -SSL_LIBS = %w(crypto ssl) -# OpenSSL 1.1.0 and above for Windows use the Unix library names -# OpenSSL 0.9.8 and 1.0.x for Windows use the *eay32 library names -SSL_LIBS_WIN = RUBY_PLATFORM =~ /mswin|mingw|bccwin/ ? %w(ssleay32 libeay32) : [] - -def dir_config_wrapper(pretty_name, name, idefault=nil, ldefault=nil) - inc, lib = dir_config(name, idefault, ldefault) - if inc && lib - # TODO: Remove when 2.0.0 is the minimum supported version - # Ruby versions not incorporating the mkmf fix at - # https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717 - # do not properly search for lib directories, and must be corrected - unless lib && lib[-3, 3] == 'lib' - @libdir_basename = 'lib' - inc, lib = dir_config(name, idefault, ldefault) - end - unless idefault && ldefault - abort "-----\nCannot find #{pretty_name} include path #{inc}\n-----" unless inc && inc.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) } - abort "-----\nCannot find #{pretty_name} library path #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) } - warn "-----\nUsing #{pretty_name} in path #{File.dirname inc}\n-----" - end - true - end -end - -def dir_config_search(pretty_name, name, paths, &b) - paths.each do |p| - if dir_config_wrapper('OpenSSL', 'ssl', p + '/include', p + '/lib') && yield - warn "-----\nFound #{pretty_name} in path #{p}\n-----" - return true - end - end - false -end - -def pkg_config_wrapper(pretty_name, name) - cflags, ldflags, libs = pkg_config(name) - unless [cflags, ldflags, libs].any?(&:nil?) || [cflags, ldflags, libs].any?(&:empty?) - warn "-----\nUsing #{pretty_name} from pkg-config #{cflags} && #{ldflags} && #{libs}\n-----" - true - end -end - -if ENV['CROSS_COMPILING'] - openssl_version = ENV.fetch("OPENSSL_VERSION", "1.0.2e") - openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-#{openssl_version}/") - if File.exist?(openssl_dir) - FileUtils.mkdir_p Dir.pwd+"/openssl/" - FileUtils.cp Dir[openssl_dir+"/include/openssl/*.h"], Dir.pwd+"/openssl/", :verbose => true - FileUtils.cp Dir[openssl_dir+"/lib*.a"], Dir.pwd, :verbose => true - $INCFLAGS << " -I#{Dir.pwd}" # for the openssl headers - add_define "WITH_SSL" - else - STDERR.puts - STDERR.puts "**************************************************************************************" - STDERR.puts "**** Cross-compiled OpenSSL not found" - STDERR.puts "**** Run: hg clone http://bitbucket.org/ged/ruby-pg && cd ruby-pg && rake openssl_libs" - STDERR.puts "**************************************************************************************" - STDERR.puts - end -elsif dir_config_wrapper('OpenSSL', 'ssl') - # If the user has provided a --with-ssl-dir argument, we must respect it or fail. - add_define 'WITH_SSL' if (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS) -elsif pkg_config_wrapper('OpenSSL', 'openssl') - # If we can detect OpenSSL by pkg-config, use it as the next-best option - add_define 'WITH_SSL' if (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS) -elsif (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS) - # If we don't even need any options to find a usable OpenSSL, go with it - add_define 'WITH_SSL' -elsif dir_config_search('OpenSSL', 'ssl', ['/usr/local', '/opt/local', '/usr/local/opt/openssl']) do - (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS) - end - # Finally, look for OpenSSL in alternate locations including MacPorts and HomeBrew - add_define 'WITH_SSL' -end - -add_define 'BUILD_FOR_RUBY' - -# Ruby features: - -have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h']) -have_func('rb_thread_blocking_region') -have_func('rb_thread_call_without_gvl', 'ruby/thread.h') -have_func('rb_thread_fd_select') -have_type('rb_fdset_t', 'ruby/intern.h') -have_func('rb_wait_for_single_fd') -have_func('rb_enable_interrupt') -have_func('rb_time_new') - -# System features: - -add_define('HAVE_INOTIFY') if inotify = have_func('inotify_init', 'sys/inotify.h') -add_define('HAVE_OLD_INOTIFY') if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h') -have_func('writev', 'sys/uio.h') -have_func('pipe2', 'unistd.h') -have_func('accept4', 'sys/socket.h') -have_const('SOCK_CLOEXEC', 'sys/socket.h') - -# Minor platform details between *nix and Windows: - -if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/ - GNU_CHAIN = ENV['CROSS_COMPILING'] || $1 == 'mingw' - OS_WIN32 = true - add_define "OS_WIN32" -else - GNU_CHAIN = true - OS_UNIX = true - add_define 'OS_UNIX' - - add_define "HAVE_KQUEUE" if have_header("sys/event.h") && have_header("sys/queue.h") -end - -# Adjust number of file descriptors (FD) on Windows - -if RbConfig::CONFIG["host_os"] =~ /mingw/ - found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS"). - any? { |v| v.include?("FD_SETSIZE") } - - add_define "FD_SETSIZE=32767" unless found -end - -# Main platform invariances: - -case RUBY_PLATFORM -when /mswin32/, /mingw32/, /bccwin32/ - check_heads(%w[windows.h winsock.h], true) - check_libs(%w[kernel32 rpcrt4 gdi32], true) - - if GNU_CHAIN - CONFIG['LDSHAREDXX'] = "$(CXX) -shared -static-libgcc -static-libstdc++" - else - $defs.push "-EHs" - $defs.push "-GR" - end - - # Newer versions of Ruby already define _WIN32_WINNT, which is needed - # to get access to newer POSIX networking functions (e.g. getaddrinfo) - add_define '_WIN32_WINNT=0x0501' unless have_func('getaddrinfo') - -when /solaris/ - add_define 'OS_SOLARIS8' - check_libs(%w[nsl socket], true) - - # If Ruby was compiled for 32-bits, then select() can only handle 1024 fds - # There is an alternate function, select_large_fdset, that supports more. - have_func('select_large_fdset', 'sys/select.h') - - if CONFIG['CC'] == 'cc' && ( - `cc -flags 2>&1` =~ /Sun/ || # detect SUNWspro compiler - `cc -V 2>&1` =~ /Sun/ # detect Solaris Studio compiler - ) - # SUN CHAIN - add_define 'CC_SUNWspro' - $preload = ["\nCXX = CC"] # hack a CXX= line into the makefile - $CFLAGS = CONFIG['CFLAGS'] = "-KPIC" - CONFIG['CCDLFLAGS'] = "-KPIC" - CONFIG['LDSHARED'] = "$(CXX) -G -KPIC -lCstd" - CONFIG['LDSHAREDXX'] = "$(CXX) -G -KPIC -lCstd" - else - # GNU CHAIN - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - end - -when /openbsd/ - # OpenBSD branch contributed by Guillaume Sellier. - - # on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs - CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC" - CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC" - -when /darwin/ - add_define 'OS_DARWIN' - - # on Unix we need a g++ link, not gcc. - # Ff line contributed by Daniel Harple. - CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ') - -when /linux/ - add_define 'HAVE_EPOLL' if have_func('epoll_create', 'sys/epoll.h') - - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - -when /aix/ - CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl" - -when /cygwin/ - # For rubies built with Cygwin, CXX may be set to CC, which is just - # a wrapper for gcc. - # This will compile, but it will not link to the C++ std library. - # Explicitly set CXX to use g++. - CONFIG['CXX'] = "g++" - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - -else - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" -end - -# Platform-specific time functions -if have_func('clock_gettime') - # clock_gettime is POSIX, but the monotonic clocks are not - have_const('CLOCK_MONOTONIC_RAW', 'time.h') # Linux - have_const('CLOCK_MONOTONIC', 'time.h') # Linux, Solaris, BSDs -else - have_func('gethrtime') # Older Solaris and HP-UX -end - -# Hack so that try_link will test with a C++ compiler instead of a C compiler -TRY_LINK.sub!('$(CC)', '$(CXX)') - -# This is our wishlist. We use whichever flags work on the host. -# In the future, add -Werror to make sure all warnings are resolved. -# deprecated-declarations are used in OS X OpenSSL -# ignored-qualifiers are used by the Bindings (would-be void *) -# unused-result because GCC 4.6 no longer silences (void) ignore_this(function) -# address because on Windows, rb_fd_select checks if &fds is non-NULL, which it cannot be -%w( - -Wall - -Wextra - -Wno-deprecated-declarations - -Wno-ignored-qualifiers - -Wno-unused-result - -Wno-address -).select do |flag| - try_link('int main() {return 0;}', flag) -end.each do |flag| - CONFIG['CXXFLAGS'] << ' ' << flag -end -puts "CXXFLAGS=#{CONFIG['CXXFLAGS']}" - -# Solaris C++ compiler doesn't have make_pair() -add_define 'HAVE_MAKE_PAIR' if try_link(< - using namespace std; - int main(){ pair tuple = make_pair(1,2); } -SRC -TRY_LINK.sub!('$(CXX)', '$(CC)') - -create_makefile "rubyeventmachine" diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/extconf.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/extconf.rb deleted file mode 100644 index e4d64e4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/extconf.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'mkmf' - -def check_libs libs = [], fatal = false - libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) } -end - -def check_heads heads = [], fatal = false - heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)} -end - -def add_define(name) - $defs.push("-D#{name}") -end - -# Eager check devs tools -have_devel? if respond_to?(:have_devel?) - -add_define 'BUILD_FOR_RUBY' - -# Minor platform details between *nix and Windows: - -if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/ - GNU_CHAIN = ENV['CROSS_COMPILING'] || $1 == 'mingw' - OS_WIN32 = true - add_define "OS_WIN32" -else - GNU_CHAIN = true - OS_UNIX = true - add_define 'OS_UNIX' -end - -# Adjust number of file descriptors (FD) on Windows - -if RbConfig::CONFIG["host_os"] =~ /mingw/ - found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS"). - any? { |v| v.include?("FD_SETSIZE") } - - add_define "FD_SETSIZE=32767" unless found -end - -# Main platform invariances: - -case RUBY_PLATFORM -when /mswin32/, /mingw32/, /bccwin32/ - check_heads(%w[windows.h winsock.h], true) - check_libs(%w[kernel32 rpcrt4 gdi32], true) - - if GNU_CHAIN - CONFIG['LDSHAREDXX'] = "$(CXX) -shared -static-libgcc -static-libstdc++" - else - $defs.push "-EHs" - $defs.push "-GR" - end - -when /solaris/ - add_define 'OS_SOLARIS8' - check_libs(%w[nsl socket], true) - - if CONFIG['CC'] == 'cc' && ( - `cc -flags 2>&1` =~ /Sun/ || # detect SUNWspro compiler - `cc -V 2>&1` =~ /Sun/ # detect Solaris Studio compiler - ) - # SUN CHAIN - add_define 'CC_SUNWspro' - $preload = ["\nCXX = CC"] # hack a CXX= line into the makefile - $CFLAGS = CONFIG['CFLAGS'] = "-KPIC" - CONFIG['CCDLFLAGS'] = "-KPIC" - CONFIG['LDSHARED'] = "$(CXX) -G -KPIC -lCstd" - CONFIG['LDSHAREDXX'] = "$(CXX) -G -KPIC -lCstd" - else - # GNU CHAIN - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - end - -when /openbsd/ - # OpenBSD branch contributed by Guillaume Sellier. - - # on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs - CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC" - CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC" - -when /darwin/ - # on Unix we need a g++ link, not gcc. - # Ff line contributed by Daniel Harple. - CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ') - -when /linux/ - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - -when /aix/ - CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl" - -when /cygwin/ - # For rubies built with Cygwin, CXX may be set to CC, which is just - # a wrapper for gcc. - # This will compile, but it will not link to the C++ std library. - # Explicitly set CXX to use g++. - CONFIG['CXX'] = "g++" - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" - -else - # on Unix we need a g++ link, not gcc. - CONFIG['LDSHARED'] = "$(CXX) -shared" -end - -create_makefile "fastfilereaderext" diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.cpp deleted file mode 100644 index f226f2d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/***************************************************************************** - -$Id: mapper.cpp 4527 2007-07-04 10:21:34Z francis $ - -File: mapper.cpp -Date: 02Jul07 - -Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved. -Gmail: garbagecat10 - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -////////////////////////////////////////////////////////////////////// -// UNIX implementation -////////////////////////////////////////////////////////////////////// - - -#ifdef OS_UNIX - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mapper.h" - -/****************** -Mapper_t::Mapper_t -******************/ - -Mapper_t::Mapper_t (const std::string &filename) -{ - /* We ASSUME we can open the file. - * (More precisely, we assume someone else checked before we got here.) - */ - - Fd = open (filename.c_str(), O_RDONLY); - if (Fd < 0) - throw std::runtime_error (strerror (errno)); - - struct stat st; - if (fstat (Fd, &st)) - throw std::runtime_error (strerror (errno)); - FileSize = st.st_size; - - #ifdef OS_WIN32 - MapPoint = (char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0); - #else - MapPoint = (const char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0); - #endif - if (MapPoint == MAP_FAILED) - throw std::runtime_error (strerror (errno)); -} - - -/******************* -Mapper_t::~Mapper_t -*******************/ - -Mapper_t::~Mapper_t() -{ - Close(); -} - - -/*************** -Mapper_t::Close -***************/ - -void Mapper_t::Close() -{ - // Can be called multiple times. - // Calls to GetChunk are invalid after a call to Close. - if (MapPoint) { - #ifdef CC_SUNWspro - // TODO: The void * cast works fine on Solaris 11, but - // I don't know at what point that changed from older Solaris. - munmap ((char*)MapPoint, FileSize); - #else - munmap ((void*)MapPoint, FileSize); - #endif - MapPoint = NULL; - } - if (Fd >= 0) { - close (Fd); - Fd = -1; - } -} - -/****************** -Mapper_t::GetChunk -******************/ - -const char *Mapper_t::GetChunk (unsigned start) -{ - return MapPoint + start; -} - - - -#endif // OS_UNIX - - -////////////////////////////////////////////////////////////////////// -// WINDOWS implementation -////////////////////////////////////////////////////////////////////// - -#ifdef OS_WIN32 - -#include - -#include -#include -#include - -#include "mapper.h" - -/****************** -Mapper_t::Mapper_t -******************/ - -Mapper_t::Mapper_t (const std::string &filename) -{ - /* We ASSUME we can open the file. - * (More precisely, we assume someone else checked before we got here.) - */ - - hFile = INVALID_HANDLE_VALUE; - hMapping = NULL; - MapPoint = NULL; - FileSize = 0; - - hFile = CreateFile (filename.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hFile == INVALID_HANDLE_VALUE) - throw std::runtime_error ("File not found"); - - BY_HANDLE_FILE_INFORMATION i; - if (GetFileInformationByHandle (hFile, &i)) - FileSize = i.nFileSizeLow; - - hMapping = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, 0, NULL); - if (!hMapping) - throw std::runtime_error ("File not mapped"); - - #ifdef OS_WIN32 - MapPoint = (char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0); - #else - MapPoint = (const char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0); - #endif - if (!MapPoint) - throw std::runtime_error ("Mappoint not read"); -} - - -/******************* -Mapper_t::~Mapper_t -*******************/ - -Mapper_t::~Mapper_t() -{ - Close(); -} - -/*************** -Mapper_t::Close -***************/ - -void Mapper_t::Close() -{ - // Can be called multiple times. - // Calls to GetChunk are invalid after a call to Close. - if (MapPoint) { - UnmapViewOfFile (MapPoint); - MapPoint = NULL; - } - if (hMapping != NULL) { - CloseHandle (hMapping); - hMapping = NULL; - } - if (hFile != INVALID_HANDLE_VALUE) { - CloseHandle (hFile); - hFile = INVALID_HANDLE_VALUE; - } -} - - -/****************** -Mapper_t::GetChunk -******************/ - -const char *Mapper_t::GetChunk (unsigned start) -{ - return MapPoint + start; -} - - - -#endif // OS_WINDOWS diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.h deleted file mode 100644 index 3db0eea..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/mapper.h +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - -$Id: mapper.h 4529 2007-07-04 11:32:22Z francis $ - -File: mapper.h -Date: 02Jul07 - -Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved. -Gmail: garbagecat10 - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#ifndef __Mapper__H_ -#define __Mapper__H_ - - -/************** -class Mapper_t -**************/ - -class Mapper_t -{ - public: - Mapper_t (const std::string&); - virtual ~Mapper_t(); - - const char *GetChunk (unsigned); - void Close(); - size_t GetFileSize() {return FileSize;} - - private: - size_t FileSize; - - #ifdef OS_UNIX - private: - int Fd; - const char *MapPoint; - #endif // OS_UNIX - - #ifdef OS_WIN32 - private: - HANDLE hFile; - HANDLE hMapping; - char *MapPoint; - #endif // OS_WIN32 - -}; - - -#endif // __Mapper__H_ - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/rubymain.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/rubymain.cpp deleted file mode 100644 index b962bf0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/fastfilereader/rubymain.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/***************************************************************************** - -$Id: rubymain.cpp 4529 2007-07-04 11:32:22Z francis $ - -File: rubymain.cpp -Date: 02Jul07 - -Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved. -Gmail: garbagecat10 - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - - -#include -#include - -#include -#include "mapper.h" - -static VALUE EmModule; -static VALUE FastFileReader; -static VALUE Mapper; - - - -/********* -mapper_dt -*********/ - -static void mapper_dt (void *ptr) -{ - if (ptr) - delete (Mapper_t*) ptr; -} - -/********** -mapper_new -**********/ - -static VALUE mapper_new (VALUE self, VALUE filename) -{ - Mapper_t *m = new Mapper_t (StringValueCStr (filename)); - if (!m) - rb_raise (rb_eStandardError, "No Mapper Object"); - VALUE v = Data_Wrap_Struct (Mapper, 0, mapper_dt, (void*)m); - return v; -} - - -/**************** -mapper_get_chunk -****************/ - -static VALUE mapper_get_chunk (VALUE self, VALUE start, VALUE length) -{ - Mapper_t *m = NULL; - Data_Get_Struct (self, Mapper_t, m); - if (!m) - rb_raise (rb_eStandardError, "No Mapper Object"); - - // TODO, what if some moron sends us a negative start value? - unsigned _start = NUM2INT (start); - unsigned _length = NUM2INT (length); - if ((_start + _length) > m->GetFileSize()) - rb_raise (rb_eStandardError, "Mapper Range Error"); - - const char *chunk = m->GetChunk (_start); - if (!chunk) - rb_raise (rb_eStandardError, "No Mapper Chunk"); - return rb_str_new (chunk, _length); -} - -/************ -mapper_close -************/ - -static VALUE mapper_close (VALUE self) -{ - Mapper_t *m = NULL; - Data_Get_Struct (self, Mapper_t, m); - if (!m) - rb_raise (rb_eStandardError, "No Mapper Object"); - m->Close(); - return Qnil; -} - -/*********** -mapper_size -***********/ - -static VALUE mapper_size (VALUE self) -{ - Mapper_t *m = NULL; - Data_Get_Struct (self, Mapper_t, m); - if (!m) - rb_raise (rb_eStandardError, "No Mapper Object"); - return INT2NUM (m->GetFileSize()); -} - - -/********************** -Init_fastfilereaderext -**********************/ - -extern "C" void Init_fastfilereaderext() -{ - EmModule = rb_define_module ("EventMachine"); - FastFileReader = rb_define_class_under (EmModule, "FastFileReader", rb_cObject); - Mapper = rb_define_class_under (FastFileReader, "Mapper", rb_cObject); - - rb_define_module_function (Mapper, "new", (VALUE(*)(...))mapper_new, 1); - rb_define_method (Mapper, "size", (VALUE(*)(...))mapper_size, 0); - rb_define_method (Mapper, "close", (VALUE(*)(...))mapper_close, 0); - rb_define_method (Mapper, "get_chunk", (VALUE(*)(...))mapper_get_chunk, 2); -} - - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/kb.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/kb.cpp deleted file mode 100644 index 2187ae2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/kb.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: kb.cpp -Date: 24Aug07 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" - - -/************************************** -KeyboardDescriptor::KeyboardDescriptor -**************************************/ - -KeyboardDescriptor::KeyboardDescriptor (EventMachine_t *parent_em): - EventableDescriptor (0, parent_em), - bReadAttemptedAfterClose (false) -{ - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - #ifdef HAVE_KQUEUE - MyEventMachine->ArmKqueueReader (this); - #endif -} - - -/*************************************** -KeyboardDescriptor::~KeyboardDescriptor -***************************************/ - -KeyboardDescriptor::~KeyboardDescriptor() -{ -} - - -/************************* -KeyboardDescriptor::Write -*************************/ - -void KeyboardDescriptor::Write() -{ - // Why are we here? - throw std::runtime_error ("bad code path in keyboard handler"); -} - - -/***************************** -KeyboardDescriptor::Heartbeat -*****************************/ - -void KeyboardDescriptor::Heartbeat() -{ - // no-op -} - - -/************************ -KeyboardDescriptor::Read -************************/ - -void KeyboardDescriptor::Read() -{ - char c; - (void)read (GetSocket(), &c, 1); - _GenericInboundDispatch(&c, 1); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.cpp deleted file mode 100644 index a3a2340..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: page.cpp -Date: 30Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#include "project.h" - - -/****************** -PageList::PageList -******************/ - -PageList::PageList() -{ -} - - -/******************* -PageList::~PageList -*******************/ - -PageList::~PageList() -{ - while (HasPages()) - PopFront(); -} - - -/*************** -PageList::Front -***************/ - -void PageList::Front (const char **page, int *length) -{ - assert (page && length); - - if (HasPages()) { - Page p = Pages.front(); - *page = p.Buffer; - *length = p.Size; - } - else { - *page = NULL; - *length = 0; - } -} - - -/****************** -PageList::PopFront -******************/ - -void PageList::PopFront() -{ - if (HasPages()) { - Page p = Pages.front(); - Pages.pop_front(); - if (p.Buffer) - free ((void*)p.Buffer); - } -} - - -/****************** -PageList::HasPages -******************/ - -bool PageList::HasPages() -{ - return (Pages.size() > 0) ? true : false; -} - - -/************** -PageList::Push -**************/ - -void PageList::Push (const char *buf, int size) -{ - if (buf && (size > 0)) { - char *copy = (char*) malloc (size); - if (!copy) - throw std::runtime_error ("no memory in pagelist"); - memcpy (copy, buf, size); - Pages.push_back (Page (copy, size)); - } -} - - - - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.h deleted file mode 100644 index 969fc91..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/page.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: page.h -Date: 30Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#ifndef __PageManager__H_ -#define __PageManager__H_ - - -/************** -class PageList -**************/ - -class PageList -{ - struct Page { - Page (const char *b, size_t s): Buffer(b), Size(s) {} - const char *Buffer; - size_t Size; - }; - - public: - PageList(); - virtual ~PageList(); - - void Push (const char*, int); - bool HasPages(); - void Front (const char**, int*); - void PopFront(); - - private: - std::deque Pages; -}; - - -#endif // __PageManager__H_ diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/pipe.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/pipe.cpp deleted file mode 100644 index a5f0d9f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/pipe.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: pipe.cpp -Date: 30May07 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" - - -#ifdef OS_UNIX -// THIS ENTIRE FILE IS ONLY COMPILED ON UNIX-LIKE SYSTEMS. - -/****************************** -PipeDescriptor::PipeDescriptor -******************************/ - -PipeDescriptor::PipeDescriptor (int fd, pid_t subpid, EventMachine_t *parent_em): - EventableDescriptor (fd, parent_em), - bReadAttemptedAfterClose (false), - OutboundDataSize (0), - SubprocessPid (subpid) -{ - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - #endif - #ifdef HAVE_KQUEUE - MyEventMachine->ArmKqueueReader (this); - #endif -} - - -/******************************* -PipeDescriptor::~PipeDescriptor -*******************************/ - -PipeDescriptor::~PipeDescriptor() NO_EXCEPT_FALSE -{ - // Run down any stranded outbound data. - for (size_t i=0; i < OutboundPages.size(); i++) - OutboundPages[i].Free(); - - /* As a virtual destructor, we come here before the base-class - * destructor that closes our file-descriptor. - * We have to make sure the subprocess goes down (if it's not - * already down) and we have to reap the zombie. - * - * This implementation is PROVISIONAL and will surely be improved. - * The intention here is that we never block, hence the highly - * undesirable sleeps. But if we can't reap the subprocess even - * after sending it SIGKILL, then something is wrong and we - * throw a fatal exception, which is also not something we should - * be doing. - * - * Eventually the right thing to do will be to have the reactor - * core respond to SIGCHLD by chaining a handler on top of the - * one Ruby may have installed, and dealing with a list of dead - * children that are pending cleanup. - * - * Since we want to have a signal processor integrated into the - * client-visible API, let's wait until that is done before cleaning - * this up. - * - * Added a very ugly hack to support passing the subprocess's exit - * status to the user. It only makes logical sense for user code to access - * the subprocess exit status in the unbind callback. But unbind is called - * back during the EventableDescriptor destructor. So by that time there's - * no way to call back this object through an object binding, because it's - * already been cleaned up. We might have added a parameter to the unbind - * callback, but that would probably break a huge amount of existing code. - * So the hack-solution is to define an instance variable in the EventMachine - * object and stick the exit status in there, where it can easily be accessed - * with an accessor visible to user code. - * User code should ONLY access the exit status from within the unbind callback. - * Otherwise there's no guarantee it'll be valid. - * This hack won't make it impossible to run multiple EventMachines in a single - * process, but it will make it impossible to reliably nest unbind calls - * within other unbind calls. (Not sure if that's even possible.) - */ - - assert (MyEventMachine); - - /* Another hack to make the SubprocessPid available to get_subprocess_status */ - MyEventMachine->SubprocessPid = SubprocessPid; - - /* 01Mar09: Updated to use a small nanosleep in a loop. When nanosleep is interrupted by SIGCHLD, - * it resumes the system call after processing the signal (resulting in unnecessary latency). - * Calling nanosleep in a loop avoids this problem. - */ - struct timespec req = {0, 50000000}; // 0.05s - int n; - - // wait 0.5s for the process to die - for (n=0; n<10; n++) { - if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return; - nanosleep (&req, NULL); - } - - // send SIGTERM and wait another 1s - kill (SubprocessPid, SIGTERM); - for (n=0; n<20; n++) { - nanosleep (&req, NULL); - if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return; - } - - // send SIGKILL and wait another 5s - kill (SubprocessPid, SIGKILL); - for (n=0; n<100; n++) { - nanosleep (&req, NULL); - if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) != 0) return; - } - - // still not dead, give up! - throw std::runtime_error ("unable to reap subprocess"); -} - - - -/******************** -PipeDescriptor::Read -********************/ - -void PipeDescriptor::Read() -{ - int sd = GetSocket(); - if (sd == INVALID_SOCKET) { - assert (!bReadAttemptedAfterClose); - bReadAttemptedAfterClose = true; - return; - } - - LastActivity = MyEventMachine->GetCurrentLoopTime(); - - int total_bytes_read = 0; - char readbuffer [16 * 1024]; - - for (int i=0; i < 10; i++) { - // Don't read just one buffer and then move on. This is faster - // if there is a lot of incoming. - // But don't read indefinitely. Give other sockets a chance to run. - // NOTICE, we're reading one less than the buffer size. - // That's so we can put a guard byte at the end of what we send - // to user code. - // Use read instead of recv, which on Linux gives a "socket operation - // on nonsocket" error. - - - int r = read (sd, readbuffer, sizeof(readbuffer) - 1); - //cerr << ""; - - if (r > 0) { - total_bytes_read += r; - - // Add a null-terminator at the the end of the buffer - // that we will send to the callback. - // DO NOT EVER CHANGE THIS. We want to explicitly allow users - // to be able to depend on this behavior, so they will have - // the option to do some things faster. Additionally it's - // a security guard against buffer overflows. - readbuffer [r] = 0; - _GenericInboundDispatch(readbuffer, r); - } - else if (r == 0) { - break; - } - else { - // Basically a would-block, meaning we've read everything there is to read. - break; - } - - } - - - if (total_bytes_read == 0) { - // If we read no data on a socket that selected readable, - // it generally means the other end closed the connection gracefully. - ScheduleClose (false); - //bCloseNow = true; - } - -} - -/********************* -PipeDescriptor::Write -*********************/ - -void PipeDescriptor::Write() -{ - int sd = GetSocket(); - assert (sd != INVALID_SOCKET); - - LastActivity = MyEventMachine->GetCurrentLoopTime(); - char output_buffer [16 * 1024]; - size_t nbytes = 0; - - while ((OutboundPages.size() > 0) && (nbytes < sizeof(output_buffer))) { - OutboundPage *op = &(OutboundPages[0]); - if ((nbytes + op->Length - op->Offset) < sizeof (output_buffer)) { - memcpy (output_buffer + nbytes, op->Buffer + op->Offset, op->Length - op->Offset); - nbytes += (op->Length - op->Offset); - op->Free(); - OutboundPages.pop_front(); - } - else { - int len = sizeof(output_buffer) - nbytes; - memcpy (output_buffer + nbytes, op->Buffer + op->Offset, len); - op->Offset += len; - nbytes += len; - } - } - - // We should never have gotten here if there were no data to write, - // so assert that as a sanity check. - // Don't bother to make sure nbytes is less than output_buffer because - // if it were we probably would have crashed already. - assert (nbytes > 0); - - assert (GetSocket() != INVALID_SOCKET); - int bytes_written = write (GetSocket(), output_buffer, nbytes); -#ifdef OS_WIN32 - int e = WSAGetLastError(); -#else - int e = errno; -#endif - - if (bytes_written > 0) { - OutboundDataSize -= bytes_written; - if ((size_t)bytes_written < nbytes) { - int len = nbytes - bytes_written; - char *buffer = (char*) malloc (len + 1); - if (!buffer) - throw std::runtime_error ("bad alloc throwing back data"); - memcpy (buffer, output_buffer + bytes_written, len); - buffer [len] = 0; - OutboundPages.push_front (OutboundPage (buffer, len)); - } - #ifdef HAVE_EPOLL - EpollEvent.events = EPOLLIN; - if (SelectForWrite()) - EpollEvent.events |= EPOLLOUT; - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - } - else { - #ifdef OS_UNIX - if ((e != EINPROGRESS) && (e != EWOULDBLOCK) && (e != EINTR)) - #endif - #ifdef OS_WIN32 - if ((e != WSAEINPROGRESS) && (e != WSAEWOULDBLOCK)) - #endif - Close(); - } -} - - -/************************* -PipeDescriptor::Heartbeat -*************************/ - -void PipeDescriptor::Heartbeat() -{ - // If an inactivity timeout is defined, then check for it. - if (InactivityTimeout && ((MyEventMachine->GetCurrentLoopTime() - LastActivity) >= InactivityTimeout)) - ScheduleClose (false); - //bCloseNow = true; -} - - -/***************************** -PipeDescriptor::SelectForRead -*****************************/ - -bool PipeDescriptor::SelectForRead() -{ - /* Pipe descriptors, being local by definition, don't have - * a pending state, so this is simpler than for the - * ConnectionDescriptor object. - */ - return bPaused ? false : true; -} - -/****************************** -PipeDescriptor::SelectForWrite -******************************/ - -bool PipeDescriptor::SelectForWrite() -{ - /* Pipe descriptors, being local by definition, don't have - * a pending state, so this is simpler than for the - * ConnectionDescriptor object. - */ - return (GetOutboundDataSize() > 0) && !bPaused ? true : false; -} - - - - -/******************************** -PipeDescriptor::SendOutboundData -********************************/ - -int PipeDescriptor::SendOutboundData (const char *data, unsigned long length) -{ - //if (bCloseNow || bCloseAfterWriting) - if (IsCloseScheduled()) - return 0; - - if (!data && (length > 0)) - throw std::runtime_error ("bad outbound data"); - char *buffer = (char *) malloc (length + 1); - if (!buffer) - throw std::runtime_error ("no allocation for outbound data"); - memcpy (buffer, data, length); - buffer [length] = 0; - OutboundPages.push_back (OutboundPage (buffer, length)); - OutboundDataSize += length; - #ifdef HAVE_EPOLL - EpollEvent.events = (EPOLLIN | EPOLLOUT); - assert (MyEventMachine); - MyEventMachine->Modify (this); - #endif - return length; -} - -/******************************** -PipeDescriptor::GetSubprocessPid -********************************/ - -bool PipeDescriptor::GetSubprocessPid (pid_t *pid) -{ - bool ok = false; - if (pid && (SubprocessPid > 0)) { - *pid = SubprocessPid; - ok = true; - } - return ok; -} - - -#endif // OS_UNIX - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/project.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/project.h deleted file mode 100644 index 757f701..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/project.h +++ /dev/null @@ -1,174 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: project.h -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#ifndef __Project__H_ -#define __Project__H_ - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef OS_UNIX -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#ifdef OS_SOLARIS8 -#include -#include -#ifndef AF_LOCAL -#define AF_LOCAL AF_UNIX -#endif -// INADDR_NONE is undefined on Solaris < 8. Thanks to Brett Eisenberg and Tim Pease. -#ifndef INADDR_NONE -#define INADDR_NONE ((unsigned long)-1) -#endif -#endif /* OS_SOLARIS8 */ - -#ifdef _AIX -#include -#ifndef AF_LOCAL -#define AF_LOCAL AF_UNIX -#endif -#endif /* _AIX */ - -#ifdef OS_DARWIN -#include -#include -#endif /* OS_DARWIN */ - -#endif /* OS_UNIX */ - -#ifdef OS_WIN32 -// 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h) -// 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333 -//#define FD_SETSIZE 1024 - -// WIN32_LEAN_AND_MEAN excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets. -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include - -// Older versions of MinGW in the Ruby Dev Kit do not provide the getaddrinfo hint flags -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0x0400 -#endif - -#ifndef AI_NUMERICSERV -#define AI_NUMERICSERV 0x0008 -#endif - -// Use the Win32 wrapper library that Ruby owns to be able to close sockets with the close() function -#define RUBY_EXPORT -#include -#include -#endif /* OS_WIN32 */ - -#if !defined(_MSC_VER) || _MSC_VER > 1500 -#include -#endif - -#ifdef WITH_SSL -#include -#include -#endif - -#ifdef HAVE_EPOLL -#include -#endif - -#ifdef HAVE_KQUEUE -#include -#include -#endif - -#ifdef HAVE_INOTIFY -#include -#endif - -#ifdef HAVE_OLD_INOTIFY -#include -#include -static inline int inotify_init (void) { return syscall (__NR_inotify_init); } -static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); } -static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); } -#define HAVE_INOTIFY 1 -#endif - -#ifdef HAVE_INOTIFY -#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event)) -#endif - -#ifdef HAVE_WRITEV -#include -#endif - -#if __cplusplus -extern "C" { -#endif - typedef void (*EMCallback)(const unsigned long, int, const char*, const unsigned long); -#if __cplusplus -} -#endif - -#if defined(__GNUC__) && (__GNUC__ >= 3) -#define UNUSED __attribute__ ((unused)) -#else -#define UNUSED -#endif - -#include "binder.h" -#include "em.h" -#include "ed.h" -#include "page.h" -#include "ssl.h" -#include "eventmachine.h" - -#endif // __Project__H_ diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/rubymain.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/rubymain.cpp deleted file mode 100644 index 305f9cb..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/rubymain.cpp +++ /dev/null @@ -1,1515 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: rubymain.cpp -Date: 06Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - -#include "project.h" -#include "eventmachine.h" -#include - -#ifndef RFLOAT_VALUE -#define RFLOAT_VALUE(arg) RFLOAT(arg)->value -#endif - -/* Adapted from NUM2BSIG / BSIG2NUM in ext/fiddle/conversions.h, - * we'll call it a BSIG for Binding Signature here. */ -#if SIZEOF_VOIDP == SIZEOF_LONG -# define BSIG2NUM(x) (ULONG2NUM((unsigned long)(x))) -# define NUM2BSIG(x) (NUM2ULONG(x)) -# ifdef OS_WIN32 -# define PRIFBSIG "I32u" -# else -# define PRIFBSIG "lu" -# endif -#else -# define BSIG2NUM(x) (ULL2NUM((unsigned long long)(x))) -# define NUM2BSIG(x) (NUM2ULL(x)) -# ifdef OS_WIN32 -# define PRIFBSIG "I64u" -# else -# define PRIFBSIG "llu" -# endif -#endif - -/******* -Statics -*******/ - -static VALUE EmModule; -static VALUE EmConnection; -static VALUE EmConnsHash; -static VALUE EmTimersHash; - -static VALUE EM_eConnectionError; -static VALUE EM_eUnknownTimerFired; -static VALUE EM_eConnectionNotBound; -static VALUE EM_eUnsupported; -static VALUE EM_eInvalidSignature; - -static VALUE Intern_at_signature; -static VALUE Intern_at_timers; -static VALUE Intern_at_conns; -static VALUE Intern_at_error_handler; -static VALUE Intern_event_callback; -static VALUE Intern_run_deferred_callbacks; -static VALUE Intern_delete; -static VALUE Intern_call; -static VALUE Intern_at; -static VALUE Intern_receive_data; -static VALUE Intern_ssl_handshake_completed; -static VALUE Intern_ssl_verify_peer; -static VALUE Intern_notify_readable; -static VALUE Intern_notify_writable; -static VALUE Intern_proxy_target_unbound; -static VALUE Intern_proxy_completed; -static VALUE Intern_connection_completed; - -static VALUE rb_cProcStatus; - -struct em_event { - uintptr_t signature; - int event; - const char *data_str; - unsigned long data_num; -}; - -static inline VALUE ensure_conn(const uintptr_t signature) -{ - VALUE conn = rb_hash_aref (EmConnsHash, BSIG2NUM (signature)); - if (conn == Qnil) - rb_raise (EM_eConnectionNotBound, "unknown connection: %" PRIFBSIG, signature); - return conn; -} - - -/**************** -t_event_callback -****************/ - -static inline void event_callback (struct em_event* e) -{ - const uintptr_t signature = e->signature; - int event = e->event; - const char *data_str = e->data_str; - const unsigned long data_num = e->data_num; - - switch (event) { - case EM_CONNECTION_READ: - { - VALUE conn = rb_hash_aref (EmConnsHash, BSIG2NUM (signature)); - if (conn == Qnil) - rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %" PRIFBSIG, data_num, signature); - rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num)); - return; - } - case EM_CONNECTION_ACCEPTED: - { - rb_funcall (EmModule, Intern_event_callback, 3, BSIG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num)); - return; - } - case EM_CONNECTION_UNBOUND: - { - rb_funcall (EmModule, Intern_event_callback, 3, BSIG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num)); - return; - } - case EM_CONNECTION_COMPLETED: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_connection_completed, 0); - return; - } - case EM_CONNECTION_NOTIFY_READABLE: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_notify_readable, 0); - return; - } - case EM_CONNECTION_NOTIFY_WRITABLE: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_notify_writable, 0); - return; - } - case EM_LOOPBREAK_SIGNAL: - { - rb_funcall (EmModule, Intern_run_deferred_callbacks, 0); - return; - } - case EM_TIMER_FIRED: - { - VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num)); - if (timer == Qnil) { - rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num); - } else if (timer == Qfalse) { - /* Timer Canceled */ - } else { - rb_funcall (timer, Intern_call, 0); - } - return; - } - #ifdef WITH_SSL - case EM_SSL_HANDSHAKE_COMPLETED: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_ssl_handshake_completed, 0); - return; - } - case EM_SSL_VERIFY: - { - VALUE conn = ensure_conn(signature); - VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num)); - if (RTEST(should_accept)) - evma_accept_ssl_peer (signature); - return; - } - #endif - case EM_PROXY_TARGET_UNBOUND: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_proxy_target_unbound, 0); - return; - } - case EM_PROXY_COMPLETED: - { - VALUE conn = ensure_conn(signature); - rb_funcall (conn, Intern_proxy_completed, 0); - return; - } - } -} - -/******************* -event_error_handler -*******************/ - -static void event_error_handler(VALUE self UNUSED, VALUE err) -{ - VALUE error_handler = rb_ivar_get(EmModule, Intern_at_error_handler); - rb_funcall (error_handler, Intern_call, 1, err); -} - -/********************** -event_callback_wrapper -**********************/ - -static void event_callback_wrapper (const uintptr_t signature, int event, const char *data_str, const unsigned long data_num) -{ - struct em_event e; - e.signature = signature; - e.event = event; - e.data_str = data_str; - e.data_num = data_num; - - if (!rb_ivar_defined(EmModule, Intern_at_error_handler)) - event_callback(&e); - else - rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler, Qnil); -} - -/************************** -t_initialize_event_machine -**************************/ - -static VALUE t_initialize_event_machine (VALUE self UNUSED) -{ - EmConnsHash = rb_ivar_get (EmModule, Intern_at_conns); - EmTimersHash = rb_ivar_get (EmModule, Intern_at_timers); - assert(EmConnsHash != Qnil); - assert(EmTimersHash != Qnil); - evma_initialize_library ((EMCallback)event_callback_wrapper); - return Qnil; -} - - -/****************** -t_run_machine_once -******************/ - -static VALUE t_run_machine_once (VALUE self UNUSED) -{ - return evma_run_machine_once () ? Qtrue : Qfalse; -} - - -/************* -t_run_machine -*************/ - -static VALUE t_run_machine (VALUE self UNUSED) -{ - evma_run_machine(); - return Qnil; -} - - -/******************* -t_add_oneshot_timer -*******************/ - -static VALUE t_add_oneshot_timer (VALUE self UNUSED, VALUE interval) -{ - const uintptr_t f = evma_install_oneshot_timer (FIX2LONG (interval)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "ran out of timers; use #set_max_timers to increase limit"); - return BSIG2NUM (f); -} - - -/************** -t_start_server -**************/ - -static VALUE t_start_server (VALUE self UNUSED, VALUE server, VALUE port) -{ - const uintptr_t f = evma_create_tcp_server (StringValueCStr(server), FIX2INT(port)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no acceptor (port is in use or requires root privileges)"); - return BSIG2NUM (f); -} - -/************* -t_stop_server -*************/ - -static VALUE t_stop_server (VALUE self UNUSED, VALUE signature) -{ - evma_stop_tcp_server (NUM2BSIG (signature)); - return Qnil; -} - - -/******************* -t_start_unix_server -*******************/ - -static VALUE t_start_unix_server (VALUE self UNUSED, VALUE filename) -{ - const uintptr_t f = evma_create_unix_domain_server (StringValueCStr(filename)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no unix-domain acceptor"); - return BSIG2NUM (f); -} - -/******************** -t_attach_sd -********************/ - -static VALUE t_attach_sd(VALUE self UNUSED, VALUE sd) -{ - const uintptr_t f = evma_attach_sd(FIX2INT(sd)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no socket descriptor acceptor"); - return BSIG2NUM (f); -} - - -/*********** -t_send_data -***********/ - -static VALUE t_send_data (VALUE self UNUSED, VALUE signature, VALUE data, VALUE data_length) -{ - int b = evma_send_data_to_connection (NUM2BSIG (signature), StringValuePtr (data), FIX2INT (data_length)); - return INT2NUM (b); -} - - -/*********** -t_start_tls -***********/ - -static VALUE t_start_tls (VALUE self UNUSED, VALUE signature) -{ - evma_start_tls (NUM2BSIG (signature)); - return Qnil; -} - -/*************** -t_set_tls_parms -***************/ - -static VALUE t_set_tls_parms (VALUE self UNUSED, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer, VALUE fail_if_no_peer_cert, VALUE snihostname, VALUE cipherlist, VALUE ecdh_curve, VALUE dhparam, VALUE ssl_version) -{ - /* set_tls_parms takes a series of positional arguments for specifying such things - * as private keys and certificate chains. - * It's expected that the parameter list will grow as we add more supported features. - * ALL of these parameters are optional, and can be specified as empty or NULL strings. - */ - evma_set_tls_parms (NUM2BSIG (signature), StringValueCStr (privkeyfile), StringValueCStr (certchainfile), (verify_peer == Qtrue ? 1 : 0), (fail_if_no_peer_cert == Qtrue ? 1 : 0), StringValueCStr (snihostname), StringValueCStr (cipherlist), StringValueCStr (ecdh_curve), StringValueCStr (dhparam), NUM2INT (ssl_version)); - return Qnil; -} - -/*************** -t_get_peer_cert -***************/ - -#ifdef WITH_SSL -static VALUE t_get_peer_cert (VALUE self UNUSED, VALUE signature) -{ - VALUE ret = Qnil; - - X509 *cert = NULL; - BUF_MEM *buf; - BIO *out; - - cert = evma_get_peer_cert (NUM2BSIG (signature)); - - if (cert != NULL) { - out = BIO_new(BIO_s_mem()); - PEM_write_bio_X509(out, cert); - BIO_get_mem_ptr(out, &buf); - ret = rb_str_new(buf->data, buf->length); - X509_free(cert); - BIO_free(out); - } - - return ret; -} -#else -static VALUE t_get_peer_cert (VALUE self UNUSED, VALUE signature UNUSED) -{ - return Qnil; -} -#endif - -/*************** -t_get_cipher_bits -***************/ - -#ifdef WITH_SSL -static VALUE t_get_cipher_bits (VALUE self UNUSED, VALUE signature) -{ - int bits = evma_get_cipher_bits (NUM2BSIG (signature)); - if (bits == -1) - return Qnil; - return INT2NUM (bits); -} -#else -static VALUE t_get_cipher_bits (VALUE self UNUSED, VALUE signature UNUSED) -{ - return Qnil; -} -#endif - -/*************** -t_get_cipher_name -***************/ - -#ifdef WITH_SSL -static VALUE t_get_cipher_name (VALUE self UNUSED, VALUE signature) -{ - const char *protocol = evma_get_cipher_name (NUM2BSIG (signature)); - if (protocol) - return rb_str_new2 (protocol); - - return Qnil; -} -#else -static VALUE t_get_cipher_name (VALUE self UNUSED, VALUE signature UNUSED) -{ - return Qnil; -} -#endif - -/*************** -t_get_cipher_protocol -***************/ - -#ifdef WITH_SSL -static VALUE t_get_cipher_protocol (VALUE self UNUSED, VALUE signature) -{ - const char *cipher = evma_get_cipher_protocol (NUM2BSIG (signature)); - if (cipher) - return rb_str_new2 (cipher); - - return Qnil; -} -#else -static VALUE t_get_cipher_protocol (VALUE self UNUSED, VALUE signature UNUSED) -{ - return Qnil; -} -#endif - -/*************** -t_get_sni_hostname -***************/ - -#ifdef WITH_SSL -static VALUE t_get_sni_hostname (VALUE self UNUSED, VALUE signature) -{ - const char *sni_hostname = evma_get_sni_hostname (NUM2BSIG (signature)); - if (sni_hostname) - return rb_str_new2 (sni_hostname); - - return Qnil; -} -#else -static VALUE t_get_sni_hostname (VALUE self UNUSED, VALUE signature UNUSED) -{ - return Qnil; -} -#endif - -/************** -t_get_peername -**************/ - -static VALUE t_get_peername (VALUE self UNUSED, VALUE signature) -{ - char buf[1024]; - socklen_t len = sizeof buf; - try { - if (evma_get_peername (NUM2BSIG (signature), (struct sockaddr*)buf, &len)) { - return rb_str_new (buf, len); - } - } catch (std::runtime_error e) { - rb_raise (rb_eRuntimeError, "%s", e.what()); - } - - return Qnil; -} - -/************** -t_get_sockname -**************/ - -static VALUE t_get_sockname (VALUE self UNUSED, VALUE signature) -{ - char buf[1024]; - socklen_t len = sizeof buf; - try { - if (evma_get_sockname (NUM2BSIG (signature), (struct sockaddr*)buf, &len)) { - return rb_str_new (buf, len); - } - } catch (std::runtime_error e) { - rb_raise (rb_eRuntimeError, "%s", e.what()); - } - - return Qnil; -} - -/******************** -t_get_subprocess_pid -********************/ - -static VALUE t_get_subprocess_pid (VALUE self UNUSED, VALUE signature) -{ - pid_t pid; - if (evma_get_subprocess_pid (NUM2BSIG (signature), &pid)) { - return INT2NUM (pid); - } - - return Qnil; -} - -/*********************** -t_get_subprocess_status -***********************/ - -static VALUE t_get_subprocess_status (VALUE self UNUSED, VALUE signature) -{ - VALUE proc_status = Qnil; - - int status; - pid_t pid; - - if (evma_get_subprocess_status (NUM2BSIG (signature), &status)) { - if (evma_get_subprocess_pid (NUM2BSIG (signature), &pid)) { - proc_status = rb_obj_alloc(rb_cProcStatus); - - /* MRI Ruby uses hidden instance vars */ - rb_iv_set(proc_status, "status", INT2FIX(status)); - rb_iv_set(proc_status, "pid", INT2FIX(pid)); - -#ifdef RUBINIUS - /* Rubinius uses standard instance vars */ - rb_iv_set(proc_status, "@pid", INT2FIX(pid)); - if (WIFEXITED(status)) { - rb_iv_set(proc_status, "@status", INT2FIX(WEXITSTATUS(status))); - } else if (WIFSIGNALED(status)) { - rb_iv_set(proc_status, "@termsig", INT2FIX(WTERMSIG(status))); - } else if (WIFSTOPPED(status)) { - rb_iv_set(proc_status, "@stopsig", INT2FIX(WSTOPSIG(status))); - } -#endif - } - } - - return proc_status; -} - -/********************** -t_get_connection_count -**********************/ - -static VALUE t_get_connection_count (VALUE self UNUSED) -{ - return INT2NUM(evma_get_connection_count()); -} - -/***************************** -t_get_comm_inactivity_timeout -*****************************/ - -static VALUE t_get_comm_inactivity_timeout (VALUE self UNUSED, VALUE signature) -{ - return rb_float_new(evma_get_comm_inactivity_timeout(NUM2BSIG (signature))); -} - -/***************************** -t_set_comm_inactivity_timeout -*****************************/ - -static VALUE t_set_comm_inactivity_timeout (VALUE self UNUSED, VALUE signature, VALUE timeout) -{ - float ti = RFLOAT_VALUE(timeout); - if (evma_set_comm_inactivity_timeout(NUM2BSIG(signature), ti)) { - return Qtrue; - } - return Qfalse; -} - -/***************************** -t_get_pending_connect_timeout -*****************************/ - -static VALUE t_get_pending_connect_timeout (VALUE self UNUSED, VALUE signature) -{ - return rb_float_new(evma_get_pending_connect_timeout(NUM2BSIG (signature))); -} - -/***************************** -t_set_pending_connect_timeout -*****************************/ - -static VALUE t_set_pending_connect_timeout (VALUE self UNUSED, VALUE signature, VALUE timeout) -{ - float ti = RFLOAT_VALUE(timeout); - if (evma_set_pending_connect_timeout(NUM2BSIG(signature), ti)) { - return Qtrue; - } - return Qfalse; -} - -/*************** -t_send_datagram -***************/ - -static VALUE t_send_datagram (VALUE self UNUSED, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port) -{ - int b = evma_send_datagram (NUM2BSIG (signature), StringValuePtr (data), FIX2INT (data_length), StringValueCStr(address), FIX2INT(port)); - if (b < 0) - rb_raise (EM_eConnectionError, "%s", "error in sending datagram"); // FIXME: this could be more specific. - return INT2NUM (b); -} - - -/****************** -t_close_connection -******************/ - -static VALUE t_close_connection (VALUE self UNUSED, VALUE signature, VALUE after_writing) -{ - evma_close_connection (NUM2BSIG (signature), ((after_writing == Qtrue) ? 1 : 0)); - return Qnil; -} - -/******************************** -t_report_connection_error_status -********************************/ - -static VALUE t_report_connection_error_status (VALUE self UNUSED, VALUE signature) -{ - int b = evma_report_connection_error_status (NUM2BSIG (signature)); - return INT2NUM (b); -} - - - -/**************** -t_connect_server -****************/ - -static VALUE t_connect_server (VALUE self UNUSED, VALUE server, VALUE port) -{ - // Avoid FIX2INT in this case, because it doesn't deal with type errors properly. - // Specifically, if the value of port comes in as a string rather than an integer, - // NUM2INT will throw a type error, but FIX2INT will generate garbage. - - try { - const uintptr_t f = evma_connect_to_server (NULL, 0, StringValueCStr(server), NUM2INT(port)); - if (!f) - rb_raise (EM_eConnectionError, "%s", "no connection"); - return BSIG2NUM (f); - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - -/********************* -t_bind_connect_server -*********************/ - -static VALUE t_bind_connect_server (VALUE self UNUSED, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port) -{ - // Avoid FIX2INT in this case, because it doesn't deal with type errors properly. - // Specifically, if the value of port comes in as a string rather than an integer, - // NUM2INT will throw a type error, but FIX2INT will generate garbage. - - try { - const uintptr_t f = evma_connect_to_server (StringValueCStr(bind_addr), NUM2INT(bind_port), StringValueCStr(server), NUM2INT(port)); - if (!f) - rb_raise (EM_eConnectionError, "%s", "no connection"); - return BSIG2NUM (f); - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - -/********************* -t_connect_unix_server -*********************/ - -static VALUE t_connect_unix_server (VALUE self UNUSED, VALUE serversocket) -{ - const uintptr_t f = evma_connect_to_unix_server (StringValueCStr(serversocket)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no connection"); - return BSIG2NUM (f); -} - -/*********** -t_attach_fd -***********/ - -static VALUE t_attach_fd (VALUE self UNUSED, VALUE file_descriptor, VALUE watch_mode) -{ - const uintptr_t f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no connection"); - return BSIG2NUM (f); -} - -/*********** -t_detach_fd -***********/ - -static VALUE t_detach_fd (VALUE self UNUSED, VALUE signature) -{ - return INT2NUM(evma_detach_fd (NUM2BSIG (signature))); -} - -/********************* -t_get_file_descriptor -*********************/ -static VALUE t_get_file_descriptor (VALUE self UNUSED, VALUE signature) -{ - return INT2NUM(evma_get_file_descriptor (NUM2BSIG (signature))); -} - -/************** -t_get_sock_opt -**************/ - -static VALUE t_get_sock_opt (VALUE self UNUSED, VALUE signature, VALUE lev, VALUE optname) -{ - int fd = evma_get_file_descriptor (NUM2BSIG (signature)); - int level = NUM2INT(lev), option = NUM2INT(optname); - socklen_t len = 128; - char buf[128]; - - if (getsockopt(fd, level, option, buf, &len) < 0) - rb_sys_fail("getsockopt"); - - return rb_str_new(buf, len); -} - -/************** -t_set_sock_opt -**************/ - -static VALUE t_set_sock_opt (VALUE self UNUSED, VALUE signature, VALUE lev, VALUE optname, VALUE optval) -{ - int fd = evma_get_file_descriptor (NUM2BSIG (signature)); - int level = NUM2INT(lev), option = NUM2INT(optname); - int i; - const void *v; - socklen_t len; - - switch (TYPE(optval)) { - case T_FIXNUM: - i = FIX2INT(optval); - goto numval; - case T_FALSE: - i = 0; - goto numval; - case T_TRUE: - i = 1; - numval: - v = (void*)&i; len = sizeof(i); - break; - default: - StringValue(optval); - v = RSTRING_PTR(optval); - len = RSTRING_LENINT(optval); - break; - } - - - if (setsockopt(fd, level, option, (char *)v, len) < 0) - rb_sys_fail("setsockopt"); - - return INT2FIX(0); -} - -/******************** -t_is_notify_readable -********************/ - -static VALUE t_is_notify_readable (VALUE self UNUSED, VALUE signature) -{ - return evma_is_notify_readable(NUM2BSIG (signature)) ? Qtrue : Qfalse; -} - -/********************* -t_set_notify_readable -*********************/ - -static VALUE t_set_notify_readable (VALUE self UNUSED, VALUE signature, VALUE mode) -{ - evma_set_notify_readable(NUM2BSIG(signature), mode == Qtrue); - return Qnil; -} - -/******************** -t_is_notify_readable -********************/ - -static VALUE t_is_notify_writable (VALUE self UNUSED, VALUE signature) -{ - return evma_is_notify_writable(NUM2BSIG (signature)) ? Qtrue : Qfalse; -} - -/********************* -t_set_notify_writable -*********************/ - -static VALUE t_set_notify_writable (VALUE self UNUSED, VALUE signature, VALUE mode) -{ - evma_set_notify_writable(NUM2BSIG (signature), mode == Qtrue); - return Qnil; -} - -/******* -t_pause -*******/ - -static VALUE t_pause (VALUE self UNUSED, VALUE signature) -{ - return evma_pause(NUM2BSIG (signature)) ? Qtrue : Qfalse; -} - -/******** -t_resume -********/ - -static VALUE t_resume (VALUE self UNUSED, VALUE signature) -{ - return evma_resume(NUM2BSIG (signature)) ? Qtrue : Qfalse; -} - -/********** -t_paused_p -**********/ - -static VALUE t_paused_p (VALUE self UNUSED, VALUE signature) -{ - return evma_is_paused(NUM2BSIG (signature)) ? Qtrue : Qfalse; -} - -/********************* -t_num_close_scheduled -*********************/ - -static VALUE t_num_close_scheduled (VALUE self UNUSED) -{ - return INT2FIX(evma_num_close_scheduled()); -} - -/***************** -t_open_udp_socket -*****************/ - -static VALUE t_open_udp_socket (VALUE self UNUSED, VALUE server, VALUE port) -{ - const uintptr_t f = evma_open_datagram_socket (StringValueCStr(server), FIX2INT(port)); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no datagram socket"); - return BSIG2NUM(f); -} - - - -/***************** -t_release_machine -*****************/ - -static VALUE t_release_machine (VALUE self UNUSED) -{ - evma_release_library(); - return Qnil; -} - - -/****** -t_stop -******/ - -static VALUE t_stop (VALUE self UNUSED) -{ - evma_stop_machine(); - return Qnil; -} - -/****************** -t_signal_loopbreak -******************/ - -static VALUE t_signal_loopbreak (VALUE self UNUSED) -{ - evma_signal_loopbreak(); - return Qnil; -} - -/************** -t_library_type -**************/ - -static VALUE t_library_type (VALUE self UNUSED) -{ - return rb_eval_string (":extension"); -} - - - -/******************* -t_set_timer_quantum -*******************/ - -static VALUE t_set_timer_quantum (VALUE self UNUSED, VALUE interval) -{ - evma_set_timer_quantum (FIX2INT (interval)); - return Qnil; -} - -/******************** -t_get_max_timer_count -********************/ - -static VALUE t_get_max_timer_count (VALUE self UNUSED) -{ - return INT2FIX (evma_get_max_timer_count()); -} - -/******************** -t_set_max_timer_count -********************/ - -static VALUE t_set_max_timer_count (VALUE self UNUSED, VALUE ct) -{ - evma_set_max_timer_count (FIX2INT (ct)); - return Qnil; -} - -/******************** -t_get/set_simultaneous_accept_count -********************/ - -static VALUE t_get_simultaneous_accept_count (VALUE self UNUSED) -{ - return INT2FIX (evma_get_simultaneous_accept_count()); -} - -static VALUE t_set_simultaneous_accept_count (VALUE self UNUSED, VALUE ct) -{ - evma_set_simultaneous_accept_count (FIX2INT (ct)); - return Qnil; -} - -/*************** -t_setuid_string -***************/ - -static VALUE t_setuid_string (VALUE self UNUSED, VALUE username) -{ - evma_setuid_string (StringValueCStr (username)); - return Qnil; -} - - - -/************** -t_invoke_popen -**************/ - -static VALUE t_invoke_popen (VALUE self UNUSED, VALUE cmd) -{ - #ifdef OS_WIN32 - rb_raise (EM_eUnsupported, "popen is not available on this platform"); - #endif - - int len = RARRAY_LEN(cmd); - if (len >= 2048) - rb_raise (rb_eRuntimeError, "%s", "too many arguments to popen"); - char *strings [2048]; - for (int i=0; i < len; i++) { - VALUE ix = INT2FIX (i); - VALUE s = rb_ary_aref (1, &ix, cmd); - strings[i] = StringValueCStr (s); - } - strings[len] = NULL; - - uintptr_t f = 0; - try { - f = evma_popen (strings); - } catch (std::runtime_error e) { - rb_raise (rb_eRuntimeError, "%s", e.what()); - } - if (!f) { - char *err = strerror (errno); - char buf[100]; - memset (buf, 0, sizeof(buf)); - snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???")); - rb_raise (rb_eRuntimeError, "%s", buf); - } - return BSIG2NUM (f); -} - - -/*************** -t_read_keyboard -***************/ - -static VALUE t_read_keyboard (VALUE self UNUSED) -{ - const uintptr_t f = evma_open_keyboard(); - if (!f) - rb_raise (rb_eRuntimeError, "%s", "no keyboard reader"); - return BSIG2NUM (f); -} - - -/**************** -t_watch_filename -****************/ - -static VALUE t_watch_filename (VALUE self UNUSED, VALUE fname) -{ - try { - return BSIG2NUM(evma_watch_filename(StringValueCStr(fname))); - } catch (std::runtime_error e) { - rb_raise (EM_eUnsupported, "%s", e.what()); - } - return Qnil; -} - - -/****************** -t_unwatch_filename -******************/ - -static VALUE t_unwatch_filename (VALUE self UNUSED, VALUE sig) -{ - try { - evma_unwatch_filename(NUM2BSIG (sig)); - } catch (std::runtime_error e) { - rb_raise (EM_eInvalidSignature, "%s", e.what()); - } - - return Qnil; -} - - -/*********** -t_watch_pid -***********/ - -static VALUE t_watch_pid (VALUE self UNUSED, VALUE pid) -{ - try { - return BSIG2NUM(evma_watch_pid(NUM2INT(pid))); - } catch (std::runtime_error e) { - rb_raise (EM_eUnsupported, "%s", e.what()); - } - return Qnil; -} - - -/************* -t_unwatch_pid -*************/ - -static VALUE t_unwatch_pid (VALUE self UNUSED, VALUE sig) -{ - evma_unwatch_pid(NUM2BSIG (sig)); - return Qnil; -} - - -/********** -t__epoll_p -**********/ - -static VALUE t__epoll_p (VALUE self UNUSED) -{ - #ifdef HAVE_EPOLL - return Qtrue; - #else - return Qfalse; - #endif -} - -/******** -t__epoll -********/ - -static VALUE t__epoll (VALUE self UNUSED) -{ - if (t__epoll_p(self) == Qfalse) - return Qfalse; - - evma_set_epoll (1); - return Qtrue; -} - -/*********** -t__epoll_set -***********/ - -static VALUE t__epoll_set (VALUE self, VALUE val) -{ - if (t__epoll_p(self) == Qfalse && val == Qtrue) - rb_raise (EM_eUnsupported, "%s", "epoll is not supported on this platform"); - - evma_set_epoll (val == Qtrue ? 1 : 0); - return val; -} - - -/*********** -t__kqueue_p -***********/ - -static VALUE t__kqueue_p (VALUE self UNUSED) -{ - #ifdef HAVE_KQUEUE - return Qtrue; - #else - return Qfalse; - #endif -} - -/********* -t__kqueue -*********/ - -static VALUE t__kqueue (VALUE self UNUSED) -{ - if (t__kqueue_p(self) == Qfalse) - return Qfalse; - - evma_set_kqueue (1); - return Qtrue; -} - -/************* -t__kqueue_set -*************/ - -static VALUE t__kqueue_set (VALUE self, VALUE val) -{ - if (t__kqueue_p(self) == Qfalse && val == Qtrue) - rb_raise (EM_eUnsupported, "%s", "kqueue is not supported on this platform"); - - evma_set_kqueue (val == Qtrue ? 1 : 0); - return val; -} - - -/******** -t__ssl_p -********/ - -static VALUE t__ssl_p (VALUE self UNUSED) -{ - #ifdef WITH_SSL - return Qtrue; - #else - return Qfalse; - #endif -} - -/******** -t_stopping -********/ - -static VALUE t_stopping () -{ - if (evma_stopping()) { - return Qtrue; - } else { - return Qfalse; - } -} - - -/**************** -t_send_file_data -****************/ - -static VALUE t_send_file_data (VALUE self UNUSED, VALUE signature, VALUE filename) -{ - - /* The current implementation of evma_send_file_data_to_connection enforces a strict - * upper limit on the file size it will transmit (currently 32K). The function returns - * zero on success, -1 if the requested file exceeds its size limit, and a positive - * number for other errors. - * TODO: Positive return values are actually errno's, which is probably the wrong way to - * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno. - */ - - int b = evma_send_file_data_to_connection (NUM2BSIG (signature), StringValueCStr(filename)); - if (b == -1) - rb_raise(rb_eRuntimeError, "%s", "File too large. send_file_data() supports files under 32k."); - if (b > 0) { - char *err = strerror (b); - char buf[1024]; - memset (buf, 0, sizeof(buf)); - snprintf (buf, sizeof(buf)-1, ": %s %s", StringValueCStr(filename),(err?err:"???")); - - rb_raise (rb_eIOError, "%s", buf); - } - - return INT2NUM (0); -} - - -/******************* -t_set_rlimit_nofile -*******************/ - -static VALUE t_set_rlimit_nofile (VALUE self UNUSED, VALUE arg) -{ - arg = (NIL_P(arg)) ? -1 : NUM2INT (arg); - return INT2NUM (evma_set_rlimit_nofile (arg)); -} - -/*************************** -conn_get_outbound_data_size -***************************/ - -static VALUE conn_get_outbound_data_size (VALUE self) -{ - VALUE sig = rb_ivar_get (self, Intern_at_signature); - return INT2NUM (evma_get_outbound_data_size (NUM2BSIG (sig))); -} - - -/****************************** -conn_associate_callback_target -******************************/ - -static VALUE conn_associate_callback_target (VALUE self UNUSED, VALUE sig UNUSED) -{ - // No-op for the time being. - return Qnil; -} - - -/*************** -t_get_loop_time -****************/ - -static VALUE t_get_loop_time (VALUE self UNUSED) -{ - uint64_t current_time = evma_get_current_loop_time(); - if (current_time == 0) { - return Qnil; - } - - // Generally the industry has moved to 64-bit time_t, this is just in case we're 32-bit time_t. - if (sizeof(time_t) < 8 && current_time > INT_MAX) { - return rb_funcall(rb_cTime, Intern_at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000)); - } else { - return rb_time_new(current_time / 1000000, current_time % 1000000); - } -} - - -/************* -t_start_proxy -**************/ - -static VALUE t_start_proxy (VALUE self UNUSED, VALUE from, VALUE to, VALUE bufsize, VALUE length) -{ - try { - evma_start_proxy(NUM2BSIG (from), NUM2BSIG (to), NUM2ULONG(bufsize), NUM2ULONG(length)); - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - - -/************ -t_stop_proxy -*************/ - -static VALUE t_stop_proxy (VALUE self UNUSED, VALUE from) -{ - try{ - evma_stop_proxy(NUM2BSIG (from)); - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - -/*************** -t_proxied_bytes -****************/ - -static VALUE t_proxied_bytes (VALUE self UNUSED, VALUE from) -{ - try{ - return BSIG2NUM(evma_proxied_bytes(NUM2BSIG (from))); - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - -/*************** -t_get_idle_time -****************/ - -static VALUE t_get_idle_time (VALUE self UNUSED, VALUE from) -{ - try{ - uint64_t current_time = evma_get_current_loop_time(); - uint64_t time = evma_get_last_activity_time(NUM2BSIG (from)); - if (current_time != 0 && time != 0) { - if (time >= current_time) - return BSIG2NUM(0); - else { - uint64_t diff = current_time - time; - float seconds = diff / (1000.0*1000.0); - return rb_float_new(seconds); - } - return Qnil; - } - } catch (std::runtime_error e) { - rb_raise (EM_eConnectionError, "%s", e.what()); - } - return Qnil; -} - -/************************ -t_get_heartbeat_interval -*************************/ - -static VALUE t_get_heartbeat_interval (VALUE self UNUSED) -{ - return rb_float_new(evma_get_heartbeat_interval()); -} - - -/************************ -t_set_heartbeat_interval -*************************/ - -static VALUE t_set_heartbeat_interval (VALUE self UNUSED, VALUE interval) -{ - float iv = RFLOAT_VALUE(interval); - if (evma_set_heartbeat_interval(iv)) - return Qtrue; - return Qfalse; -} - - -/********************* -Init_rubyeventmachine -*********************/ - -extern "C" void Init_rubyeventmachine() -{ - // Lookup Process::Status for get_subprocess_status - VALUE rb_mProcess = rb_const_get(rb_cObject, rb_intern("Process")); - rb_cProcStatus = rb_const_get(rb_mProcess, rb_intern("Status")); - - // Tuck away some symbol values so we don't have to look 'em up every time we need 'em. - Intern_at_signature = rb_intern ("@signature"); - Intern_at_timers = rb_intern ("@timers"); - Intern_at_conns = rb_intern ("@conns"); - Intern_at_error_handler = rb_intern("@error_handler"); - - Intern_event_callback = rb_intern ("event_callback"); - Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks"); - Intern_delete = rb_intern ("delete"); - Intern_call = rb_intern ("call"); - Intern_at = rb_intern("at"); - Intern_receive_data = rb_intern ("receive_data"); - Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed"); - Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer"); - Intern_notify_readable = rb_intern ("notify_readable"); - Intern_notify_writable = rb_intern ("notify_writable"); - Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound"); - Intern_proxy_completed = rb_intern ("proxy_completed"); - Intern_connection_completed = rb_intern ("connection_completed"); - - // INCOMPLETE, we need to define class Connections inside module EventMachine - // run_machine and run_machine_without_threads are now identical. - // Must deprecate the without_threads variant. - EmModule = rb_define_module ("EventMachine"); - EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject); - - rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eRuntimeError); - EM_eConnectionError = rb_define_class_under (EmModule, "ConnectionError", rb_eRuntimeError); - EM_eConnectionNotBound = rb_define_class_under (EmModule, "ConnectionNotBound", rb_eRuntimeError); - EM_eUnknownTimerFired = rb_define_class_under (EmModule, "UnknownTimerFired", rb_eRuntimeError); - EM_eUnsupported = rb_define_class_under (EmModule, "Unsupported", rb_eRuntimeError); - EM_eInvalidSignature = rb_define_class_under (EmModule, "InvalidSignature", rb_eRuntimeError); - - rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0); - rb_define_module_function (EmModule, "run_machine_once", (VALUE(*)(...))t_run_machine_once, 0); - rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine, 0); - rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine, 0); - rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1); - rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2); - rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1); - rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1); - rb_define_module_function (EmModule, "attach_sd", (VALUE(*)(...))t_attach_sd, 1); - rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 10); - rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1); - rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1); - rb_define_module_function (EmModule, "get_cipher_bits", (VALUE(*)(...))t_get_cipher_bits, 1); - rb_define_module_function (EmModule, "get_cipher_name", (VALUE(*)(...))t_get_cipher_name, 1); - rb_define_module_function (EmModule, "get_cipher_protocol", (VALUE(*)(...))t_get_cipher_protocol, 1); - rb_define_module_function (EmModule, "get_sni_hostname", (VALUE(*)(...))t_get_sni_hostname, 1); - rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3); - rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5); - rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2); - rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1); - rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2); - rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4); - rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1); - - rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 2); - rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1); - rb_define_module_function (EmModule, "get_file_descriptor", (VALUE (*)(...))t_get_file_descriptor, 1); - rb_define_module_function (EmModule, "get_sock_opt", (VALUE (*)(...))t_get_sock_opt, 3); - rb_define_module_function (EmModule, "set_sock_opt", (VALUE (*)(...))t_set_sock_opt, 4); - rb_define_module_function (EmModule, "set_notify_readable", (VALUE (*)(...))t_set_notify_readable, 2); - rb_define_module_function (EmModule, "set_notify_writable", (VALUE (*)(...))t_set_notify_writable, 2); - rb_define_module_function (EmModule, "is_notify_readable", (VALUE (*)(...))t_is_notify_readable, 1); - rb_define_module_function (EmModule, "is_notify_writable", (VALUE (*)(...))t_is_notify_writable, 1); - - rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1); - rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1); - rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1); - rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0); - - rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4); - rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1); - rb_define_module_function (EmModule, "get_proxied_bytes", (VALUE (*)(...))t_proxied_bytes, 1); - - rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1); - rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1); - - rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1); - rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1); - - rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0); - - rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2); - rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0); - rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0); - rb_define_module_function (EmModule, "stop", (VALUE(*)(...))t_stop, 0); - rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0); - rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0); - rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1); - rb_define_module_function (EmModule, "get_max_timer_count", (VALUE(*)(...))t_get_max_timer_count, 0); - rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1); - rb_define_module_function (EmModule, "get_simultaneous_accept_count", (VALUE(*)(...))t_get_simultaneous_accept_count, 0); - rb_define_module_function (EmModule, "set_simultaneous_accept_count", (VALUE(*)(...))t_set_simultaneous_accept_count, 1); - rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1); - rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1); - rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2); - rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0); - rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1); - rb_define_module_function (EmModule, "get_idle_time", (VALUE(*)(...))t_get_idle_time, 1); - - rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1); - rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1); - rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1); - rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1); - rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1); - rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2); - rb_define_module_function (EmModule, "get_pending_connect_timeout", (VALUE(*)(...))t_get_pending_connect_timeout, 1); - rb_define_module_function (EmModule, "set_pending_connect_timeout", (VALUE(*)(...))t_set_pending_connect_timeout, 2); - rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1); - rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0); - - rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0); - rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1); - rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0); - - rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0); - rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1); - rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0); - - rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0); - rb_define_module_function(EmModule, "stopping?",(VALUE(*)(...))t_stopping, 0); - - rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0); - rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1); - - // Connection states - rb_define_const (EmModule, "TimerFired", INT2NUM(EM_TIMER_FIRED )); - rb_define_const (EmModule, "ConnectionData", INT2NUM(EM_CONNECTION_READ )); - rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(EM_CONNECTION_UNBOUND )); - rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(EM_CONNECTION_ACCEPTED )); - rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(EM_CONNECTION_COMPLETED )); - rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(EM_LOOPBREAK_SIGNAL )); - rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(EM_CONNECTION_NOTIFY_READABLE)); - rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(EM_CONNECTION_NOTIFY_WRITABLE)); - rb_define_const (EmModule, "SslHandshakeCompleted", INT2NUM(EM_SSL_HANDSHAKE_COMPLETED )); - rb_define_const (EmModule, "SslVerify", INT2NUM(EM_SSL_VERIFY )); - // EM_PROXY_TARGET_UNBOUND = 110, - // EM_PROXY_COMPLETED = 111 - - // SSL Protocols - rb_define_const (EmModule, "EM_PROTO_SSLv2", INT2NUM(EM_PROTO_SSLv2 )); - rb_define_const (EmModule, "EM_PROTO_SSLv3", INT2NUM(EM_PROTO_SSLv3 )); - rb_define_const (EmModule, "EM_PROTO_TLSv1", INT2NUM(EM_PROTO_TLSv1 )); - rb_define_const (EmModule, "EM_PROTO_TLSv1_1", INT2NUM(EM_PROTO_TLSv1_1)); - rb_define_const (EmModule, "EM_PROTO_TLSv1_2", INT2NUM(EM_PROTO_TLSv1_2)); -} - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.cpp b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.cpp deleted file mode 100644 index 8d5e038..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.cpp +++ /dev/null @@ -1,619 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: ssl.cpp -Date: 30Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#ifdef WITH_SSL - -#include "project.h" - - -bool SslContext_t::bLibraryInitialized = false; - - - -static void InitializeDefaultCredentials(); -static EVP_PKEY *DefaultPrivateKey = NULL; -static X509 *DefaultCertificate = NULL; - -static char PrivateMaterials[] = { -"-----BEGIN RSA PRIVATE KEY-----\n" -"MIICXAIBAAKBgQDCYYhcw6cGRbhBVShKmbWm7UVsEoBnUf0cCh8AX+MKhMxwVDWV\n" -"Igdskntn3cSJjRtmgVJHIK0lpb/FYHQB93Ohpd9/Z18pDmovfFF9nDbFF0t39hJ/\n" -"AqSzFB3GiVPoFFZJEE1vJqh+3jzsSF5K56bZ6azz38VlZgXeSozNW5bXkQIDAQAB\n" -"AoGALA89gIFcr6BIBo8N5fL3aNHpZXjAICtGav+kTUpuxSiaym9cAeTHuAVv8Xgk\n" -"H2Wbq11uz+6JMLpkQJH/WZ7EV59DPOicXrp0Imr73F3EXBfR7t2EQDYHPMthOA1D\n" -"I9EtCzvV608Ze90hiJ7E3guGrGppZfJ+eUWCPgy8CZH1vRECQQDv67rwV/oU1aDo\n" -"6/+d5nqjeW6mWkGqTnUU96jXap8EIw6B+0cUKskwx6mHJv+tEMM2748ZY7b0yBlg\n" -"w4KDghbFAkEAz2h8PjSJG55LwqmXih1RONSgdN9hjB12LwXL1CaDh7/lkEhq0PlK\n" -"PCAUwQSdM17Sl0Xxm2CZiekTSlwmHrtqXQJAF3+8QJwtV2sRJp8u2zVe37IeH1cJ\n" -"xXeHyjTzqZ2803fnjN2iuZvzNr7noOA1/Kp+pFvUZUU5/0G2Ep8zolPUjQJAFA7k\n" -"xRdLkzIx3XeNQjwnmLlncyYPRv+qaE3FMpUu7zftuZBnVCJnvXzUxP3vPgKTlzGa\n" -"dg5XivDRfsV+okY5uQJBAMV4FesUuLQVEKb6lMs7rzZwpeGQhFDRfywJzfom2TLn\n" -"2RdJQQ3dcgnhdVDgt5o1qkmsqQh8uJrJ9SdyLIaZQIc=\n" -"-----END RSA PRIVATE KEY-----\n" -"-----BEGIN CERTIFICATE-----\n" -"MIID6TCCA1KgAwIBAgIJANm4W/Tzs+s+MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD\n" -"VQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRYw\n" -"FAYDVQQKEw1TdGVhbWhlYXQubmV0MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEdMBsG\n" -"A1UEAxMUb3BlbmNhLnN0ZWFtaGVhdC5uZXQxKDAmBgkqhkiG9w0BCQEWGWVuZ2lu\n" -"ZWVyaW5nQHN0ZWFtaGVhdC5uZXQwHhcNMDYwNTA1MTcwNjAzWhcNMjQwMjIwMTcw\n" -"NjAzWjCBqjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQH\n" -"EwhOZXcgWW9yazEWMBQGA1UEChMNU3RlYW1oZWF0Lm5ldDEUMBIGA1UECxMLRW5n\n" -"aW5lZXJpbmcxHTAbBgNVBAMTFG9wZW5jYS5zdGVhbWhlYXQubmV0MSgwJgYJKoZI\n" -"hvcNAQkBFhllbmdpbmVlcmluZ0BzdGVhbWhlYXQubmV0MIGfMA0GCSqGSIb3DQEB\n" -"AQUAA4GNADCBiQKBgQDCYYhcw6cGRbhBVShKmbWm7UVsEoBnUf0cCh8AX+MKhMxw\n" -"VDWVIgdskntn3cSJjRtmgVJHIK0lpb/FYHQB93Ohpd9/Z18pDmovfFF9nDbFF0t3\n" -"9hJ/AqSzFB3GiVPoFFZJEE1vJqh+3jzsSF5K56bZ6azz38VlZgXeSozNW5bXkQID\n" -"AQABo4IBEzCCAQ8wHQYDVR0OBBYEFPJvPd1Fcmd8o/Tm88r+NjYPICCkMIHfBgNV\n" -"HSMEgdcwgdSAFPJvPd1Fcmd8o/Tm88r+NjYPICCkoYGwpIGtMIGqMQswCQYDVQQG\n" -"EwJVUzERMA8GA1UECBMITmV3IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRYwFAYD\n" -"VQQKEw1TdGVhbWhlYXQubmV0MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEdMBsGA1UE\n" -"AxMUb3BlbmNhLnN0ZWFtaGVhdC5uZXQxKDAmBgkqhkiG9w0BCQEWGWVuZ2luZWVy\n" -"aW5nQHN0ZWFtaGVhdC5uZXSCCQDZuFv087PrPjAMBgNVHRMEBTADAQH/MA0GCSqG\n" -"SIb3DQEBBQUAA4GBAC1CXey/4UoLgJiwcEMDxOvW74plks23090iziFIlGgcIhk0\n" -"Df6hTAs7H3MWww62ddvR8l07AWfSzSP5L6mDsbvq7EmQsmPODwb6C+i2aF3EDL8j\n" -"uw73m4YIGI0Zw2XdBpiOGkx2H56Kya6mJJe/5XORZedh1wpI7zki01tHYbcy\n" -"-----END CERTIFICATE-----\n"}; - -/* These private materials were made with: - * openssl req -new -x509 -keyout cakey.pem -out cacert.pem -nodes -days 6500 - * TODO: We need a full-blown capability to work with user-supplied - * keypairs and properly-signed certificates. - */ - - -/***************** -builtin_passwd_cb -*****************/ - -extern "C" int builtin_passwd_cb (char *buf UNUSED, int bufsize UNUSED, int rwflag UNUSED, void *userdata UNUSED) -{ - strcpy (buf, "kittycat"); - return 8; -} - -/**************************** -InitializeDefaultCredentials -****************************/ - -static void InitializeDefaultCredentials() -{ - BIO *bio = BIO_new_mem_buf (PrivateMaterials, -1); - assert (bio); - - if (DefaultPrivateKey) { - // we may come here in a restart. - EVP_PKEY_free (DefaultPrivateKey); - DefaultPrivateKey = NULL; - } - PEM_read_bio_PrivateKey (bio, &DefaultPrivateKey, builtin_passwd_cb, 0); - - if (DefaultCertificate) { - // we may come here in a restart. - X509_free (DefaultCertificate); - DefaultCertificate = NULL; - } - PEM_read_bio_X509 (bio, &DefaultCertificate, NULL, 0); - - BIO_free (bio); -} - - - -/************************** -SslContext_t::SslContext_t -**************************/ - -SslContext_t::SslContext_t (bool is_server, const std::string &privkeyfile, const std::string &certchainfile, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version) : - bIsServer (is_server), - pCtx (NULL), - PrivateKey (NULL), - Certificate (NULL) -{ - /* TODO: the usage of the specified private-key and cert-chain filenames only applies to - * client-side connections at this point. Server connections currently use the default materials. - * That needs to be fixed asap. - * Also, in this implementation, server-side connections use statically defined X-509 defaults. - * One thing I'm really not clear on is whether or not you have to explicitly free X509 and EVP_PKEY - * objects when we call our destructor, or whether just calling SSL_CTX_free is enough. - */ - - if (!bLibraryInitialized) { - bLibraryInitialized = true; - SSL_library_init(); - OpenSSL_add_ssl_algorithms(); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); - ERR_load_crypto_strings(); - - InitializeDefaultCredentials(); - } - - pCtx = SSL_CTX_new (bIsServer ? SSLv23_server_method() : SSLv23_client_method()); - if (!pCtx) - throw std::runtime_error ("no SSL context"); - - SSL_CTX_set_options (pCtx, SSL_OP_ALL); - - #ifdef SSL_CTRL_CLEAR_OPTIONS - SSL_CTX_clear_options (pCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1); - # ifdef SSL_OP_NO_TLSv1_1 - SSL_CTX_clear_options (pCtx, SSL_OP_NO_TLSv1_1); - # endif - # ifdef SSL_OP_NO_TLSv1_2 - SSL_CTX_clear_options (pCtx, SSL_OP_NO_TLSv1_2); - # endif - #endif - - if (!(ssl_version & EM_PROTO_SSLv2)) - SSL_CTX_set_options (pCtx, SSL_OP_NO_SSLv2); - - if (!(ssl_version & EM_PROTO_SSLv3)) - SSL_CTX_set_options (pCtx, SSL_OP_NO_SSLv3); - - if (!(ssl_version & EM_PROTO_TLSv1)) - SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1); - - #ifdef SSL_OP_NO_TLSv1_1 - if (!(ssl_version & EM_PROTO_TLSv1_1)) - SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1_1); - #endif - - #ifdef SSL_OP_NO_TLSv1_2 - if (!(ssl_version & EM_PROTO_TLSv1_2)) - SSL_CTX_set_options (pCtx, SSL_OP_NO_TLSv1_2); - #endif - - #ifdef SSL_MODE_RELEASE_BUFFERS - SSL_CTX_set_mode (pCtx, SSL_MODE_RELEASE_BUFFERS); - #endif - - if (bIsServer) { - - // The SSL_CTX calls here do NOT allocate memory. - int e; - if (privkeyfile.length() > 0) - e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM); - else - e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey); - if (e <= 0) ERR_print_errors_fp(stderr); - assert (e > 0); - - if (certchainfile.length() > 0) - e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str()); - else - e = SSL_CTX_use_certificate (pCtx, DefaultCertificate); - if (e <= 0) ERR_print_errors_fp(stderr); - assert (e > 0); - - if (dhparam.length() > 0) { - DH *dh; - BIO *bio; - - bio = BIO_new_file(dhparam.c_str(), "r"); - if (bio == NULL) { - char buf [500]; - snprintf (buf, sizeof(buf)-1, "dhparam: BIO_new_file(%s) failed", dhparam.c_str()); - throw std::runtime_error (buf); - } - - dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); - - if (dh == NULL) { - BIO_free(bio); - char buf [500]; - snprintf (buf, sizeof(buf)-1, "dhparam: PEM_read_bio_DHparams(%s) failed", dhparam.c_str()); - throw std::runtime_error (buf); - } - - SSL_CTX_set_tmp_dh(pCtx, dh); - - DH_free(dh); - BIO_free(bio); - } - - if (ecdh_curve.length() > 0) { - #if OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH) - int nid; - EC_KEY *ecdh; - - nid = OBJ_sn2nid((const char *) ecdh_curve.c_str()); - if (nid == 0) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "ecdh_curve: Unknown curve name: %s", ecdh_curve.c_str()); - throw std::runtime_error (buf); - } - - ecdh = EC_KEY_new_by_curve_name(nid); - if (ecdh == NULL) { - char buf [200]; - snprintf (buf, sizeof(buf)-1, "ecdh_curve: Unable to create: %s", ecdh_curve.c_str()); - throw std::runtime_error (buf); - } - - SSL_CTX_set_options(pCtx, SSL_OP_SINGLE_ECDH_USE); - - SSL_CTX_set_tmp_ecdh(pCtx, ecdh); - - EC_KEY_free(ecdh); - #else - throw std::runtime_error ("No openssl ECDH support"); - #endif - } - } - - if (cipherlist.length() > 0) - SSL_CTX_set_cipher_list (pCtx, cipherlist.c_str()); - else - SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH"); - - if (bIsServer) { - SSL_CTX_sess_set_cache_size (pCtx, 128); - SSL_CTX_set_session_id_context (pCtx, (unsigned char*)"eventmachine", 12); - } - else { - int e; - if (privkeyfile.length() > 0) { - e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM); - if (e <= 0) ERR_print_errors_fp(stderr); - assert (e > 0); - } - if (certchainfile.length() > 0) { - e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str()); - if (e <= 0) ERR_print_errors_fp(stderr); - assert (e > 0); - } - } -} - - - -/*************************** -SslContext_t::~SslContext_t -***************************/ - -SslContext_t::~SslContext_t() -{ - if (pCtx) - SSL_CTX_free (pCtx); - if (PrivateKey) - EVP_PKEY_free (PrivateKey); - if (Certificate) - X509_free (Certificate); -} - - - -/****************** -SslBox_t::SslBox_t -******************/ - -SslBox_t::SslBox_t (bool is_server, const std::string &privkeyfile, const std::string &certchainfile, bool verify_peer, bool fail_if_no_peer_cert, const std::string &snihostname, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version, const uintptr_t binding): - bIsServer (is_server), - bHandshakeCompleted (false), - bVerifyPeer (verify_peer), - bFailIfNoPeerCert (fail_if_no_peer_cert), - pSSL (NULL), - pbioRead (NULL), - pbioWrite (NULL) -{ - /* TODO someday: make it possible to re-use SSL contexts so we don't have to create - * a new one every time we come here. - */ - - Context = new SslContext_t (bIsServer, privkeyfile, certchainfile, cipherlist, ecdh_curve, dhparam, ssl_version); - assert (Context); - - pbioRead = BIO_new (BIO_s_mem()); - assert (pbioRead); - - pbioWrite = BIO_new (BIO_s_mem()); - assert (pbioWrite); - - pSSL = SSL_new (Context->pCtx); - assert (pSSL); - - if (snihostname.length() > 0) { - SSL_set_tlsext_host_name (pSSL, snihostname.c_str()); - } - - SSL_set_bio (pSSL, pbioRead, pbioWrite); - - // Store a pointer to the binding signature in the SSL object so we can retrieve it later - SSL_set_ex_data(pSSL, 0, (void*) binding); - - if (bVerifyPeer) { - int mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; - if (bFailIfNoPeerCert) - mode = mode | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - SSL_set_verify(pSSL, mode, ssl_verify_wrapper); - } - - if (!bIsServer) { - int e = SSL_connect (pSSL); - if (e != 1) - ERR_print_errors_fp(stderr); - } -} - - - -/******************* -SslBox_t::~SslBox_t -*******************/ - -SslBox_t::~SslBox_t() -{ - // Freeing pSSL will also free the associated BIOs, so DON'T free them separately. - if (pSSL) { - if (SSL_get_shutdown (pSSL) & SSL_RECEIVED_SHUTDOWN) - SSL_shutdown (pSSL); - else - SSL_clear (pSSL); - SSL_free (pSSL); - } - - delete Context; -} - - - -/*********************** -SslBox_t::PutCiphertext -***********************/ - -bool SslBox_t::PutCiphertext (const char *buf, int bufsize) -{ - assert (buf && (bufsize > 0)); - - assert (pbioRead); - int n = BIO_write (pbioRead, buf, bufsize); - - return (n == bufsize) ? true : false; -} - - -/********************** -SslBox_t::GetPlaintext -**********************/ - -int SslBox_t::GetPlaintext (char *buf, int bufsize) -{ - if (!SSL_is_init_finished (pSSL)) { - int e = bIsServer ? SSL_accept (pSSL) : SSL_connect (pSSL); - if (e != 1) { - int er = SSL_get_error (pSSL, e); - if (er != SSL_ERROR_WANT_READ) { - ERR_print_errors_fp(stderr); - // Return -1 for a nonfatal error, -2 for an error that should force the connection down. - return (er == SSL_ERROR_SSL) ? (-2) : (-1); - } - else - return 0; - } - bHandshakeCompleted = true; - // If handshake finished, FALL THROUGH and return the available plaintext. - } - - if (!SSL_is_init_finished (pSSL)) { - // We can get here if a browser abandons a handshake. - // The user can see a warning dialog and abort the connection. - //cerr << ""; - return 0; - } - - //cerr << "CIPH: " << SSL_get_cipher (pSSL) << endl; - - int n = SSL_read (pSSL, buf, bufsize); - if (n >= 0) { - return n; - } - else { - if (SSL_get_error (pSSL, n) == SSL_ERROR_WANT_READ) { - return 0; - } - else { - return -1; - } - } - - return 0; -} - - - -/************************** -SslBox_t::CanGetCiphertext -**************************/ - -bool SslBox_t::CanGetCiphertext() -{ - assert (pbioWrite); - return BIO_pending (pbioWrite) ? true : false; -} - - - -/*********************** -SslBox_t::GetCiphertext -***********************/ - -int SslBox_t::GetCiphertext (char *buf, int bufsize) -{ - assert (pbioWrite); - assert (buf && (bufsize > 0)); - - return BIO_read (pbioWrite, buf, bufsize); -} - - - -/********************** -SslBox_t::PutPlaintext -**********************/ - -int SslBox_t::PutPlaintext (const char *buf, int bufsize) -{ - // The caller will interpret the return value as the number of bytes written. - // WARNING WARNING WARNING, are there any situations in which a 0 or -1 return - // from SSL_write means we should immediately retry? The socket-machine loop - // will probably wait for a time-out cycle (perhaps a second) before re-trying. - // THIS WOULD CAUSE A PERCEPTIBLE DELAY! - - /* We internally queue any outbound plaintext that can't be dispatched - * because we're in the middle of a handshake or something. - * When we get called, try to send any queued data first, and then - * send the caller's data (or queue it). We may get called with no outbound - * data, which means we try to send the outbound queue and that's all. - * - * Return >0 if we wrote any data, 0 if we didn't, and <0 for a fatal error. - * Note that if we return 0, the connection is still considered live - * and we are signalling that we have accepted the outbound data (if any). - */ - - OutboundQ.Push (buf, bufsize); - - if (!SSL_is_init_finished (pSSL)) - return 0; - - bool fatal = false; - bool did_work = false; - int pending = BIO_pending(pbioWrite); - - while (OutboundQ.HasPages() && pending < SSLBOX_WRITE_BUFFER_SIZE) { - const char *page; - int length; - OutboundQ.Front (&page, &length); - assert (page && (length > 0)); - int n = SSL_write (pSSL, page, length); - pending = BIO_pending(pbioWrite); - - if (n > 0) { - did_work = true; - OutboundQ.PopFront(); - } - else { - int er = SSL_get_error (pSSL, n); - if ((er != SSL_ERROR_WANT_READ) && (er != SSL_ERROR_WANT_WRITE)) - fatal = true; - break; - } - } - - - if (did_work) - return 1; - else if (fatal) - return -1; - else - return 0; -} - -/********************** -SslBox_t::GetPeerCert -**********************/ - -X509 *SslBox_t::GetPeerCert() -{ - X509 *cert = NULL; - - if (pSSL) - cert = SSL_get_peer_certificate(pSSL); - - return cert; -} - -/********************** -SslBox_t::GetCipherBits -**********************/ - -int SslBox_t::GetCipherBits() -{ - int bits = -1; - if (pSSL) - SSL_get_cipher_bits(pSSL, &bits); - return bits; -} - -/********************** -SslBox_t::GetCipherName -**********************/ - -const char *SslBox_t::GetCipherName() -{ - if (pSSL) - return SSL_get_cipher_name(pSSL); - return NULL; -} - -/********************** -SslBox_t::GetCipherProtocol -**********************/ - -const char *SslBox_t::GetCipherProtocol() -{ - if (pSSL) - return SSL_get_cipher_version(pSSL); - return NULL; -} - -/********************** -SslBox_t::GetSNIHostname -**********************/ - -const char *SslBox_t::GetSNIHostname() -{ - #ifdef TLSEXT_NAMETYPE_host_name - if (pSSL) - return SSL_get_servername (pSSL, TLSEXT_NAMETYPE_host_name); - #endif - return NULL; -} - -/****************** -ssl_verify_wrapper -*******************/ - -extern "C" int ssl_verify_wrapper(int preverify_ok UNUSED, X509_STORE_CTX *ctx) -{ - uintptr_t binding; - X509 *cert; - SSL *ssl; - BUF_MEM *buf; - BIO *out; - int result; - - cert = X509_STORE_CTX_get_current_cert(ctx); - ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - binding = (uintptr_t) SSL_get_ex_data(ssl, 0); - - out = BIO_new(BIO_s_mem()); - PEM_write_bio_X509(out, cert); - BIO_write(out, "\0", 1); - BIO_get_mem_ptr(out, &buf); - - ConnectionDescriptor *cd = dynamic_cast (Bindable_t::GetObject(binding)); - result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0); - BIO_free(out); - - return result; -} - -#endif // WITH_SSL - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.h b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.h deleted file mode 100644 index 64ff6e1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/ext/ssl.h +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** - -$Id$ - -File: ssl.h -Date: 30Apr06 - -Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -Gmail: blackhedd - -This program is free software; you can redistribute it and/or modify -it under the terms of either: 1) the GNU General Public License -as published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version; or 2) Ruby's License. - -See the file COPYING for complete licensing information. - -*****************************************************************************/ - - -#ifndef __SslBox__H_ -#define __SslBox__H_ - - - - -#ifdef WITH_SSL - -/****************** -class SslContext_t -******************/ - -class SslContext_t -{ - public: - SslContext_t (bool is_server, const std::string &privkeyfile, const std::string &certchainfile, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version); - virtual ~SslContext_t(); - - private: - static bool bLibraryInitialized; - - private: - bool bIsServer; - SSL_CTX *pCtx; - - EVP_PKEY *PrivateKey; - X509 *Certificate; - - friend class SslBox_t; -}; - - -/************** -class SslBox_t -**************/ - -#define SSLBOX_INPUT_CHUNKSIZE 2019 -#define SSLBOX_OUTPUT_CHUNKSIZE 2048 -#define SSLBOX_WRITE_BUFFER_SIZE 8192 // (SSLBOX_OUTPUT_CHUNKSIZE * 4) - -class SslBox_t -{ - public: - SslBox_t (bool is_server, const std::string &privkeyfile, const std::string &certchainfile, bool verify_peer, bool fail_if_no_peer_cert, const std::string &snihostname, const std::string &cipherlist, const std::string &ecdh_curve, const std::string &dhparam, int ssl_version, const uintptr_t binding); - virtual ~SslBox_t(); - - int PutPlaintext (const char*, int); - int GetPlaintext (char*, int); - - bool PutCiphertext (const char*, int); - bool CanGetCiphertext(); - int GetCiphertext (char*, int); - bool IsHandshakeCompleted() {return bHandshakeCompleted;} - - X509 *GetPeerCert(); - int GetCipherBits(); - const char *GetCipherName(); - const char *GetCipherProtocol(); - const char *GetSNIHostname(); - - void Shutdown(); - - protected: - SslContext_t *Context; - - bool bIsServer; - bool bHandshakeCompleted; - bool bVerifyPeer; - bool bFailIfNoPeerCert; - SSL *pSSL; - BIO *pbioRead; - BIO *pbioWrite; - - PageList OutboundQ; -}; - -extern "C" int ssl_verify_wrapper(int, X509_STORE_CTX*); - -#endif // WITH_SSL - - -#endif // __SslBox__H_ - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.classpath b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.classpath deleted file mode 100644 index 11672dd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.project b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.project deleted file mode 100644 index c7766db..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - em_reactor - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactor.java b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactor.java deleted file mode 100644 index 31642f3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactor.java +++ /dev/null @@ -1,613 +0,0 @@ -/** - * $Id$ - * - * Author:: Francis Cianfrocca (gmail: blackhedd) - * Homepage:: http://rubyeventmachine.com - * Date:: 15 Jul 2007 - * - * See EventMachine and EventMachine::Connection for documentation and - * usage examples. - * - * - *---------------------------------------------------------------------------- - * - * Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - * Gmail: blackhedd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of either: 1) the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version; or 2) Ruby's License. - * - * See the file COPYING for complete licensing information. - * - *--------------------------------------------------------------------------- - * - * - */ - -package com.rubyeventmachine; - -import java.io.*; -import java.nio.channels.*; -import java.util.*; -import java.nio.*; -import java.net.*; -import java.util.concurrent.atomic.*; -import java.security.*; - -public class EmReactor { - public final int EM_TIMER_FIRED = 100; - public final int EM_CONNECTION_READ = 101; - public final int EM_CONNECTION_UNBOUND = 102; - public final int EM_CONNECTION_ACCEPTED = 103; - public final int EM_CONNECTION_COMPLETED = 104; - public final int EM_LOOPBREAK_SIGNAL = 105; - public final int EM_CONNECTION_NOTIFY_READABLE = 106; - public final int EM_CONNECTION_NOTIFY_WRITABLE = 107; - public final int EM_SSL_HANDSHAKE_COMPLETED = 108; - public final int EM_SSL_VERIFY = 109; - public final int EM_PROXY_TARGET_UNBOUND = 110; - public final int EM_PROXY_COMPLETED = 111; - - public final int EM_PROTO_SSLv2 = 2; - public final int EM_PROTO_SSLv3 = 4; - public final int EM_PROTO_TLSv1 = 8; - public final int EM_PROTO_TLSv1_1 = 16; - public final int EM_PROTO_TLSv1_2 = 32; - - private Selector mySelector; - private TreeMap> Timers; - private HashMap Connections; - private HashMap Acceptors; - private ArrayList NewConnections; - private ArrayList UnboundConnections; - private ArrayList DetachedConnections; - - private boolean bRunReactor; - private long BindingIndex; - private AtomicBoolean loopBreaker; - private ByteBuffer myReadBuffer; - private int timerQuantum; - - public EmReactor() { - Timers = new TreeMap>(); - Connections = new HashMap(); - Acceptors = new HashMap(); - NewConnections = new ArrayList(); - UnboundConnections = new ArrayList(); - DetachedConnections = new ArrayList(); - - BindingIndex = 0; - loopBreaker = new AtomicBoolean(); - loopBreaker.set(false); - myReadBuffer = ByteBuffer.allocate(32*1024); // don't use a direct buffer. Ruby doesn't seem to like them. - timerQuantum = 98; - } - - /** - * This is a no-op stub, intended to be overridden in user code. - */ - public void eventCallback (long sig, int eventType, ByteBuffer data, long data2) { - System.out.println ("Default callback: "+sig+" "+eventType+" "+data+" "+data2); - } - public void eventCallback (long sig, int eventType, ByteBuffer data) { - eventCallback (sig, eventType, data, 0); - } - - - public void run() { - try { - mySelector = Selector.open(); - bRunReactor = true; - } catch (IOException e) { - throw new RuntimeException ("Could not open selector", e); - } - - while (bRunReactor) { - runLoopbreaks(); - if (!bRunReactor) break; - - runTimers(); - if (!bRunReactor) break; - - removeUnboundConnections(); - checkIO(); - addNewConnections(); - processIO(); - } - - close(); - } - - void addNewConnections() { - ListIterator iter = DetachedConnections.listIterator(0); - while (iter.hasNext()) { - EventableSocketChannel ec = iter.next(); - ec.cleanup(); - } - DetachedConnections.clear(); - - ListIterator iter2 = NewConnections.listIterator(0); - while (iter2.hasNext()) { - long b = iter2.next(); - - EventableChannel ec = Connections.get(b); - if (ec != null) { - try { - ec.register(); - } catch (ClosedChannelException e) { - UnboundConnections.add (ec.getBinding()); - } - } - } - NewConnections.clear(); - } - - void removeUnboundConnections() { - ListIterator iter = UnboundConnections.listIterator(0); - while (iter.hasNext()) { - long b = iter.next(); - - EventableChannel ec = Connections.remove(b); - if (ec != null) { - eventCallback (b, EM_CONNECTION_UNBOUND, null); - ec.close(); - - EventableSocketChannel sc = (EventableSocketChannel) ec; - if (sc != null && sc.isAttached()) - DetachedConnections.add (sc); - } - } - UnboundConnections.clear(); - } - - void checkIO() { - long timeout; - - if (NewConnections.size() > 0) { - timeout = -1; - } else if (!Timers.isEmpty()) { - long now = new Date().getTime(); - long k = Timers.firstKey(); - long diff = k-now; - - if (diff <= 0) - timeout = -1; // don't wait, just poll once - else - timeout = diff; - } else { - timeout = 0; // wait indefinitely - } - - try { - if (timeout == -1) - mySelector.selectNow(); - else - mySelector.select(timeout); - } catch (IOException e) { - e.printStackTrace(); - } - } - - void processIO() { - Iterator it = mySelector.selectedKeys().iterator(); - while (it.hasNext()) { - SelectionKey k = it.next(); - it.remove(); - - if (k.isConnectable()) - isConnectable(k); - - else if (k.isAcceptable()) - isAcceptable(k); - - else { - if (k.isWritable()) - isWritable(k); - - if (k.isReadable()) - isReadable(k); - } - } - } - - void isAcceptable (SelectionKey k) { - ServerSocketChannel ss = (ServerSocketChannel) k.channel(); - SocketChannel sn; - long b; - - for (int n = 0; n < 10; n++) { - try { - sn = ss.accept(); - if (sn == null) - break; - } catch (IOException e) { - e.printStackTrace(); - k.cancel(); - - ServerSocketChannel server = Acceptors.remove(k.attachment()); - if (server != null) - try{ server.close(); } catch (IOException ex) {}; - break; - } - - try { - sn.configureBlocking(false); - } catch (IOException e) { - e.printStackTrace(); - continue; - } - - b = createBinding(); - EventableSocketChannel ec = new EventableSocketChannel (sn, b, mySelector); - Connections.put (b, ec); - NewConnections.add (b); - - eventCallback (((Long)k.attachment()).longValue(), EM_CONNECTION_ACCEPTED, null, b); - } - } - - void isReadable (SelectionKey k) { - EventableChannel ec = (EventableChannel) k.attachment(); - long b = ec.getBinding(); - - if (ec.isWatchOnly()) { - if (ec.isNotifyReadable()) - eventCallback (b, EM_CONNECTION_NOTIFY_READABLE, null); - } else { - myReadBuffer.clear(); - - try { - ec.readInboundData (myReadBuffer); - myReadBuffer.flip(); - if (myReadBuffer.limit() > 0) - eventCallback (b, EM_CONNECTION_READ, myReadBuffer); - } catch (IOException e) { - UnboundConnections.add (b); - } - } - } - - void isWritable (SelectionKey k) { - EventableChannel ec = (EventableChannel) k.attachment(); - long b = ec.getBinding(); - - if (ec.isWatchOnly()) { - if (ec.isNotifyWritable()) - eventCallback (b, EM_CONNECTION_NOTIFY_WRITABLE, null); - } - else { - try { - if (!ec.writeOutboundData()) - UnboundConnections.add (b); - } catch (IOException e) { - UnboundConnections.add (b); - } - } - } - - void isConnectable (SelectionKey k) { - EventableSocketChannel ec = (EventableSocketChannel) k.attachment(); - long b = ec.getBinding(); - - try { - if (ec.finishConnecting()) - eventCallback (b, EM_CONNECTION_COMPLETED, null); - else - UnboundConnections.add (b); - } catch (IOException e) { - UnboundConnections.add (b); - } - } - - void close() { - try { - if (mySelector != null) - mySelector.close(); - } catch (IOException e) {} - mySelector = null; - - // run down open connections and sockets. - Iterator i = Acceptors.values().iterator(); - while (i.hasNext()) { - try { - i.next().close(); - } catch (IOException e) {} - } - - // 29Sep09: We create an ArrayList of the existing connections, then iterate over - // that to call unbind on them. This is because an unbind can trigger a reconnect, - // which will add to the Connections HashMap, causing a ConcurrentModificationException. - // XXX: The correct behavior here would be to latch the various reactor methods to return - // immediately if the reactor is shutting down. - ArrayList conns = new ArrayList(); - Iterator i2 = Connections.values().iterator(); - while (i2.hasNext()) { - EventableChannel ec = i2.next(); - if (ec != null) { - conns.add (ec); - } - } - Connections.clear(); - - ListIterator i3 = conns.listIterator(0); - while (i3.hasNext()) { - EventableChannel ec = i3.next(); - eventCallback (ec.getBinding(), EM_CONNECTION_UNBOUND, null); - ec.close(); - - EventableSocketChannel sc = (EventableSocketChannel) ec; - if (sc != null && sc.isAttached()) - DetachedConnections.add (sc); - } - - ListIterator i4 = DetachedConnections.listIterator(0); - while (i4.hasNext()) { - EventableSocketChannel ec = i4.next(); - ec.cleanup(); - } - DetachedConnections.clear(); - } - - void runLoopbreaks() { - if (loopBreaker.getAndSet(false)) { - eventCallback (0, EM_LOOPBREAK_SIGNAL, null); - } - } - - public void stop() { - bRunReactor = false; - signalLoopbreak(); - } - - void runTimers() { - long now = new Date().getTime(); - while (!Timers.isEmpty()) { - long k = Timers.firstKey(); - if (k > now) - break; - - ArrayList callbacks = Timers.get(k); - Timers.remove(k); - - // Fire all timers at this timestamp - ListIterator iter = callbacks.listIterator(0); - while (iter.hasNext()) { - eventCallback (0, EM_TIMER_FIRED, null, iter.next().longValue()); - } - } - } - - public long installOneshotTimer (long milliseconds) { - long s = createBinding(); - long deadline = new Date().getTime() + milliseconds; - - if (Timers.containsKey(deadline)) { - Timers.get(deadline).add(s); - } else { - ArrayList callbacks = new ArrayList(); - callbacks.add(s); - Timers.put(deadline, callbacks); - } - - return s; - } - - public long startTcpServer (SocketAddress sa) throws EmReactorException { - try { - ServerSocketChannel server = ServerSocketChannel.open(); - server.configureBlocking(false); - server.socket().bind (sa); - long s = createBinding(); - Acceptors.put(s, server); - server.register(mySelector, SelectionKey.OP_ACCEPT, s); - return s; - } catch (IOException e) { - throw new EmReactorException ("unable to open socket acceptor: " + e.toString()); - } - } - - public long startTcpServer (String address, int port) throws EmReactorException { - return startTcpServer (new InetSocketAddress (address, port)); - } - - public void stopTcpServer (long signature) throws IOException { - ServerSocketChannel server = Acceptors.remove(signature); - if (server != null) - server.close(); - else - throw new RuntimeException ("failed to close unknown acceptor"); - } - - public long openUdpSocket (InetSocketAddress address) throws IOException { - // TODO, don't throw an exception out of here. - DatagramChannel dg = DatagramChannel.open(); - dg.configureBlocking(false); - dg.socket().bind(address); - long b = createBinding(); - EventableChannel ec = new EventableDatagramChannel (dg, b, mySelector); - dg.register(mySelector, SelectionKey.OP_READ, ec); - Connections.put(b, ec); - return b; - } - - public long openUdpSocket (String address, int port) throws IOException { - return openUdpSocket (new InetSocketAddress (address, port)); - } - - public void sendData (long sig, ByteBuffer bb) throws IOException { - Connections.get(sig).scheduleOutboundData( bb ); - } - - public void sendData (long sig, byte[] data) throws IOException { - sendData (sig, ByteBuffer.wrap(data)); - } - - public void setCommInactivityTimeout (long sig, long mills) { - Connections.get(sig).setCommInactivityTimeout (mills); - } - - public void sendDatagram (long sig, byte[] data, int length, String recipAddress, int recipPort) { - sendDatagram (sig, ByteBuffer.wrap(data), recipAddress, recipPort); - } - - public void sendDatagram (long sig, ByteBuffer bb, String recipAddress, int recipPort) { - (Connections.get(sig)).scheduleOutboundDatagram( bb, recipAddress, recipPort); - } - - public long connectTcpServer (String address, int port) { - return connectTcpServer(null, 0, address, port); - } - - public long connectTcpServer (String bindAddr, int bindPort, String address, int port) { - long b = createBinding(); - - try { - SocketChannel sc = SocketChannel.open(); - sc.configureBlocking(false); - if (bindAddr != null) - sc.socket().bind(new InetSocketAddress (bindAddr, bindPort)); - - EventableSocketChannel ec = new EventableSocketChannel (sc, b, mySelector); - - if (sc.connect (new InetSocketAddress (address, port))) { - // Connection returned immediately. Can happen with localhost connections. - // WARNING, this code is untested due to lack of available test conditions. - // Ought to be be able to come here from a localhost connection, but that - // doesn't happen on Linux. (Maybe on FreeBSD?) - // The reason for not handling this until we can test it is that we - // really need to return from this function WITHOUT triggering any EM events. - // That's because until the user code has seen the signature we generated here, - // it won't be able to properly dispatch them. The C++ EM deals with this - // by setting pending mode as a flag in ALL eventable descriptors and making - // the descriptor select for writable. Then, it can send UNBOUND and - // CONNECTION_COMPLETED on the next pass through the loop, because writable will - // fire. - throw new RuntimeException ("immediate-connect unimplemented"); - } - else { - ec.setConnectPending(); - Connections.put (b, ec); - NewConnections.add (b); - } - } catch (IOException e) { - // Can theoretically come here if a connect failure can be determined immediately. - // I don't know how to make that happen for testing purposes. - throw new RuntimeException ("immediate-connect unimplemented: " + e.toString()); - } - return b; - } - - public void closeConnection (long sig, boolean afterWriting) { - EventableChannel ec = Connections.get(sig); - if (ec != null) - if (ec.scheduleClose (afterWriting)) - UnboundConnections.add (sig); - } - - long createBinding() { - return ++BindingIndex; - } - - public void signalLoopbreak() { - loopBreaker.set(true); - if (mySelector != null) - mySelector.wakeup(); - } - - public void startTls (long sig) throws NoSuchAlgorithmException, KeyManagementException { - Connections.get(sig).startTls(); - } - - public void setTimerQuantum (int mills) { - if (mills < 5 || mills > 2500) - throw new RuntimeException ("attempt to set invalid timer-quantum value: "+mills); - timerQuantum = mills; - } - - public Object[] getPeerName (long sig) { - EventableChannel channel = Connections.get(sig); - if (channel != null) { - return Connections.get(sig).getPeerName(); - } - else { - ServerSocketChannel acceptor = Acceptors.get(sig); - return new Object[] { acceptor.socket().getLocalPort(), - acceptor.socket().getInetAddress().getHostAddress() }; - } - } - - public Object[] getSockName (long sig) { - EventableChannel channel = Connections.get(sig); - if (channel != null) { - return Connections.get(sig).getSockName(); - } - else { - ServerSocketChannel acceptor = Acceptors.get(sig); - return new Object[] { acceptor.socket().getLocalPort(), - acceptor.socket().getInetAddress().getHostAddress() }; - } - } - - public long attachChannel (SocketChannel sc, boolean watch_mode) { - long b = createBinding(); - - EventableSocketChannel ec = new EventableSocketChannel (sc, b, mySelector); - - ec.setAttached(); - if (watch_mode) - ec.setWatchOnly(); - - Connections.put (b, ec); - NewConnections.add (b); - - return b; - } - - public SocketChannel detachChannel (long sig) { - EventableSocketChannel ec = (EventableSocketChannel) Connections.get (sig); - if (ec != null) { - UnboundConnections.add (sig); - return ec.getChannel(); - } else { - return null; - } - } - - public void setNotifyReadable (long sig, boolean mode) { - ((EventableSocketChannel) Connections.get(sig)).setNotifyReadable(mode); - } - - public void setNotifyWritable (long sig, boolean mode) { - ((EventableSocketChannel) Connections.get(sig)).setNotifyWritable(mode); - } - - public boolean isNotifyReadable (long sig) { - return Connections.get(sig).isNotifyReadable(); - } - - public boolean isNotifyWritable (long sig) { - return Connections.get(sig).isNotifyWritable(); - } - - public boolean pauseConnection (long sig) { - return ((EventableSocketChannel) Connections.get(sig)).pause(); - } - - public boolean resumeConnection (long sig) { - return ((EventableSocketChannel) Connections.get(sig)).resume(); - } - - public boolean isConnectionPaused (long sig) { - return ((EventableSocketChannel) Connections.get(sig)).isPaused(); - } - - public long getOutboundDataSize (long sig) { - return Connections.get(sig).getOutboundDataSize(); - } - - public int getConnectionCount() { - return Connections.size() + Acceptors.size(); - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactorException.java b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactorException.java deleted file mode 100644 index 69efaa3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EmReactorException.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * $Id$ - * - * Author:: Francis Cianfrocca (gmail: blackhedd) - * Homepage:: http://rubyeventmachine.com - * Date:: 15 Jul 2007 - * - * See EventMachine and EventMachine::Connection for documentation and - * usage examples. - * - * - *---------------------------------------------------------------------------- - * - * Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - * Gmail: blackhedd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of either: 1) the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version; or 2) Ruby's License. - * - * See the file COPYING for complete licensing information. - * - *--------------------------------------------------------------------------- - * - * - */ - -package com.rubyeventmachine; - -/** - * @author francis - * - */ -public class EmReactorException extends Exception { - static final long serialVersionUID = 0; - public EmReactorException (String msg) { - super (msg); - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableChannel.java b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableChannel.java deleted file mode 100644 index 3d4f5fd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableChannel.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * $Id$ - * - * Author:: Francis Cianfrocca (gmail: blackhedd) - * Homepage:: http://rubyeventmachine.com - * Date:: 15 Jul 2007 - * - * See EventMachine and EventMachine::Connection for documentation and - * usage examples. - * - * - *---------------------------------------------------------------------------- - * - * Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - * Gmail: blackhedd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of either: 1) the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version; or 2) Ruby's License. - * - * See the file COPYING for complete licensing information. - * - *--------------------------------------------------------------------------- - * - * - */ - - -package com.rubyeventmachine; - -import java.nio.ByteBuffer; -import java.io.IOException; -import java.nio.channels.ClosedChannelException; - -public interface EventableChannel { - - public void scheduleOutboundData (ByteBuffer bb); - - public void scheduleOutboundDatagram (ByteBuffer bb, String recipAddress, int recipPort); - - public boolean scheduleClose (boolean afterWriting); - - public void startTls(); - - public long getBinding(); - - public void readInboundData (ByteBuffer dst) throws IOException; - - public void register() throws ClosedChannelException; - - /** - * This is called by the reactor after it finishes running. - * The idea is to free network resources. - */ - public void close(); - - public boolean writeOutboundData() throws IOException; - - public long getOutboundDataSize(); - - public void setCommInactivityTimeout (long seconds); - - public Object[] getPeerName(); - public Object[] getSockName(); - - public boolean isWatchOnly(); - - public boolean isNotifyReadable(); - public boolean isNotifyWritable(); - -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableDatagramChannel.java b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableDatagramChannel.java deleted file mode 100644 index df1c9fd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableDatagramChannel.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * $Id$ - * - * Author:: Francis Cianfrocca (gmail: blackhedd) - * Homepage:: http://rubyeventmachine.com - * Date:: 15 Jul 2007 - * - * See EventMachine and EventMachine::Connection for documentation and - * usage examples. - * - * - *---------------------------------------------------------------------------- - * - * Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - * Gmail: blackhedd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of either: 1) the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version; or 2) Ruby's License. - * - * See the file COPYING for complete licensing information. - * - *--------------------------------------------------------------------------- - * - * - */ - - -package com.rubyeventmachine; - -import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.DatagramChannel; -import java.util.LinkedList; -import java.io.*; -import java.net.*; - -public class EventableDatagramChannel implements EventableChannel { - - class Packet { - public ByteBuffer bb; - public SocketAddress recipient; - public Packet (ByteBuffer _bb, SocketAddress _recipient) { - bb = _bb; - recipient = _recipient; - } - } - - DatagramChannel channel; - long binding; - Selector selector; - boolean bCloseScheduled; - LinkedList outboundQ; - long outboundS; - SocketAddress returnAddress; - - - public EventableDatagramChannel (DatagramChannel dc, long _binding, Selector sel) throws ClosedChannelException { - channel = dc; - binding = _binding; - selector = sel; - bCloseScheduled = false; - outboundQ = new LinkedList(); - outboundS = 0; - - dc.register(selector, SelectionKey.OP_READ, this); - } - - public void scheduleOutboundData (ByteBuffer bb) { - try { - if ((!bCloseScheduled) && (bb.remaining() > 0)) { - outboundQ.addLast(new Packet(bb, returnAddress)); - outboundS += bb.remaining(); - channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, this); - } - } catch (ClosedChannelException e) { - throw new RuntimeException ("no outbound data"); - } - } - - public void scheduleOutboundDatagram (ByteBuffer bb, String recipAddress, int recipPort) { - try { - if ((!bCloseScheduled) && (bb.remaining() > 0)) { - outboundQ.addLast(new Packet (bb, new InetSocketAddress (recipAddress, recipPort))); - outboundS += bb.remaining(); - channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, this); - } - } catch (ClosedChannelException e) { - throw new RuntimeException ("no outbound data"); - } - } - - public boolean scheduleClose (boolean afterWriting) { - System.out.println ("NOT SCHEDULING CLOSE ON DATAGRAM"); - return false; - } - - public void startTls() { - throw new RuntimeException ("TLS is unimplemented on this Channel"); - } - - public long getBinding() { - return binding; - } - - public void register() throws ClosedChannelException { - // TODO - } - - /** - * Terminate with extreme prejudice. Don't assume there will be another pass through - * the reactor core. - */ - public void close() { - try { - channel.close(); - } catch (IOException e) { - } - } - - public void readInboundData (ByteBuffer dst) { - returnAddress = null; - try { - // If there is no datagram available (we're nonblocking after all), - // then channel.receive returns null. - returnAddress = channel.receive(dst); - } catch (IOException e) { - // probably a no-op. The caller will see the empty (or even partial) buffer - // and presumably do the right thing. - } - } - - public boolean writeOutboundData() { - while (!outboundQ.isEmpty()) { - Packet p = outboundQ.getFirst(); - int written = 0; - try { - // With a datagram socket, it's ok to send an empty buffer. - written = channel.send(p.bb, p.recipient); - outboundS -= written; - } - catch (IOException e) { - return false; - } - - /* Did we consume the whole outbound buffer? If yes, pop it off and - * keep looping. If no, the outbound network buffers are full, so break - * out of here. There's a flaw that affects outbound buffers that are intentionally - * empty. We can tell whether they got sent or not. So we assume they were. - * TODO: As implemented, this ALWAYS discards packets if they were at least - * partially written. This matches the behavior of the C++ EM. My judgment - * is that this is less surprising than fragmenting the data and sending multiple - * packets would be. I could be wrong, so this is subject to change. - */ - - if ((written > 0) || (p.bb.remaining() == 0)) - outboundQ.removeFirst(); - else - break; - } - - if (outboundQ.isEmpty()) { - try { - channel.register(selector, SelectionKey.OP_READ, this); - } catch (ClosedChannelException e) {} - } - - // ALWAYS drain the outbound queue before triggering a connection close. - // If anyone wants to close immediately, they're responsible for clearing - // the outbound queue. - return (bCloseScheduled && outboundQ.isEmpty()) ? false : true; - } - - public void setCommInactivityTimeout (long seconds) { - // TODO - System.out.println ("DATAGRAM: SET COMM INACTIVITY UNIMPLEMENTED " + seconds); - } - - public Object[] getPeerName () { - if (returnAddress != null) { - InetSocketAddress inetAddr = (InetSocketAddress) returnAddress; - return new Object[]{ inetAddr.getPort(), inetAddr.getHostName() }; - } else { - return null; - } - } - - public Object[] getSockName () { - DatagramSocket socket = channel.socket(); - return new Object[]{ socket.getLocalPort(), - socket.getLocalAddress().getHostAddress() }; - } - - public boolean isWatchOnly() { return false; } - public boolean isNotifyReadable() { return false; } - public boolean isNotifyWritable() { return false; } - public long getOutboundDataSize() { return outboundS; } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableSocketChannel.java b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableSocketChannel.java deleted file mode 100644 index 2905ec6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/java/src/com/rubyeventmachine/EventableSocketChannel.java +++ /dev/null @@ -1,415 +0,0 @@ -/** - * $Id$ - * - * Author:: Francis Cianfrocca (gmail: blackhedd) - * Homepage:: http://rubyeventmachine.com - * Date:: 15 Jul 2007 - * - * See EventMachine and EventMachine::Connection for documentation and - * usage examples. - * - * - *---------------------------------------------------------------------------- - * - * Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. - * Gmail: blackhedd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of either: 1) the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version; or 2) Ruby's License. - * - * See the file COPYING for complete licensing information. - * - *--------------------------------------------------------------------------- - * - * - */ - -/** - * - */ -package com.rubyeventmachine; - -/** - * @author francis - * - */ - -import java.nio.channels.*; -import java.nio.*; -import java.util.*; -import java.io.*; -import java.net.Socket; -import javax.net.ssl.*; -import javax.net.ssl.SSLEngineResult.*; -import java.lang.reflect.Field; - -import java.security.*; - -public class EventableSocketChannel implements EventableChannel { - Selector selector; - SelectionKey channelKey; - SocketChannel channel; - - long binding; - LinkedList outboundQ; - long outboundS; - - boolean bCloseScheduled; - boolean bConnectPending; - boolean bWatchOnly; - boolean bAttached; - boolean bNotifyReadable; - boolean bNotifyWritable; - boolean bPaused; - - SSLEngine sslEngine; - SSLContext sslContext; - - public EventableSocketChannel (SocketChannel sc, long _binding, Selector sel) { - channel = sc; - binding = _binding; - selector = sel; - bCloseScheduled = false; - bConnectPending = false; - bWatchOnly = false; - bAttached = false; - bNotifyReadable = false; - bNotifyWritable = false; - outboundQ = new LinkedList(); - outboundS = 0; - } - - public long getBinding() { - return binding; - } - - public SocketChannel getChannel() { - return channel; - } - - public void register() throws ClosedChannelException { - if (channelKey == null) { - int events = currentEvents(); - channelKey = channel.register(selector, events, this); - } - } - - /** - * Terminate with extreme prejudice. Don't assume there will be another pass through - * the reactor core. - */ - public void close() { - if (channelKey != null) { - channelKey.cancel(); - channelKey = null; - } - - if (bAttached) { - // attached channels are copies, so reset the file descriptor to prevent java from close()ing it - Field f; - FileDescriptor fd; - - try { - /* do _NOT_ clobber fdVal here, it will break epoll/kqueue on jdk6! - * channelKey.cancel() above does not occur until the next call to select - * and if fdVal is gone, we will continue to get events for this fd. - * - * instead, remove fdVal in cleanup(), which is processed via DetachedConnections, - * after UnboundConnections but before NewConnections. - */ - - f = channel.getClass().getDeclaredField("fd"); - f.setAccessible(true); - fd = (FileDescriptor) f.get(channel); - - f = fd.getClass().getDeclaredField("fd"); - f.setAccessible(true); - f.set(fd, -1); - } catch (java.lang.NoSuchFieldException e) { - e.printStackTrace(); - } catch (java.lang.IllegalAccessException e) { - e.printStackTrace(); - } - - return; - } - - try { - channel.close(); - } catch (IOException e) { - } - } - - public void cleanup() { - if (bAttached) { - Field f; - try { - f = channel.getClass().getDeclaredField("fdVal"); - f.setAccessible(true); - f.set(channel, -1); - } catch (java.lang.NoSuchFieldException e) { - e.printStackTrace(); - } catch (java.lang.IllegalAccessException e) { - e.printStackTrace(); - } - } - - channel = null; - } - - public void scheduleOutboundData (ByteBuffer bb) { - if (!bCloseScheduled && bb.remaining() > 0) { - if (sslEngine != null) { - try { - ByteBuffer b = ByteBuffer.allocate(32*1024); // TODO, preallocate this buffer. - sslEngine.wrap(bb, b); - b.flip(); - outboundQ.addLast(b); - outboundS += b.remaining(); - } catch (SSLException e) { - throw new RuntimeException ("ssl error"); - } - } - else { - outboundQ.addLast(bb); - outboundS += bb.remaining(); - } - - updateEvents(); - } - } - - public void scheduleOutboundDatagram (ByteBuffer bb, String recipAddress, int recipPort) { - throw new RuntimeException ("datagram sends not supported on this channel"); - } - - /** - * Called by the reactor when we have selected readable. - */ - public void readInboundData (ByteBuffer bb) throws IOException { - if (channel.read(bb) == -1) - throw new IOException ("eof"); - } - - public long getOutboundDataSize() { return outboundS; } - - /** - * Called by the reactor when we have selected writable. - * Return false to indicate an error that should cause the connection to close. - * TODO, VERY IMPORTANT: we're here because we selected writable, but it's always - * possible to become unwritable between the poll and when we get here. The way - * this code is written, we're depending on a nonblocking write NOT TO CONSUME - * the whole outbound buffer in this case, rather than firing an exception. - * We should somehow verify that this is indeed Java's defined behavior. - * @return - */ - public boolean writeOutboundData() throws IOException { - ByteBuffer[] bufs = new ByteBuffer[64]; - int i; - long written, toWrite; - while (!outboundQ.isEmpty()) { - i = 0; - toWrite = 0; - written = 0; - while (i < 64 && !outboundQ.isEmpty()) { - bufs[i] = outboundQ.removeFirst(); - toWrite += bufs[i].remaining(); - i++; - } - if (toWrite > 0) - written = channel.write(bufs, 0, i); - - outboundS -= written; - // Did we consume the whole outbound buffer? If yes, - // pop it off and keep looping. If no, the outbound network - // buffers are full, so break out of here. - if (written < toWrite) { - while (i > 0 && bufs[i-1].remaining() > 0) { - outboundQ.addFirst(bufs[i-1]); - i--; - } - break; - } - } - - if (outboundQ.isEmpty() && !bCloseScheduled) { - updateEvents(); - } - - // ALWAYS drain the outbound queue before triggering a connection close. - // If anyone wants to close immediately, they're responsible for clearing - // the outbound queue. - return (bCloseScheduled && outboundQ.isEmpty()) ? false : true; - } - - public void setConnectPending() { - bConnectPending = true; - updateEvents(); - } - - /** - * Called by the reactor when we have selected connectable. - * Return false to indicate an error that should cause the connection to close. - */ - public boolean finishConnecting() throws IOException { - channel.finishConnect(); - - bConnectPending = false; - updateEvents(); - return true; - } - - public boolean scheduleClose (boolean afterWriting) { - // TODO: What the hell happens here if bConnectPending is set? - if (!afterWriting) { - outboundQ.clear(); - outboundS = 0; - } - - if (outboundQ.isEmpty()) - return true; - else { - updateEvents(); - bCloseScheduled = true; - return false; - } - } - - public void startTls() { - if (sslEngine == null) { - try { - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, null, null); // TODO, fill in the parameters. - sslEngine = sslContext.createSSLEngine(); // TODO, should use the parameterized version, to get Kerb stuff and session re-use. - sslEngine.setUseClientMode(false); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException ("unable to start TLS"); // TODO, get rid of this. - } catch (KeyManagementException e) { - throw new RuntimeException ("unable to start TLS"); // TODO, get rid of this. - } - } - System.out.println ("Starting TLS"); - } - - public ByteBuffer dispatchInboundData (ByteBuffer bb) throws SSLException { - if (sslEngine != null) { - if (true) throw new RuntimeException ("TLS currently unimplemented"); - System.setProperty("javax.net.debug", "all"); - ByteBuffer w = ByteBuffer.allocate(32*1024); // TODO, WRONG, preallocate this buffer. - SSLEngineResult res = sslEngine.unwrap(bb, w); - if (res.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { - Runnable r; - while ((r = sslEngine.getDelegatedTask()) != null) { - r.run(); - } - } - System.out.println (bb); - w.flip(); - return w; - } - else - return bb; - } - - public void setCommInactivityTimeout (long seconds) { - // TODO - System.out.println ("SOCKET: SET COMM INACTIVITY UNIMPLEMENTED " + seconds); - } - - public Object[] getPeerName () { - Socket sock = channel.socket(); - return new Object[]{ sock.getPort(), sock.getInetAddress().getHostAddress() }; - } - - public Object[] getSockName () { - Socket sock = channel.socket(); - return new Object[]{ sock.getLocalPort(), - sock.getLocalAddress().getHostAddress() }; - } - - public void setWatchOnly() { - bWatchOnly = true; - updateEvents(); - } - public boolean isWatchOnly() { return bWatchOnly; } - - public void setAttached() { - bAttached = true; - } - public boolean isAttached() { return bAttached; } - - public void setNotifyReadable (boolean mode) { - bNotifyReadable = mode; - updateEvents(); - } - public boolean isNotifyReadable() { return bNotifyReadable; } - - public void setNotifyWritable (boolean mode) { - bNotifyWritable = mode; - updateEvents(); - } - public boolean isNotifyWritable() { return bNotifyWritable; } - - public boolean pause() { - if (bWatchOnly) { - throw new RuntimeException ("cannot pause/resume 'watch only' connections, set notify readable/writable instead"); - } - boolean old = bPaused; - bPaused = true; - updateEvents(); - return !old; - } - - public boolean resume() { - if (bWatchOnly) { - throw new RuntimeException ("cannot pause/resume 'watch only' connections, set notify readable/writable instead"); - } - boolean old = bPaused; - bPaused = false; - updateEvents(); - return old; - } - - public boolean isPaused() { - return bPaused; - } - - private void updateEvents() { - if (channelKey == null) - return; - - int events = currentEvents(); - - if (channelKey.interestOps() != events) { - channelKey.interestOps(events); - } - } - - private int currentEvents() { - int events = 0; - - if (bWatchOnly) - { - if (bNotifyReadable) - events |= SelectionKey.OP_READ; - - if (bNotifyWritable) - events |= SelectionKey.OP_WRITE; - } - else if (!bPaused) - { - if (bConnectPending) - events |= SelectionKey.OP_CONNECT; - else { - events |= SelectionKey.OP_READ; - - if (!outboundQ.isEmpty()) - events |= SelectionKey.OP_WRITE; - } - } - - return events; - } -} diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/buftok.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/buftok.rb deleted file mode 100644 index caf4f77..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/buftok.rb +++ /dev/null @@ -1,59 +0,0 @@ -# BufferedTokenizer takes a delimiter upon instantiation, or acts line-based -# by default. It allows input to be spoon-fed from some outside source which -# receives arbitrary length datagrams which may-or-may-not contain the token -# by which entities are delimited. In this respect it's ideally paired with -# something like EventMachine (http://rubyeventmachine.com/). -class BufferedTokenizer - # New BufferedTokenizers will operate on lines delimited by a delimiter, - # which is by default the global input delimiter $/ ("\n"). - # - # The input buffer is stored as an array. This is by far the most efficient - # approach given language constraints (in C a linked list would be a more - # appropriate data structure). Segments of input data are stored in a list - # which is only joined when a token is reached, substantially reducing the - # number of objects required for the operation. - def initialize(delimiter = $/) - @delimiter = delimiter - @input = [] - @tail = '' - @trim = @delimiter.length - 1 - end - - # Extract takes an arbitrary string of input data and returns an array of - # tokenized entities, provided there were any available to extract. This - # makes for easy processing of datagrams using a pattern like: - # - # tokenizer.extract(data).map { |entity| Decode(entity) }.each do ... - # - # Using -1 makes split to return "" if the token is at the end of - # the string, meaning the last element is the start of the next chunk. - def extract(data) - if @trim > 0 - tail_end = @tail.slice!(-@trim, @trim) # returns nil if string is too short - data = tail_end + data if tail_end - end - - @input << @tail - entities = data.split(@delimiter, -1) - @tail = entities.shift - - unless entities.empty? - @input << @tail - entities.unshift @input.join - @input.clear - @tail = entities.pop - end - - entities - end - - # Flush the contents of the input buffer, i.e. return the input buffer even though - # a token has not yet been encountered - def flush - @input << @tail - buffer = @input.join - @input.clear - @tail = "" # @tail.clear is slightly faster, but not supported on 1.8.7 - buffer - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/callback.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/callback.rb deleted file mode 100644 index 4928feb..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/callback.rb +++ /dev/null @@ -1,58 +0,0 @@ -module EventMachine - # Utility method for coercing arguments to an object that responds to :call. - # Accepts an object and a method name to send to, or a block, or an object - # that responds to :call. - # - # @example EventMachine.Callback used with a block. Returns that block. - # - # cb = EventMachine.Callback do |msg| - # puts(msg) - # end - # # returned object is a callable - # cb.call('hello world') - # - # - # @example EventMachine.Callback used with an object (to be more specific, class object) and a method name, returns an object that responds to #call - # - # cb = EventMachine.Callback(Object, :puts) - # # returned object is a callable that delegates to Kernel#puts (in this case Object.puts) - # cb.call('hello world') - # - # - # @example EventMachine.Callback used with an object that responds to #call. Returns the argument. - # - # cb = EventMachine.Callback(proc{ |msg| puts(msg) }) - # # returned object is a callable - # cb.call('hello world') - # - # - # @overload Callback(object, method) - # Wraps `method` invocation on `object` into an object that responds to #call that proxies all the arguments to that method - # @param [Object] Object to invoke method on - # @param [Symbol] Method name - # @return [<#call>] An object that responds to #call that takes any number of arguments and invokes method on object with those arguments - # - # @overload Callback(object) - # Returns callable object as is, without any coercion - # @param [<#call>] An object that responds to #call - # @return [<#call>] Its argument - # - # @overload Callback(&block) - # Returns block passed to it without any coercion - # @return [<#call>] Block passed to this method - # - # @raise [ArgumentError] When argument doesn't respond to #call, method name is missing or when invoked without arguments and block isn't given - # - # @return [<#call>] - def self.Callback(object = nil, method = nil, &blk) - if object && method - lambda { |*args| object.__send__ method, *args } - else - if object.respond_to? :call - object - else - blk || raise(ArgumentError) - end # if - end # if - end # self.Callback -end # EventMachine diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/channel.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/channel.rb deleted file mode 100644 index a919adf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/channel.rb +++ /dev/null @@ -1,69 +0,0 @@ -module EventMachine - # Provides a simple thread-safe way to transfer data between (typically) long running - # tasks in {EventMachine.defer} and event loop thread. - # - # @example - # - # channel = EventMachine::Channel.new - # sid = channel.subscribe { |msg| p [:got, msg] } - # - # channel.push('hello world') - # channel.unsubscribe(sid) - # - # - class Channel - def initialize - @subs = {} - @uid = 0 - end - - # Return the number of current subscribers. - def num_subscribers - return @subs.size - end - - # Takes any arguments suitable for EM::Callback() and returns a subscriber - # id for use when unsubscribing. - # - # @return [Integer] Subscribe identifier - # @see #unsubscribe - def subscribe(*a, &b) - name = gen_id - EM.schedule { @subs[name] = EM::Callback(*a, &b) } - - name - end - - # Removes subscriber from the list. - # - # @param [Integer] Subscriber identifier - # @see #subscribe - def unsubscribe(name) - EM.schedule { @subs.delete name } - end - - # Add items to the channel, which are pushed out to all subscribers. - def push(*items) - items = items.dup - EM.schedule { items.each { |i| @subs.values.each { |s| s.call i } } } - end - alias << push - - # Fetches one message from the channel. - def pop(*a, &b) - EM.schedule { - name = subscribe do |*args| - unsubscribe(name) - EM::Callback(*a, &b).call(*args) - end - } - end - - private - - # @private - def gen_id - @uid += 1 - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/completion.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/completion.rb deleted file mode 100644 index 926535f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/completion.rb +++ /dev/null @@ -1,304 +0,0 @@ -# = EM::Completion -# -# A completion is a callback container for various states of completion. In -# its most basic form it has a start state and a finish state. -# -# This implementation includes some hold-back from the EM::Deferrable -# interface in order to be compatible - but it has a much cleaner -# implementation. -# -# In general it is preferred that this implementation be used as a state -# callback container than EM::DefaultDeferrable or other classes including -# EM::Deferrable. This is because it is generally more sane to keep this level -# of state in a dedicated state-back container. This generally leads to more -# malleable interfaces and software designs, as well as eradicating nasty bugs -# that result from abstraction leakage. -# -# == Basic Usage -# -# As already mentioned, the basic usage of a Completion is simply for its two -# final states, :succeeded and :failed. -# -# An asynchronous operation will complete at some future point in time, and -# users often want to react to this event. API authors will want to expose -# some common interface to react to these events. -# -# In the following example, the user wants to know when a short lived -# connection has completed its exchange with the remote server. The simple -# protocol just waits for an ack to its message. -# -# class Protocol < EM::Connection -# include EM::P::LineText2 -# -# def initialize(message, completion) -# @message, @completion = message, completion -# @completion.completion { close_connection } -# @completion.timeout(1, :timeout) -# end -# -# def post_init -# send_data(@message) -# end -# -# def receive_line(line) -# case line -# when /ACK/i -# @completion.succeed line -# when /ERR/i -# @completion.fail :error, line -# else -# @completion.fail :unknown, line -# end -# end -# -# def unbind -# @completion.fail :disconnected unless @completion.completed? -# end -# end -# -# class API -# attr_reader :host, :port -# -# def initialize(host = 'example.org', port = 8000) -# @host, @port = host, port -# end -# -# def request(message) -# completion = EM::Deferrable::Completion.new -# EM.connect(host, port, Protocol, message, completion) -# completion -# end -# end -# -# api = API.new -# completion = api.request('stuff') -# completion.callback do |line| -# puts "API responded with: #{line}" -# end -# completion.errback do |type, line| -# case type -# when :error -# puts "API error: #{line}" -# when :unknown -# puts "API returned unknown response: #{line}" -# when :disconnected -# puts "API server disconnected prematurely" -# when :timeout -# puts "API server did not respond in a timely fashion" -# end -# end -# -# == Advanced Usage -# -# This completion implementation also supports more state callbacks and -# arbitrary states (unlike the original Deferrable API). This allows for basic -# stateful process encapsulation. One might use this to setup state callbacks -# for various states in an exchange like in the basic usage example, except -# where the applicaiton could be made to react to "connected" and -# "disconnected" states additionally. -# -# class Protocol < EM::Connection -# def initialize(completion) -# @response = [] -# @completion = completion -# @completion.stateback(:disconnected) do -# @completion.succeed @response.join -# end -# end -# -# def connection_completed -# @host, @port = Socket.unpack_sockaddr_in get_peername -# @completion.change_state(:connected, @host, @port) -# send_data("GET http://example.org/ HTTP/1.0\r\n\r\n") -# end -# -# def receive_data(data) -# @response << data -# end -# -# def unbind -# @completion.change_state(:disconnected, @host, @port) -# end -# end -# -# completion = EM::Deferrable::Completion.new -# completion.stateback(:connected) do |host, port| -# puts "Connected to #{host}:#{port}" -# end -# completion.stateback(:disconnected) do |host, port| -# puts "Disconnected from #{host}:#{port}" -# end -# completion.callback do |response| -# puts response -# end -# -# EM.connect('example.org', 80, Protocol, completion) -# -# == Timeout -# -# The Completion also has a timeout. The timeout is global and is not aware of -# states apart from completion states. The timeout is only engaged if #timeout -# is called, and it will call fail if it is reached. -# -# == Completion states -# -# By default there are two completion states, :succeeded and :failed. These -# states can be modified by subclassing and overrding the #completion_states -# method. Completion states are special, in that callbacks for all completion -# states are explcitly cleared when a completion state is entered. This -# prevents errors that could arise from accidental unterminated timeouts, and -# other such user errors. -# -# == Other notes -# -# Several APIs have been carried over from EM::Deferrable for compatibility -# reasons during a transitionary period. Specifically cancel_errback and -# cancel_callback are implemented, but their usage is to be strongly -# discouraged. Due to the already complex nature of reaction systems, dynamic -# callback deletion only makes the problem much worse. It is always better to -# add correct conditionals to the callback code, or use more states, than to -# address such implementaiton issues with conditional callbacks. - -module EventMachine - - class Completion - # This is totally not used (re-implemented), it's here in case people check - # for kind_of? - include EventMachine::Deferrable - - attr_reader :state, :value - - def initialize - @state = :unknown - @callbacks = Hash.new { |h,k| h[k] = [] } - @value = [] - @timeout_timer = nil - end - - # Enter the :succeeded state, setting the result value if given. - def succeed(*args) - change_state(:succeeded, *args) - end - # The old EM method: - alias set_deferred_success succeed - - # Enter the :failed state, setting the result value if given. - def fail(*args) - change_state(:failed, *args) - end - # The old EM method: - alias set_deferred_failure fail - - # Statebacks are called when you enter (or are in) the named state. - def stateback(state, *a, &b) - # The following is quite unfortunate special casing for :completed - # statebacks, but it's a necessary evil for latent completion - # definitions. - - if :completed == state || !completed? || @state == state - @callbacks[state] << EM::Callback(*a, &b) - end - execute_callbacks - self - end - - # Callbacks are called when you enter (or are in) a :succeeded state. - def callback(*a, &b) - stateback(:succeeded, *a, &b) - end - - # Errbacks are called when you enter (or are in) a :failed state. - def errback(*a, &b) - stateback(:failed, *a, &b) - end - - # Completions are called when you enter (or are in) either a :failed or a - # :succeeded state. They are stored as a special (reserved) state called - # :completed. - def completion(*a, &b) - stateback(:completed, *a, &b) - end - - # Enter a new state, setting the result value if given. If the state is one - # of :succeeded or :failed, then :completed callbacks will also be called. - def change_state(state, *args) - @value = args - @state = state - - EM.schedule { execute_callbacks } - end - - # The old EM method: - alias set_deferred_status change_state - - # Indicates that we've reached some kind of completion state, by default - # this is :succeeded or :failed. Due to these semantics, the :completed - # state is reserved for internal use. - def completed? - completion_states.any? { |s| state == s } - end - - # Completion states simply returns a list of completion states, by default - # this is :succeeded and :failed. - def completion_states - [:succeeded, :failed] - end - - # Schedule a time which if passes before we enter a completion state, this - # deferrable will be failed with the given arguments. - def timeout(time, *args) - cancel_timeout - @timeout_timer = EM::Timer.new(time) do - fail(*args) unless completed? - end - end - - # Disable the timeout - def cancel_timeout - if @timeout_timer - @timeout_timer.cancel - @timeout_timer = nil - end - end - - # Remove an errback. N.B. Some errbacks cannot be deleted. Usage is NOT - # recommended, this is an anti-pattern. - def cancel_errback(*a, &b) - @callbacks[:failed].delete(EM::Callback(*a, &b)) - end - - # Remove a callback. N.B. Some callbacks cannot be deleted. Usage is NOT - # recommended, this is an anti-pattern. - def cancel_callback(*a, &b) - @callbacks[:succeeded].delete(EM::Callback(*a, &b)) - end - - private - # Execute all callbacks for the current state. If in a completed state, then - # call any statebacks associated with the completed state. - def execute_callbacks - execute_state_callbacks(state) - if completed? - execute_state_callbacks(:completed) - clear_dead_callbacks - cancel_timeout - end - end - - # Iterate all callbacks for a given state, and remove then call them. - def execute_state_callbacks(state) - while callback = @callbacks[state].shift - callback.call(*value) - end - end - - # If we enter a completion state, clear other completion states after all - # callback chains are completed. This means that operation specific - # callbacks can't be dual-called, which is most common user error. - def clear_dead_callbacks - completion_states.each do |state| - @callbacks[state].clear - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/connection.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/connection.rb deleted file mode 100644 index 267aec2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/connection.rb +++ /dev/null @@ -1,770 +0,0 @@ -module EventMachine - class FileNotFoundException < Exception - end - - # EventMachine::Connection is a class that is instantiated - # by EventMachine's processing loop whenever a new connection - # is created. (New connections can be either initiated locally - # to a remote server or accepted locally from a remote client.) - # When a Connection object is instantiated, it mixes in - # the functionality contained in the user-defined module - # specified in calls to {EventMachine.connect} or {EventMachine.start_server}. - # User-defined handler modules may redefine any or all of the standard - # methods defined here, as well as add arbitrary additional code - # that will also be mixed in. - # - # EventMachine manages one object inherited from EventMachine::Connection - # (and containing the mixed-in user code) for every network connection - # that is active at any given time. - # The event loop will automatically call methods on EventMachine::Connection - # objects whenever specific events occur on the corresponding connections, - # as described below. - # - # This class is never instantiated by user code, and does not publish an - # initialize method. The instance methods of EventMachine::Connection - # which may be called by the event loop are: - # - # * {#post_init} - # * {#connection_completed} - # * {#receive_data} - # * {#unbind} - # * {#ssl_verify_peer} (if TLS is used) - # * {#ssl_handshake_completed} - # - # All of the other instance methods defined here are called only by user code. - # - # @see file:docs/GettingStarted.md EventMachine tutorial - class Connection - # @private - attr_accessor :signature - - # @private - alias original_method method - - # Override .new so subclasses don't have to call super and can ignore - # connection-specific arguments - # - # @private - def self.new(sig, *args) - allocate.instance_eval do - # Store signature - @signature = sig - # associate_callback_target sig - - # Call a superclass's #initialize if it has one - initialize(*args) - - # post initialize callback - post_init - - self - end - end - - # Stubbed initialize so legacy superclasses can safely call super - # - # @private - def initialize(*args) - end - - # Called by the event loop immediately after the network connection has been established, - # and before resumption of the network loop. - # This method is generally not called by user code, but is called automatically - # by the event loop. The base-class implementation is a no-op. - # This is a very good place to initialize instance variables that will - # be used throughout the lifetime of the network connection. - # - # @see #connection_completed - # @see #unbind - # @see #send_data - # @see #receive_data - def post_init - end - - # Called by the event loop whenever data has been received by the network connection. - # It is never called by user code. {#receive_data} is called with a single parameter, a String containing - # the network protocol data, which may of course be binary. You will - # generally redefine this method to perform your own processing of the incoming data. - # - # Here's a key point which is essential to understanding the event-driven - # programming model: EventMachine knows absolutely nothing about the protocol - # which your code implements. You must not make any assumptions about - # the size of the incoming data packets, or about their alignment on any - # particular intra-message or PDU boundaries (such as line breaks). - # receive_data can and will send you arbitrary chunks of data, with the - # only guarantee being that the data is presented to your code in the order - # it was collected from the network. Don't even assume that the chunks of - # data will correspond to network packets, as EventMachine can and will coalesce - # several incoming packets into one, to improve performance. The implication for your - # code is that you generally will need to implement some kind of a state machine - # in your redefined implementation of receive_data. For a better understanding - # of this, read through the examples of specific protocol handlers in EventMachine::Protocols - # - # The base-class implementation (which will be invoked only if you didn't override it in your protocol handler) - # simply prints incoming data packet size to stdout. - # - # @param [String] data Opaque incoming data. - # @note Depending on the protocol, buffer sizes and OS networking stack configuration, incoming data may or may not be "a complete message". - # It is up to this handler to detect content boundaries to determine whether all the content (for example, full HTTP request) - # has been received and can be processed. - # - # @see #post_init - # @see #connection_completed - # @see #unbind - # @see #send_data - # @see file:docs/GettingStarted.md EventMachine tutorial - def receive_data data - puts "............>>>#{data.length}" - end - - # Called by EventMachine when the SSL/TLS handshake has - # been completed, as a result of calling #start_tls to initiate SSL/TLS on the connection. - # - # This callback exists because {#post_init} and {#connection_completed} are **not** reliable - # for indicating when an SSL/TLS connection is ready to have its certificate queried for. - # - # @see #get_peer_cert - def ssl_handshake_completed - end - - # Called by EventMachine when :verify_peer => true has been passed to {#start_tls}. - # It will be called with each certificate in the certificate chain provided by the remote peer. - # - # The cert will be passed as a String in PEM format, the same as in {#get_peer_cert}. It is up to user defined - # code to perform a check on the certificates. The return value from this callback is used to accept or deny the peer. - # A return value that is not nil or false triggers acceptance. If the peer is not accepted, the connection - # will be subsequently closed. - # - # @example This server always accepts all peers - # - # module AcceptServer - # def post_init - # start_tls(:verify_peer => true) - # end - # - # def ssl_verify_peer(cert) - # true - # end - # - # def ssl_handshake_completed - # $server_handshake_completed = true - # end - # end - # - # - # @example This server never accepts any peers - # - # module DenyServer - # def post_init - # start_tls(:verify_peer => true) - # end - # - # def ssl_verify_peer(cert) - # # Do not accept the peer. This should now cause the connection to shut down - # # without the SSL handshake being completed. - # false - # end - # - # def ssl_handshake_completed - # $server_handshake_completed = true - # end - # end - # - # @see #start_tls - def ssl_verify_peer(cert) - end - - # called by the framework whenever a connection (either a server or client connection) is closed. - # The close can occur because your code intentionally closes it (using {#close_connection} and {#close_connection_after_writing}), - # because the remote peer closed the connection, or because of a network error. - # You may not assume that the network connection is still open and able to send or - # receive data when the callback to unbind is made. This is intended only to give - # you a chance to clean up associations your code may have made to the connection - # object while it was open. - # - # If you want to detect which peer has closed the connection, you can override {#close_connection} in your protocol handler - # and set an @ivar. - # - # @example Overriding Connection#close_connection to distinguish connections closed on our side - # - # class MyProtocolHandler < EventMachine::Connection - # - # # ... - # - # def close_connection(*args) - # @intentionally_closed_connection = true - # super(*args) - # end - # - # def unbind - # if @intentionally_closed_connection - # # ... - # end - # end - # - # # ... - # - # end - # - # @see #post_init - # @see #connection_completed - # @see file:docs/GettingStarted.md EventMachine tutorial - def unbind - end - - # Called by the reactor after attempting to relay incoming data to a descriptor (set as a proxy target descriptor with - # {EventMachine.enable_proxy}) that has already been closed. - # - # @see EventMachine.enable_proxy - def proxy_target_unbound - end - - # called when the reactor finished proxying all - # of the requested bytes. - def proxy_completed - end - - # EventMachine::Connection#proxy_incoming_to is called only by user code. It sets up - # a low-level proxy relay for all data inbound for this connection, to the connection given - # as the argument. This is essentially just a helper method for enable_proxy. - # - # @see EventMachine.enable_proxy - def proxy_incoming_to(conn,bufsize=0) - EventMachine::enable_proxy(self, conn, bufsize) - end - - # A helper method for {EventMachine.disable_proxy} - def stop_proxying - EventMachine::disable_proxy(self) - end - - # The number of bytes proxied to another connection. Reset to zero when - # EventMachine::Connection#proxy_incoming_to is called, and incremented whenever data is proxied. - def get_proxied_bytes - EventMachine::get_proxied_bytes(@signature) - end - - # EventMachine::Connection#close_connection is called only by user code, and never - # by the event loop. You may call this method against a connection object in any - # callback handler, whether or not the callback was made against the connection - # you want to close. close_connection schedules the connection to be closed - # at the next available opportunity within the event loop. You may not assume that - # the connection is closed when close_connection returns. In particular, the framework - # will callback the unbind method for the particular connection at a point shortly - # after you call close_connection. You may assume that the unbind callback will - # take place sometime after your call to close_connection completes. In other words, - # the unbind callback will not re-enter your code "inside" of your call to close_connection. - # However, it's not guaranteed that a future version of EventMachine will not change - # this behavior. - # - # {#close_connection} will *silently discard* any outbound data which you have - # sent to the connection using {EventMachine::Connection#send_data} but which has not - # yet been sent across the network. If you want to avoid this behavior, use - # {EventMachine::Connection#close_connection_after_writing}. - # - def close_connection after_writing = false - EventMachine::close_connection @signature, after_writing - end - - # Removes given connection from the event loop. - # The connection's socket remains open and its file descriptor number is returned. - def detach - EventMachine::detach_fd @signature - end - - def get_sock_opt level, option - EventMachine::get_sock_opt @signature, level, option - end - - def set_sock_opt level, optname, optval - EventMachine::set_sock_opt @signature, level, optname, optval - end - - # A variant of {#close_connection}. - # All of the descriptive comments given for close_connection also apply to - # close_connection_after_writing, *with one exception*: if the connection has - # outbound data sent using send_dat but which has not yet been sent across the network, - # close_connection_after_writing will schedule the connection to be closed *after* - # all of the outbound data has been safely written to the remote peer. - # - # Depending on the amount of outgoing data and the speed of the network, - # considerable time may elapse between your call to close_connection_after_writing - # and the actual closing of the socket (at which time the unbind callback will be called - # by the event loop). During this time, you *may not* call send_data to transmit - # additional data (that is, the connection is closed for further writes). In very - # rare cases, you may experience a receive_data callback after your call to {#close_connection_after_writing}, - # depending on whether incoming data was in the process of being received on the connection - # at the moment when you called {#close_connection_after_writing}. Your protocol handler must - # be prepared to properly deal with such data (probably by ignoring it). - # - # @see #close_connection - # @see #send_data - def close_connection_after_writing - close_connection true - end - - # Call this method to send data to the remote end of the network connection. It takes a single String argument, - # which may contain binary data. Data is buffered to be sent at the end of this event loop tick (cycle). - # - # When used in a method that is event handler (for example, {#post_init} or {#connection_completed}, it will send - # data to the other end of the connection that generated the event. - # You can also call {#send_data} to write to other connections. For more information see The Chat Server Example in the - # {file:docs/GettingStarted.md EventMachine tutorial}. - # - # If you want to send some data and then immediately close the connection, make sure to use {#close_connection_after_writing} - # instead of {#close_connection}. - # - # - # @param [String] data Data to send asynchronously - # - # @see file:docs/GettingStarted.md EventMachine tutorial - # @see Connection#receive_data - # @see Connection#post_init - # @see Connection#unbind - def send_data data - data = data.to_s - size = data.bytesize if data.respond_to?(:bytesize) - size ||= data.size - EventMachine::send_data @signature, data, size - end - - # Returns true if the connection is in an error state, false otherwise. - # - # In general, you can detect the occurrence of communication errors or unexpected - # disconnection by the remote peer by handing the {#unbind} method. In some cases, however, - # it's useful to check the status of the connection using {#error?} before attempting to send data. - # This function is synchronous but it will return immediately without blocking. - # - # @return [Boolean] true if the connection is in an error state, false otherwise - def error? - errno = EventMachine::report_connection_error_status(@signature) - case errno - when 0 - false - when -1 - true - else - EventMachine::ERRNOS[errno] - end - end - - # Called by the event loop when a remote TCP connection attempt completes successfully. - # You can expect to get this notification after calls to {EventMachine.connect}. Remember that EventMachine makes remote connections - # asynchronously, just as with any other kind of network event. This method - # is intended primarily to assist with network diagnostics. For normal protocol - # handling, use #post_init to perform initial work on a new connection (such as sending initial set of data). - # {Connection#post_init} will always be called. This method will only be called in case of a successful completion. - # A connection attempt which fails will result a call to {Connection#unbind} after the failure. - # - # @see Connection#post_init - # @see Connection#unbind - # @see file:docs/GettingStarted.md EventMachine tutorial - def connection_completed - end - - # Call {#start_tls} at any point to initiate TLS encryption on connected streams. - # The method is smart enough to know whether it should perform a server-side - # or a client-side handshake. An appropriate place to call {#start_tls} is in - # your redefined {#post_init} method, or in the {#connection_completed} handler for - # an outbound connection. - # - # - # @option args [String] :cert_chain_file (nil) local path of a readable file that contants a chain of X509 certificates in - # the [PEM format](http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail), - # with the most-resolved certificate at the top of the file, successive intermediate - # certs in the middle, and the root (or CA) cert at the bottom. - # - # @option args [String] :private_key_file (nil) local path of a readable file that must contain a private key in the [PEM format](http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail). - # - # @option args [Boolean] :verify_peer (false) indicates whether a server should request a certificate from a peer, to be verified by user code. - # If true, the {#ssl_verify_peer} callback on the {EventMachine::Connection} object is called with each certificate - # in the certificate chain provided by the peer. See documentation on {#ssl_verify_peer} for how to use this. - # - # @option args [Boolean] :fail_if_no_peer_cert (false) Used in conjunction with verify_peer. If set the SSL handshake will be terminated if the peer does not provide a certificate. - # - # - # @option args [String] :cipher_list ("ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH") indicates the available SSL cipher values. Default value is "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH". Check the format of the OpenSSL cipher string at http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT. - # - # @option args [String] :ecdh_curve (nil) The curve for ECDHE ciphers. See available ciphers with 'openssl ecparam -list_curves' - # - # @option args [String] :dhparam (nil) The local path of a file containing DH parameters for EDH ciphers in [PEM format](http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail) See: 'openssl dhparam' - # - # @option args [Array] :ssl_version (TLSv1 TLSv1_1 TLSv1_2) indicates the allowed SSL/TLS versions. Possible values are: {SSLv2}, {SSLv3}, {TLSv1}, {TLSv1_1}, {TLSv1_2}. - # - # @example Using TLS with EventMachine - # - # require 'rubygems' - # require 'eventmachine' - # - # module Handler - # def post_init - # start_tls(:private_key_file => '/tmp/server.key', :cert_chain_file => '/tmp/server.crt', :verify_peer => false) - # end - # end - # - # EventMachine.run do - # EventMachine.start_server("127.0.0.1", 9999, Handler) - # end - # - # @param [Hash] args - # - # @todo support passing an encryption parameter, which can be string or Proc, to get a passphrase - # for encrypted private keys. - # @todo support passing key material via raw strings or Procs that return strings instead of - # just filenames. - # - # @see #ssl_verify_peer - def start_tls args={} - priv_key = args[:private_key_file] - cert_chain = args[:cert_chain_file] - verify_peer = args[:verify_peer] - sni_hostname = args[:sni_hostname] - cipher_list = args[:cipher_list] - ssl_version = args[:ssl_version] - ecdh_curve = args[:ecdh_curve] - dhparam = args[:dhparam] - fail_if_no_peer_cert = args[:fail_if_no_peer_cert] - - [priv_key, cert_chain].each do |file| - next if file.nil? or file.empty? - raise FileNotFoundException, - "Could not find #{file} for start_tls" unless File.exist? file - end - - protocols_bitmask = 0 - if ssl_version.nil? - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1 - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1_1 - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1_2 - else - [ssl_version].flatten.each do |p| - case p.to_s.downcase - when 'sslv2' - protocols_bitmask |= EventMachine::EM_PROTO_SSLv2 - when 'sslv3' - protocols_bitmask |= EventMachine::EM_PROTO_SSLv3 - when 'tlsv1' - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1 - when 'tlsv1_1' - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1_1 - when 'tlsv1_2' - protocols_bitmask |= EventMachine::EM_PROTO_TLSv1_2 - else - raise("Unrecognized SSL/TLS Protocol: #{p}") - end - end - end - - EventMachine::set_tls_parms(@signature, priv_key || '', cert_chain || '', verify_peer, fail_if_no_peer_cert, sni_hostname || '', cipher_list || '', ecdh_curve || '', dhparam || '', protocols_bitmask) - EventMachine::start_tls @signature - end - - # If [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security) is active on the connection, returns the remote [X509 certificate](http://en.wikipedia.org/wiki/X.509) - # as a string, in the popular [PEM format](http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail). This can then be used for arbitrary validation - # of a peer's certificate in your code. - # - # This should be called in/after the {#ssl_handshake_completed} callback, which indicates - # that SSL/TLS is active. Using this callback is important, because the certificate may not - # be available until the time it is executed. Using #post_init or #connection_completed is - # not adequate, because the SSL handshake may still be taking place. - # - # This method will return `nil` if: - # - # * EventMachine is not built with [OpenSSL](http://www.openssl.org) support - # * [TLS](http://en.wikipedia.org/wiki/Transport_Layer_Security) is not active on the connection - # * TLS handshake is not yet complete - # * Remote peer for any other reason has not presented a certificate - # - # - # @example Getting peer TLS certificate information in EventMachine - # - # module Handler - # def post_init - # puts "Starting TLS" - # start_tls - # end - # - # def ssl_handshake_completed - # puts get_peer_cert - # close_connection - # end - # - # def unbind - # EventMachine::stop_event_loop - # end - # end - # - # EventMachine.run do - # EventMachine.connect "mail.google.com", 443, Handler - # end - # - # # Will output: - # # -----BEGIN CERTIFICATE----- - # # MIIDIjCCAougAwIBAgIQbldpChBPqv+BdPg4iwgN8TANBgkqhkiG9w0BAQUFADBM - # # MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg - # # THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wODA1MDIxNjMyNTRaFw0w - # # OTA1MDIxNjMyNTRaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh - # # MRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRgw - # # FgYDVQQDEw9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ - # # AoGBALlkxdh2QXegdElukCSOV2+8PKiONIS+8Tu9K7MQsYpqtLNC860zwOPQ2NLI - # # 3Zp4jwuXVTrtzGuiqf5Jioh35Ig3CqDXtLyZoypjZUQcq4mlLzHlhIQ4EhSjDmA7 - # # Ffw9y3ckSOQgdBQWNLbquHh9AbEUjmhkrYxIqKXeCnRKhv6nAgMBAAGjgecwgeQw - # # KAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwNgYDVR0f - # # BC8wLTAroCmgJ4YlaHR0cDovL2NybC50aGF3dGUuY29tL1RoYXd0ZVNHQ0NBLmNy - # # bDByBggrBgEFBQcBAQRmMGQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0 - # # ZS5jb20wPgYIKwYBBQUHMAKGMmh0dHA6Ly93d3cudGhhd3RlLmNvbS9yZXBvc2l0 - # # b3J5L1RoYXd0ZV9TR0NfQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF - # # BQADgYEAsRwpLg1dgCR1gYDK185MFGukXMeQFUvhGqF8eT/CjpdvezyKVuz84gSu - # # 6ccMXgcPQZGQN/F4Xug+Q01eccJjRSVfdvR5qwpqCj+6BFl5oiKDBsveSkrmL5dz - # # s2bn7TdTSYKcLeBkjXxDLHGBqLJ6TNCJ3c4/cbbG5JhGvoema94= - # # -----END CERTIFICATE----- - # - # You can do whatever you want with the certificate String, such as load it - # as a certificate object using the OpenSSL library, and check its fields. - # - # @return [String] the remote [X509 certificate](http://en.wikipedia.org/wiki/X.509), in the popular [PEM format](http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail), - # if TLS is active on the connection - # - # @see Connection#start_tls - # @see Connection#ssl_handshake_completed - def get_peer_cert - EventMachine::get_peer_cert @signature - end - - def get_cipher_bits - EventMachine::get_cipher_bits @signature - end - - def get_cipher_name - EventMachine::get_cipher_name @signature - end - - def get_cipher_protocol - EventMachine::get_cipher_protocol @signature - end - - def get_sni_hostname - EventMachine::get_sni_hostname @signature - end - - # Sends UDP messages. - # - # This method may be called from any Connection object that refers - # to an open datagram socket (see EventMachine#open_datagram_socket). - # The method sends a UDP (datagram) packet containing the data you specify, - # to a remote peer specified by the IP address and port that you give - # as parameters to the method. - # Observe that you may send a zero-length packet (empty string). - # However, you may not send an arbitrarily-large data packet because - # your operating system will enforce a platform-specific limit on - # the size of the outbound packet. (Your kernel - # will respond in a platform-specific way if you send an overlarge - # packet: some will send a truncated packet, some will complain, and - # some will silently drop your request). - # On LANs, it's usually OK to send datagrams up to about 4000 bytes in length, - # but to be really safe, send messages smaller than the Ethernet-packet - # size (typically about 1400 bytes). Some very restrictive WANs - # will either drop or truncate packets larger than about 500 bytes. - # - # @param [String] data Data to send asynchronously - # @param [String] recipient_address IP address of the recipient - # @param [String] recipient_port Port of the recipient - def send_datagram data, recipient_address, recipient_port - data = data.to_s - size = data.bytesize if data.respond_to?(:bytesize) - size ||= data.size - EventMachine::send_datagram @signature, data, size, recipient_address, Integer(recipient_port) - end - - - # This method is used with stream-connections to obtain the identity - # of the remotely-connected peer. If a peername is available, this method - # returns a sockaddr structure. The method returns nil if no peername is available. - # You can use Socket.unpack_sockaddr_in and its variants to obtain the - # values contained in the peername structure returned from #get_peername. - # - # @example How to get peer IP address and port with EventMachine - # - # require 'socket' - # - # module Handler - # def receive_data data - # port, ip = Socket.unpack_sockaddr_in(get_peername) - # puts "got #{data.inspect} from #{ip}:#{port}" - # end - # end - def get_peername - EventMachine::get_peername @signature - end - - # Used with stream-connections to obtain the identity - # of the local side of the connection. If a local name is available, this method - # returns a sockaddr structure. The method returns nil if no local name is available. - # You can use {Socket.unpack_sockaddr_in} and its variants to obtain the - # values contained in the local-name structure returned from this method. - # - # @example - # - # require 'socket' - # - # module Handler - # def receive_data data - # port, ip = Socket.unpack_sockaddr_in(get_sockname) - # puts "got #{data.inspect}" - # end - # end - def get_sockname - EventMachine::get_sockname @signature - end - - # Returns the PID (kernel process identifier) of a subprocess - # associated with this Connection object. For use with {EventMachine.popen} - # and similar methods. Returns nil when there is no meaningful subprocess. - # - # @return [Integer] - def get_pid - EventMachine::get_subprocess_pid @signature - end - - # Returns a subprocess exit status. Only useful for {EventMachine.popen}. Call it in your - # {#unbind} handler. - # - # @return [Integer] - def get_status - EventMachine::get_subprocess_status @signature - end - - # The number of seconds since the last send/receive activity on this connection. - def get_idle_time - EventMachine::get_idle_time @signature - end - - # comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout - # property of network-connection and datagram-socket objects. A nonzero value - # indicates that the connection or socket will automatically be closed if no read or write - # activity takes place for at least that number of seconds. - # A zero value (the default) specifies that no automatic timeout will take place. - def comm_inactivity_timeout - EventMachine::get_comm_inactivity_timeout @signature - end - - # Allows you to set the inactivity-timeout property for - # a network connection or datagram socket. Specify a non-negative float value in seconds. - # If the value is greater than zero, the connection or socket will automatically be closed - # if no read or write activity takes place for at least that number of seconds. - # Specify a value of zero to indicate that no automatic timeout should take place. - # Zero is the default value. - def comm_inactivity_timeout= value - EventMachine::set_comm_inactivity_timeout @signature, value.to_f - end - alias set_comm_inactivity_timeout comm_inactivity_timeout= - - # The duration after which a TCP connection in the connecting state will fail. - # It is important to distinguish this value from {EventMachine::Connection#comm_inactivity_timeout}, - # which looks at how long since data was passed on an already established connection. - # The value is a float in seconds. - # - # @return [Float] The duration after which a TCP connection in the connecting state will fail, in seconds. - def pending_connect_timeout - EventMachine::get_pending_connect_timeout @signature - end - - # Sets the duration after which a TCP connection in a - # connecting state will fail. - # - # @param [Float, #to_f] value Connection timeout in seconds - def pending_connect_timeout= value - EventMachine::set_pending_connect_timeout @signature, value.to_f - end - alias set_pending_connect_timeout pending_connect_timeout= - - # Reconnect to a given host/port with the current instance - # - # @param [String] server Hostname or IP address - # @param [Integer] port Port to reconnect to - def reconnect server, port - EventMachine::reconnect server, port, self - end - - - # Like {EventMachine::Connection#send_data}, this sends data to the remote end of - # the network connection. {EventMachine::Connection#send_file_data} takes a - # filename as an argument, though, and sends the contents of the file, in one - # chunk. - # - # @param [String] filename Local path of the file to send - # - # @see #send_data - # @author Kirk Haines - def send_file_data filename - EventMachine::send_file_data @signature, filename - end - - # Open a file on the filesystem and send it to the remote peer. This returns an - # object of type {EventMachine::Deferrable}. The object's callbacks will be executed - # on the reactor main thread when the file has been completely scheduled for - # transmission to the remote peer. Its errbacks will be called in case of an error (such as file-not-found). - # This method employs various strategies to achieve the fastest possible performance, - # balanced against minimum consumption of memory. - # - # Warning: this feature has an implicit dependency on an outboard extension, - # evma_fastfilereader. You must install this extension in order to use {#stream_file_data} - # with files larger than a certain size (currently 8192 bytes). - # - # @option args [Boolean] :http_chunks (false) If true, this method will stream the file data in a format - # compatible with the HTTP chunked-transfer encoding - # - # @param [String] filename Local path of the file to stream - # @param [Hash] args Options - # - # @return [EventMachine::Deferrable] - def stream_file_data filename, args={} - EventMachine::FileStreamer.new( self, filename, args ) - end - - # Watches connection for readability. Only possible if the connection was created - # using {EventMachine.attach} and had {EventMachine.notify_readable}/{EventMachine.notify_writable} defined on the handler. - # - # @see #notify_readable? - def notify_readable= mode - EventMachine::set_notify_readable @signature, mode - end - - # @return [Boolean] true if the connection is being watched for readability. - def notify_readable? - EventMachine::is_notify_readable @signature - end - - # Watches connection for writeability. Only possible if the connection was created - # using {EventMachine.attach} and had {EventMachine.notify_readable}/{EventMachine.notify_writable} defined on the handler. - # - # @see #notify_writable? - def notify_writable= mode - EventMachine::set_notify_writable @signature, mode - end - - # Returns true if the connection is being watched for writability. - def notify_writable? - EventMachine::is_notify_writable @signature - end - - # Pause a connection so that {#send_data} and {#receive_data} events are not fired until {#resume} is called. - # @see #resume - def pause - EventMachine::pause_connection @signature - end - - # Resume a connection's {#send_data} and {#receive_data} events. - # @see #pause - def resume - EventMachine::resume_connection @signature - end - - # @return [Boolean] true if the connect was paused using {EventMachine::Connection#pause}. - # @see #pause - # @see #resume - def paused? - EventMachine::connection_paused? @signature - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable.rb deleted file mode 100644 index 18a6d31..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable.rb +++ /dev/null @@ -1,210 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 Jul 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Deferrable - autoload :Pool, 'em/deferrable/pool' - - # Specify a block to be executed if and when the Deferrable object receives - # a status of :succeeded. See #set_deferred_status for more information. - # - # Calling this method on a Deferrable object whose status is not yet known - # will cause the callback block to be stored on an internal list. - # If you call this method on a Deferrable whose status is :succeeded, the - # block will be executed immediately, receiving the parameters given to the - # prior #set_deferred_status call. - # - #-- - # If there is no status, add a callback to an internal list. - # If status is succeeded, execute the callback immediately. - # If status is failed, do nothing. - # - def callback &block - return unless block - @deferred_status ||= :unknown - if @deferred_status == :succeeded - block.call(*@deferred_args) - elsif @deferred_status != :failed - @callbacks ||= [] - @callbacks.unshift block # << block - end - self - end - - # Cancels an outstanding callback to &block if any. Undoes the action of #callback. - # - def cancel_callback block - @callbacks ||= [] - @callbacks.delete block - end - - # Specify a block to be executed if and when the Deferrable object receives - # a status of :failed. See #set_deferred_status for more information. - #-- - # If there is no status, add an errback to an internal list. - # If status is failed, execute the errback immediately. - # If status is succeeded, do nothing. - # - def errback &block - return unless block - @deferred_status ||= :unknown - if @deferred_status == :failed - block.call(*@deferred_args) - elsif @deferred_status != :succeeded - @errbacks ||= [] - @errbacks.unshift block # << block - end - self - end - - # Cancels an outstanding errback to &block if any. Undoes the action of #errback. - # - def cancel_errback block - @errbacks ||= [] - @errbacks.delete block - end - - # Sets the "disposition" (status) of the Deferrable object. See also the large set of - # sugarings for this method. - # Note that if you call this method without arguments, - # no arguments will be passed to the callback/errback. - # If the user has coded these with arguments, then the - # user code will throw an argument exception. - # Implementors of deferrable classes must - # document the arguments they will supply to user callbacks. - # - # OBSERVE SOMETHING VERY SPECIAL here: you may call this method even - # on the INSIDE of a callback. This is very useful when a previously-registered - # callback wants to change the parameters that will be passed to subsequently-registered - # ones. - # - # You may give either :succeeded or :failed as the status argument. - # - # If you pass :succeeded, then all of the blocks passed to the object using the #callback - # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks - # passed to the object using #errback will be discarded. - # - # If you pass :failed, then all of the blocks passed to the object using the #errback - # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks - # passed to the object using # callback will be discarded. - # - # If you pass any arguments to #set_deferred_status in addition to the status argument, - # they will be passed as arguments to any callbacks or errbacks that are executed. - # It's your responsibility to ensure that the argument lists specified in your callbacks and - # errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise - # an ArgumentError. - # - #-- - # We're shifting callbacks off and discarding them as we execute them. - # This is valid because by definition callbacks are executed no more than - # once. It also has the magic effect of permitting recursive calls, which - # means that a callback can call #set_deferred_status and change the parameters - # that will be sent to subsequent callbacks down the chain. - # - # Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion - # by Kirk Haines, to work around the memory leak bug that still exists in many Ruby - # versions. - # - # Changed 15Sep07: after processing callbacks or errbacks, CLEAR the other set of - # handlers. This gets us a little closer to the behavior of Twisted's "deferred," - # which only allows status to be set once. Prior to making this change, it was possible - # to "succeed" a Deferrable (triggering its callbacks), and then immediately "fail" it, - # triggering its errbacks! That is clearly undesirable, but it's just as undesirable - # to raise an exception is status is set more than once on a Deferrable. The latter - # behavior would invalidate the idiom of resetting arguments by setting status from - # within a callback or errback, but more seriously it would cause spurious errors - # if a Deferrable was timed out and then an attempt was made to succeed it. See the - # comments under the new method #timeout. - # - def set_deferred_status status, *args - cancel_timeout - @errbacks ||= nil - @callbacks ||= nil - @deferred_status = status - @deferred_args = args - case @deferred_status - when :succeeded - if @callbacks - while cb = @callbacks.pop - cb.call(*@deferred_args) - end - end - @errbacks.clear if @errbacks - when :failed - if @errbacks - while eb = @errbacks.pop - eb.call(*@deferred_args) - end - end - @callbacks.clear if @callbacks - end - end - - - # Setting a timeout on a Deferrable causes it to go into the failed state after - # the Timeout expires (passing no arguments to the object's errbacks). - # Setting the status at any time prior to a call to the expiration of the timeout - # will cause the timer to be cancelled. - def timeout seconds, *args - cancel_timeout - me = self - @deferred_timeout = EventMachine::Timer.new(seconds) {me.fail(*args)} - self - end - - # Cancels an outstanding timeout if any. Undoes the action of #timeout. - # - def cancel_timeout - @deferred_timeout ||= nil - if @deferred_timeout - @deferred_timeout.cancel - @deferred_timeout = nil - end - end - - - # Sugar for set_deferred_status(:succeeded, ...) - # - def succeed *args - set_deferred_status :succeeded, *args - end - alias set_deferred_success succeed - - # Sugar for set_deferred_status(:failed, ...) - # - def fail *args - set_deferred_status :failed, *args - end - alias set_deferred_failure fail - end - - - # DefaultDeferrable is an otherwise empty class that includes Deferrable. - # This is very useful when you just need to return a Deferrable object - # as a way of communicating deferred status to some other part of a program. - class DefaultDeferrable - include Deferrable - end -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable/pool.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable/pool.rb deleted file mode 100644 index 3c278ee..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/deferrable/pool.rb +++ /dev/null @@ -1,2 +0,0 @@ -warn "EM::Deferrable::Pool is deprecated, please use EM::Pool" -EM::Deferrable::Pool = EM::Pool \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/file_watch.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/file_watch.rb deleted file mode 100644 index 074ffed..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/file_watch.rb +++ /dev/null @@ -1,73 +0,0 @@ -module EventMachine - # Utility class that is useful for file monitoring. Supported events are - # - # * File is modified - # * File is deleted - # * File is moved - # - # @note On Mac OS X, file watching only works when kqueue is enabled - # - # @see EventMachine.watch_file - class FileWatch < Connection - # @private - Cmodified = 'modified'.freeze - # @private - Cdeleted = 'deleted'.freeze - # @private - Cmoved = 'moved'.freeze - - - # @private - def receive_data(data) - case data - when Cmodified - file_modified - when Cdeleted - file_deleted - when Cmoved - file_moved - end - end - - # Returns the path that is being monitored. - # - # @note Current implementation does not pick up on the new filename after a rename occurs. - # - # @return [String] - # @see EventMachine.watch_file - def path - @path - end - - # Will be called when the file is modified. Supposed to be redefined by subclasses. - # - # @abstract - def file_modified - end - - # Will be called when the file is deleted. Supposed to be redefined by subclasses. - # When the file is deleted, stop_watching will be called after this to make sure everything is - # cleaned up correctly. - # - # @note On Linux (with {http://en.wikipedia.org/wiki/Inotify inotify}), this method will not be called until *all* open file descriptors to - # the file have been closed. - # - # @abstract - def file_deleted - end - - # Will be called when the file is moved or renamed. Supposed to be redefined by subclasses. - # - # @abstract - def file_moved - end - - # Discontinue monitoring of the file. - # - # This involves cleaning up the underlying monitoring details with kqueue/inotify, and in turn firing {EventMachine::Connection#unbind}. - # This will be called automatically when a file is deleted. User code may call it as well. - def stop_watching - EventMachine::unwatch_filename(@signature) - end # stop_watching - end # FileWatch -end # EventMachine diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/future.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/future.rb deleted file mode 100644 index 4affbf5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/future.rb +++ /dev/null @@ -1,61 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 Jul 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -#-- -# This defines EventMachine::Deferrable#future, which requires -# that the rest of EventMachine::Deferrable has already been seen. -# (It's in deferrable.rb.) - -module EventMachine - module Deferrable - - # A future is a sugaring of a typical deferrable usage. - #-- - # Evaluate arg (which may be an expression or a block). - # What's the class of arg? - # If arg is an ordinary expression, then return it. - # If arg is deferrable (responds to :set_deferred_status), - # then look at the arguments. If either callback or errback - # are defined, then use them. If neither are defined, then - # use the supplied block (if any) as the callback. - # Then return arg. - def self.future arg, cb=nil, eb=nil, &blk - arg = arg.call if arg.respond_to?(:call) - - if arg.respond_to?(:set_deferred_status) - if cb || eb - arg.callback(&cb) if cb - arg.errback(&eb) if eb - else - arg.callback(&blk) if blk - end - end - - arg - end - - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/iterator.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/iterator.rb deleted file mode 100644 index a30b9dd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/iterator.rb +++ /dev/null @@ -1,252 +0,0 @@ -module EventMachine - # A simple iterator for concurrent asynchronous work. - # - # Unlike ruby's built-in iterators, the end of the current iteration cycle is signaled manually, - # instead of happening automatically after the yielded block finishes executing. For example: - # - # (0..10).each{ |num| } - # - # becomes: - # - # EM::Iterator.new(0..10).each{ |num,iter| iter.next } - # - # This is especially useful when doing asynchronous work via reactor libraries and - # functions. For example, given a sync and async http api: - # - # response = sync_http_get(url); ... - # async_http_get(url){ |response| ... } - # - # a synchronous iterator such as: - # - # responses = urls.map{ |url| sync_http_get(url) } - # ... - # puts 'all done!' - # - # could be written as: - # - # EM::Iterator.new(urls).map(proc{ |url,iter| - # async_http_get(url){ |res| - # iter.return(res) - # } - # }, proc{ |responses| - # ... - # puts 'all done!' - # }) - # - # Now, you can take advantage of the asynchronous api to issue requests in parallel. For example, - # to fetch 10 urls at a time, simply pass in a concurrency of 10: - # - # EM::Iterator.new(urls, 10).each do |url,iter| - # async_http_get(url){ iter.next } - # end - # - class Iterator - Stop = "EM::Stop" - # Create a new parallel async iterator with specified concurrency. - # - # i = EM::Iterator.new(1..100, 10) - # - # will create an iterator over the range that processes 10 items at a time. Iteration - # is started via #each, #map or #inject - # - # The list may either be an array-like object, or a proc that returns a new object - # to be processed each time it is called. If a proc is used, it must return - # EventMachine::Iterator::Stop to signal the end of the iterations. - # - def initialize(list, concurrency = 1) - raise ArgumentError, 'concurrency must be bigger than zero' unless (concurrency > 0) - if list.respond_to?(:call) - @list = nil - @list_proc = list - elsif list.respond_to?(:to_a) - @list = list.to_a.dup - @list_proc = nil - else - raise ArgumentError, 'argument must be a proc or an array' - end - @concurrency = concurrency - - @started = false - @ended = false - end - - # Change the concurrency of this iterator. Workers will automatically be spawned or destroyed - # to accomodate the new concurrency level. - # - def concurrency=(val) - old = @concurrency - @concurrency = val - - spawn_workers if val > old and @started and !@ended - end - attr_reader :concurrency - - # Iterate over a set of items using the specified block or proc. - # - # EM::Iterator.new(1..100).each do |num, iter| - # puts num - # iter.next - # end - # - # An optional second proc is invoked after the iteration is complete. - # - # EM::Iterator.new(1..100).each( - # proc{ |num,iter| iter.next }, - # proc{ puts 'all done' } - # ) - # - def each(foreach=nil, after=nil, &blk) - raise ArgumentError, 'proc or block required for iteration' unless foreach ||= blk - raise RuntimeError, 'cannot iterate over an iterator more than once' if @started or @ended - - @started = true - @pending = 0 - @workers = 0 - - all_done = proc{ - after.call if after and @ended and @pending == 0 - } - - @process_next = proc{ - # p [:process_next, :pending=, @pending, :workers=, @workers, :ended=, @ended, :concurrency=, @concurrency, :list=, @list] - unless @ended or @workers > @concurrency - item = next_item() - if item.equal?(Stop) - @ended = true - @workers -= 1 - all_done.call - else - @pending += 1 - - is_done = false - on_done = proc{ - raise RuntimeError, 'already completed this iteration' if is_done - is_done = true - - @pending -= 1 - - if @ended - all_done.call - else - EM.next_tick(@process_next) - end - } - class << on_done - alias :next :call - end - - foreach.call(item, on_done) - end - else - @workers -= 1 - end - } - - spawn_workers - - self - end - - # Collect the results of an asynchronous iteration into an array. - # - # EM::Iterator.new(%w[ pwd uptime uname date ], 2).map(proc{ |cmd,iter| - # EM.system(cmd){ |output,status| - # iter.return(output) - # } - # }, proc{ |results| - # p results - # }) - # - def map(foreach, after) - index = 0 - - inject([], proc{ |results,item,iter| - i = index - index += 1 - - is_done = false - on_done = proc{ |res| - raise RuntimeError, 'already returned a value for this iteration' if is_done - is_done = true - - results[i] = res - iter.return(results) - } - class << on_done - alias :return :call - def next - raise NoMethodError, 'must call #return on a map iterator' - end - end - - foreach.call(item, on_done) - }, proc{ |results| - after.call(results) - }) - end - - # Inject the results of an asynchronous iteration onto a given object. - # - # EM::Iterator.new(%w[ pwd uptime uname date ], 2).inject({}, proc{ |hash,cmd,iter| - # EM.system(cmd){ |output,status| - # hash[cmd] = status.exitstatus == 0 ? output.strip : nil - # iter.return(hash) - # } - # }, proc{ |results| - # p results - # }) - # - def inject(obj, foreach, after) - each(proc{ |item,iter| - is_done = false - on_done = proc{ |res| - raise RuntimeError, 'already returned a value for this iteration' if is_done - is_done = true - - obj = res - iter.next - } - class << on_done - alias :return :call - def next - raise NoMethodError, 'must call #return on an inject iterator' - end - end - - foreach.call(obj, item, on_done) - }, proc{ - after.call(obj) - }) - end - - private - - # Spawn workers to consume items from the iterator's enumerator based on the current concurrency level. - # - def spawn_workers - EM.next_tick(start_worker = proc{ - if @workers < @concurrency and !@ended - # p [:spawning_worker, :workers=, @workers, :concurrency=, @concurrency, :ended=, @ended] - @workers += 1 - @process_next.call - EM.next_tick(start_worker) - end - }) - nil - end - - # Return the next item from @list or @list_proc. - # Once items have run out, will return EM::Iterator::Stop. Procs must supply this themselves - def next_item - if @list_proc - @list_proc.call - else - @list.empty? ? Stop : @list.shift - end - end - end -end - -# TODO: pass in one object instead of two? .each{ |iter| puts iter.current; iter.next } -# TODO: support iter.pause/resume/stop/break/continue? -# TODO: create some exceptions instead of using RuntimeError diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/messages.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/messages.rb deleted file mode 100644 index 9a51c39..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/messages.rb +++ /dev/null @@ -1,66 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 Jul 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -=begin - -Message Routing in EventMachine. - -The goal here is to enable "routing points," objects that can send and receive -"messages," which are delimited streams of bytes. The boundaries of a message -are preserved as it passes through the reactor system. - -There will be several module methods defined in EventMachine to create route-point -objects (which will probably have a base class of EventMachine::MessageRouter -until someone suggests a better name). - -As with I/O objects, routing objects will receive events by having the router -core call methods on them. And of course user code can and will define handlers -to deal with events of interest. - -The message router base class only really needs a receive_message method. There will -be an EM module-method to send messages, in addition to the module methods to create -the various kinds of message receivers. - -The simplest kind of message receiver object can receive messages by being named -explicitly in a parameter to EM#send_message. More sophisticated receivers can define -pub-sub selectors and message-queue names. And they can also define channels for -route-points in other processes or even on other machines. - -A message is NOT a marshallable entity. Rather, it's a chunk of flat content more like -an Erlang message. Initially, all content submitted for transmission as a message will -have the to_s method called on it. Eventually, we'll be able to transmit certain structured -data types (XML and YAML documents, Structs within limits) and have them reconstructed -on the other end. - -A fundamental goal of the message-routing capability is to interoperate seamlessly with -external systems, including non-Ruby systems like ActiveMQ. We will define various protocol -handlers for things like Stomp and possibly AMQP, but these will be wrapped up and hidden -from the users of the basic routing capability. - -As with Erlang, a critical goal is for programs that are built to use message-passing to work -WITHOUT CHANGE when the code is re-based on a multi-process system. - -=end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pool.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pool.rb deleted file mode 100644 index 2cb3662..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pool.rb +++ /dev/null @@ -1,151 +0,0 @@ -module EventMachine - # A simple async resource pool based on a resource and work queue. Resources - # are enqueued and work waits for resources to become available. - # - # @example - # require 'em-http-request' - # - # EM.run do - # pool = EM::Pool.new - # spawn = lambda { pool.add EM::HttpRequest.new('http://example.org') } - # 10.times { spawn[] } - # done, scheduled = 0, 0 - # - # check = lambda do - # done += 1 - # if done >= scheduled - # EM.stop - # end - # end - # - # pool.on_error { |conn| spawn[] } - # - # 100.times do |i| - # scheduled += 1 - # pool.perform do |conn| - # req = conn.get :path => '/', :keepalive => true - # - # req.callback do - # p [:success, conn.object_id, i, req.response.size] - # check[] - # end - # - # req.errback { check[] } - # - # req - # end - # end - # end - # - # Resources are expected to be controlled by an object responding to a - # deferrable/completion style API with callback and errback blocks. - # - class Pool - - def initialize - @resources = EM::Queue.new - @removed = [] - @contents = [] - @on_error = nil - end - - def add resource - @contents << resource - requeue resource - end - - def remove resource - @contents.delete resource - @removed << resource - end - - # Returns a list for introspection purposes only. You should *NEVER* call - # modification or work oriented methods on objects in this list. A good - # example use case is periodic statistics collection against a set of - # connection resources. - # - # @example - # pool.contents.inject(0) { |sum, connection| connection.num_bytes } - def contents - @contents.dup - end - - # Define a default catch-all for when the deferrables returned by work - # blocks enter a failed state. By default all that happens is that the - # resource is returned to the pool. If on_error is defined, this block is - # responsible for re-adding the resource to the pool if it is still usable. - # In other words, it is generally assumed that on_error blocks explicitly - # handle the rest of the lifetime of the resource. - def on_error *a, &b - @on_error = EM::Callback(*a, &b) - end - - # Perform a given #call-able object or block. The callable object will be - # called with a resource from the pool as soon as one is available, and is - # expected to return a deferrable. - # - # The deferrable will have callback and errback added such that when the - # deferrable enters a finished state, the object is returned to the pool. - # - # If on_error is defined, then objects are not automatically returned to the - # pool. - def perform(*a, &b) - work = EM::Callback(*a, &b) - - @resources.pop do |resource| - if removed? resource - @removed.delete resource - reschedule work - else - process work, resource - end - end - end - alias reschedule perform - - # A peek at the number of enqueued jobs waiting for resources - def num_waiting - @resources.num_waiting - end - - # Removed will show resources in a partial pruned state. Resources in the - # removed list may not appear in the contents list if they are currently in - # use. - def removed? resource - @removed.include? resource - end - - protected - def requeue resource - @resources.push resource - end - - def failure resource - if @on_error - @contents.delete resource - @on_error.call resource - # Prevent users from calling a leak. - @removed.delete resource - else - requeue resource - end - end - - def completion deferrable, resource - deferrable.callback { requeue resource } - deferrable.errback { failure resource } - end - - def process work, resource - deferrable = work.call resource - if deferrable.kind_of?(EM::Deferrable) - completion deferrable, resource - else - raise ArgumentError, "deferrable expected from work" - end - rescue - failure resource - raise - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/process_watch.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/process_watch.rb deleted file mode 100644 index 66e8943..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/process_watch.rb +++ /dev/null @@ -1,45 +0,0 @@ -module EventMachine - - # This is subclassed from EventMachine::Connection for use with the process monitoring API. Read the - # documentation on the instance methods of this class, and for a full explanation see EventMachine.watch_process. - class ProcessWatch < Connection - # @private - Cfork = 'fork'.freeze - # @private - Cexit = 'exit'.freeze - - # @private - def receive_data(data) - case data - when Cfork - process_forked - when Cexit - process_exited - end - end - - # Returns the pid that EventMachine::watch_process was originally called with. - def pid - @pid - end - - # Should be redefined with the user's custom callback that will be fired when the prcess is forked. - # - # There is currently not an easy way to get the pid of the forked child. - def process_forked - end - - # Should be redefined with the user's custom callback that will be fired when the process exits. - # - # stop_watching is called automatically after this callback - def process_exited - end - - # Discontinue monitoring of the process. - # This will be called automatically when a process dies. User code may call it as well. - def stop_watching - EventMachine::unwatch_pid(@signature) - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/processes.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/processes.rb deleted file mode 100644 index 4bbc14f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/processes.rb +++ /dev/null @@ -1,123 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 13 Dec 07 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-08 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - - -module EventMachine - - # EM::DeferrableChildProcess is a sugaring of a common use-case - # involving EM::popen. - # Call the #open method on EM::DeferrableChildProcess, passing - # a command-string. #open immediately returns an EM::Deferrable - # object. It also schedules the forking of a child process, which - # will execute the command passed to #open. - # When the forked child terminates, the Deferrable will be signalled - # and execute its callbacks, passing the data that the child process - # wrote to stdout. - # - class DeferrableChildProcess < EventMachine::Connection - include EventMachine::Deferrable - - # @private - def initialize - super - @data = [] - end - - # Sugars a common use-case involving forked child processes. - # #open takes a String argument containing an shell command - # string (including arguments if desired). #open immediately - # returns an EventMachine::Deferrable object, without blocking. - # - # It also invokes EventMachine#popen to run the passed-in - # command in a forked child process. - # - # When the forked child terminates, the Deferrable that - # #open calls its callbacks, passing the data returned - # from the child process. - # - def self.open cmd - EventMachine.popen( cmd, DeferrableChildProcess ) - end - - # @private - def receive_data data - @data << data - end - - # @private - def unbind - succeed( @data.join ) - end - end - - # @private - class SystemCmd < EventMachine::Connection - def initialize cb - @cb = cb - @output = [] - end - def receive_data data - @output << data - end - def unbind - @cb.call @output.join(''), get_status if @cb - end - end - - # EM::system is a simple wrapper for EM::popen. It is similar to Kernel::system, but requires a - # single string argument for the command and performs no shell expansion. - # - # The block or proc passed to EM::system is called with two arguments: the output generated by the command, - # and a Process::Status that contains information about the command's execution. - # - # EM.run{ - # EM.system('ls'){ |output,status| puts output if status.exitstatus == 0 } - # } - # - # You can also supply an additional proc to send some data to the process: - # - # EM.run{ - # EM.system('sh', proc{ |process| - # process.send_data("echo hello\n") - # process.send_data("exit\n") - # }, proc{ |out,status| - # puts(out) - # }) - # } - # - # Like EventMachine.popen, EventMachine.system currently does not work on windows. - # It returns the pid of the spawned process. - def EventMachine::system cmd, *args, &cb - cb ||= args.pop if args.last.is_a? Proc - init = args.pop if args.last.is_a? Proc - - # merge remaining arguments into the command - cmd = [cmd, *args] if args.any? - - EM.get_subprocess_pid(EM.popen(cmd, SystemCmd, cb) do |c| - init[c] if init - end.signature) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols.rb deleted file mode 100644 index 0c17906..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols.rb +++ /dev/null @@ -1,37 +0,0 @@ -module EventMachine - # This module contains various protocol implementations, including: - # - HttpClient and HttpClient2 - # - Stomp - # - Memcache - # - SmtpClient and SmtpServer - # - SASLauth and SASLauthclient - # - LineProtocol, LineAndTextProtocol and LineText2 - # - HeaderAndContentProtocol - # - Postgres3 - # - ObjectProtocol - # - # The protocol implementations live in separate files in the protocols/ subdirectory, - # but are auto-loaded when they are first referenced in your application. - # - # EventMachine::Protocols is also aliased to EM::P for easier usage. - # - module Protocols - # TODO : various autotools are completely useless with the lack of naming - # convention, we need to correct that! - autoload :TcpConnectTester, 'em/protocols/tcptest' - autoload :HttpClient, 'em/protocols/httpclient' - autoload :HttpClient2, 'em/protocols/httpclient2' - autoload :LineAndTextProtocol, 'em/protocols/line_and_text' - autoload :HeaderAndContentProtocol, 'em/protocols/header_and_content' - autoload :LineText2, 'em/protocols/linetext2' - autoload :Stomp, 'em/protocols/stomp' - autoload :SmtpClient, 'em/protocols/smtpclient' - autoload :SmtpServer, 'em/protocols/smtpserver' - autoload :SASLauth, 'em/protocols/saslauth' - autoload :Memcache, 'em/protocols/memcache' - autoload :Postgres3, 'em/protocols/postgres3' - autoload :ObjectProtocol, 'em/protocols/object_protocol' - autoload :Socks4, 'em/protocols/socks4' - autoload :LineProtocol, 'em/protocols/line_protocol' - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/header_and_content.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/header_and_content.rb deleted file mode 100644 index b5a465a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/header_and_content.rb +++ /dev/null @@ -1,138 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 Nov 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Protocols - - # === Usage - # - # class RequestHandler < EM::P::HeaderAndContentProtocol - # def receive_request headers, content - # p [:request, headers, content] - # end - # end - # - # EM.run{ - # EM.start_server 'localhost', 80, RequestHandler - # } - # - #-- - # Originally, this subclassed LineAndTextProtocol, which in - # turn relies on BufferedTokenizer, which doesn't gracefully - # handle the transitions between lines and binary text. - # Changed 13Sep08 by FCianfrocca. - class HeaderAndContentProtocol < Connection - include LineText2 - - ContentLengthPattern = /Content-length:\s*(\d+)/i - - def initialize *args - super - init_for_request - end - - def receive_line line - case @hc_mode - when :discard_blanks - unless line == "" - @hc_mode = :headers - receive_line line - end - when :headers - if line == "" - raise "unrecognized state" unless @hc_headers.length > 0 - if respond_to?(:receive_headers) - receive_headers @hc_headers - end - # @hc_content_length will be nil, not 0, if there was no content-length header. - if @hc_content_length.to_i > 0 - set_binary_mode @hc_content_length - else - dispatch_request - end - else - @hc_headers << line - if ContentLengthPattern =~ line - # There are some attacks that rely on sending multiple content-length - # headers. This is a crude protection, but needs to become tunable. - raise "extraneous content-length header" if @hc_content_length - @hc_content_length = $1.to_i - end - if @hc_headers.length == 1 and respond_to?(:receive_first_header_line) - receive_first_header_line line - end - end - else - raise "internal error, unsupported mode" - end - end - - def receive_binary_data text - @hc_content = text - dispatch_request - end - - def dispatch_request - if respond_to?(:receive_request) - receive_request @hc_headers, @hc_content - end - init_for_request - end - private :dispatch_request - - def init_for_request - @hc_mode = :discard_blanks - @hc_headers = [] - # originally was @hc_headers ||= []; @hc_headers.clear to get a performance - # boost, but it's counterproductive because a subclassed handler will have to - # call dup to use the header array we pass in receive_headers. - - @hc_content_length = nil - @hc_content = "" - end - private :init_for_request - - # Basically a convenience method. We might create a subclass that does this - # automatically. But it's such a performance killer. - def headers_2_hash hdrs - self.class.headers_2_hash hdrs - end - - class << self - def headers_2_hash hdrs - hash = {} - hdrs.each {|h| - if /\A([^\s:]+)\s*:\s*/ =~ h - tail = $'.dup - hash[ $1.downcase.gsub(/-/,"_").intern ] = tail - end - } - hash - end - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient.rb deleted file mode 100644 index 38b175c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient.rb +++ /dev/null @@ -1,300 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 July 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Protocols - - # Note: This class is deprecated and will be removed. Please use EM-HTTP-Request instead. - # - # @example - # EventMachine.run { - # http = EventMachine::Protocols::HttpClient.request( - # :host => server, - # :port => 80, - # :request => "/index.html", - # :query_string => "parm1=value1&parm2=value2" - # ) - # http.callback {|response| - # puts response[:status] - # puts response[:headers] - # puts response[:content] - # } - # } - #-- - # TODO: - # Add streaming so we can support enormous POSTs. Current max is 20meg. - # Timeout for connections that run too long or hang somewhere in the middle. - # Persistent connections (HTTP/1.1), may need a associated delegate object. - # DNS: Some way to cache DNS lookups for hostnames we connect to. Ruby's - # DNS lookups are unbelievably slow. - # HEAD requests. - # Convenience methods for requests. get, post, url, etc. - # SSL. - # Handle status codes like 304, 100, etc. - # Refactor this code so that protocol errors all get handled one way (an exception?), - # instead of sprinkling set_deferred_status :failed calls everywhere. - class HttpClient < Connection - include EventMachine::Deferrable - - MaxPostContentLength = 20 * 1024 * 1024 - - def initialize - warn "HttpClient is deprecated and will be removed. EM-Http-Request should be used instead." - @connected = false - end - - # @param args [Hash] The request arguments - # @option args [String] :host The host IP/DNS name - # @option args [Integer] :port The port to connect too - # @option args [String] :verb The request type [GET | POST | DELETE | PUT] - # @option args [String] :request The request path - # @option args [Hash] :basic_auth The basic auth credentials (:username and :password) - # @option args [String] :content The request content - # @option args [String] :contenttype The content type (e.g. text/plain) - # @option args [String] :query_string The query string - # @option args [String] :host_header The host header to set - # @option args [String] :cookie Cookies to set - def self.request( args = {} ) - args[:port] ||= 80 - EventMachine.connect( args[:host], args[:port], self ) {|c| - # According to the docs, we will get here AFTER post_init is called. - c.instance_eval {@args = args} - } - end - - def post_init - @start_time = Time.now - @data = "" - @read_state = :base - end - - # We send the request when we get a connection. - # AND, we set an instance variable to indicate we passed through here. - # That allows #unbind to know whether there was a successful connection. - # NB: This naive technique won't work when we have to support multiple - # requests on a single connection. - def connection_completed - @connected = true - send_request @args - end - - def send_request args - args[:verb] ||= args[:method] # Support :method as an alternative to :verb. - args[:verb] ||= :get # IS THIS A GOOD IDEA, to default to GET if nothing was specified? - - verb = args[:verb].to_s.upcase - unless ["GET", "POST", "PUT", "DELETE", "HEAD"].include?(verb) - set_deferred_status :failed, {:status => 0} # TODO, not signalling the error type - return # NOTE THE EARLY RETURN, we're not sending any data. - end - - request = args[:request] || "/" - unless request[0,1] == "/" - request = "/" + request - end - - qs = args[:query_string] || "" - if qs.length > 0 and qs[0,1] != '?' - qs = "?" + qs - end - - version = args[:version] || "1.1" - - # Allow an override for the host header if it's not the connect-string. - host = args[:host_header] || args[:host] || "_" - # For now, ALWAYS tuck in the port string, although we may want to omit it if it's the default. - port = args[:port].to_i != 80 ? ":#{args[:port]}" : "" - - # POST items. - postcontenttype = args[:contenttype] || "application/octet-stream" - postcontent = args[:content] || "" - raise "oversized content in HTTP POST" if postcontent.length > MaxPostContentLength - - # ESSENTIAL for the request's line-endings to be CRLF, not LF. Some servers misbehave otherwise. - # TODO: We ASSUME the caller wants to send a 1.1 request. May not be a good assumption. - req = [ - "#{verb} #{request}#{qs} HTTP/#{version}", - "Host: #{host}#{port}", - "User-agent: Ruby EventMachine", - ] - - if verb == "POST" || verb == "PUT" - req << "Content-type: #{postcontenttype}" - req << "Content-length: #{postcontent.length}" - end - - # TODO, this cookie handler assumes it's getting a single, semicolon-delimited string. - # Eventually we will want to deal intelligently with arrays and hashes. - if args[:cookie] - req << "Cookie: #{args[:cookie]}" - end - - # Allow custom HTTP headers, e.g. SOAPAction - args[:custom_headers].each do |k,v| - req << "#{k}: #{v}" - end if args[:custom_headers] - - # Basic-auth stanza contributed by Matt Murphy. - if args[:basic_auth] - basic_auth_string = ["#{args[:basic_auth][:username]}:#{args[:basic_auth][:password]}"].pack('m').strip.gsub(/\n/,'') - req << "Authorization: Basic #{basic_auth_string}" - end - - req << "" - reqstring = req.map {|l| "#{l}\r\n"}.join - send_data reqstring - - if verb == "POST" || verb == "PUT" - send_data postcontent - end - end - - - def receive_data data - while data and data.length > 0 - case @read_state - when :base - # Perform any per-request initialization here and don't consume any data. - @data = "" - @headers = [] - @content_length = nil # not zero - @content = "" - @status = nil - @chunked = false - @chunk_length = nil - @read_state = :header - @connection_close = nil - when :header - ary = data.split( /\r?\n/m, 2 ) - if ary.length == 2 - data = ary.last - if ary.first == "" - if (@content_length and @content_length > 0) || @chunked || @connection_close - @read_state = :content - else - dispatch_response - @read_state = :base - end - else - @headers << ary.first - if @headers.length == 1 - parse_response_line - elsif ary.first =~ /\Acontent-length:\s*/i - # Only take the FIRST content-length header that appears, - # which we can distinguish because @content_length is nil. - # TODO, it's actually a fatal error if there is more than one - # content-length header, because the caller is presumptively - # a bad guy. (There is an exploit that depends on multiple - # content-length headers.) - @content_length ||= $'.to_i - elsif ary.first =~ /\Aconnection:\s*close/i - @connection_close = true - elsif ary.first =~ /\Atransfer-encoding:\s*chunked/i - @chunked = true - end - end - else - @data << data - data = "" - end - when :content - if @chunked && @chunk_length - bytes_needed = @chunk_length - @chunk_read - new_data = data[0, bytes_needed] - @chunk_read += new_data.length - @content += new_data - data = data[bytes_needed..-1] || "" - if @chunk_length == @chunk_read && data[0,2] == "\r\n" - @chunk_length = nil - data = data[2..-1] - end - elsif @chunked - if (m = data.match(/\A(\S*)\r\n/m)) - data = data[m[0].length..-1] - @chunk_length = m[1].to_i(16) - @chunk_read = 0 - if @chunk_length == 0 - dispatch_response - @read_state = :base - end - end - elsif @content_length - # If there was no content-length header, we have to wait until the connection - # closes. Everything we get until that point is content. - # TODO: Must impose a content-size limit, and also must implement chunking. - # Also, must support either temporary files for large content, or calling - # a content-consumer block supplied by the user. - bytes_needed = @content_length - @content.length - @content += data[0, bytes_needed] - data = data[bytes_needed..-1] || "" - if @content_length == @content.length - dispatch_response - @read_state = :base - end - else - @content << data - data = "" - end - end - end - end - - - # We get called here when we have received an HTTP response line. - # It's an opportunity to throw an exception or trigger other exceptional - # handling. - def parse_response_line - if @headers.first =~ /\AHTTP\/1\.[01] ([\d]{3})/ - @status = $1.to_i - else - set_deferred_status :failed, { - :status => 0 # crappy way of signifying an unrecognized response. TODO, find a better way to do this. - } - close_connection - end - end - private :parse_response_line - - def dispatch_response - @read_state = :base - set_deferred_status :succeeded, { - :content => @content, - :headers => @headers, - :status => @status - } - # TODO, we close the connection for now, but this is wrong for persistent clients. - close_connection - end - - def unbind - if !@connected - set_deferred_status :failed, {:status => 0} # YECCCCH. Find a better way to signal no-connect/network error. - elsif (@read_state == :content and @content_length == nil) - dispatch_response - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient2.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient2.rb deleted file mode 100644 index 0fb64e8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/httpclient2.rb +++ /dev/null @@ -1,600 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 July 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Protocols - - # Note: This class is deprecated and will be removed. Please use EM-HTTP-Request instead. - # - # === Usage - # - # EM.run{ - # conn = EM::Protocols::HttpClient2.connect 'google.com', 80 - # - # req = conn.get('/') - # req.callback{ |response| - # p(response.status) - # p(response.headers) - # p(response.content) - # } - # } - class HttpClient2 < Connection - include LineText2 - - def initialize - warn "HttpClient2 is deprecated and will be removed. EM-Http-Request should be used instead." - - @authorization = nil - @closed = nil - @requests = nil - end - - # @private - class Request - include Deferrable - - attr_reader :version - attr_reader :status - attr_reader :header_lines - attr_reader :headers - attr_reader :content - attr_reader :internal_error - - def initialize conn, args - @conn = conn - @args = args - @header_lines = [] - @headers = {} - @blanks = 0 - @chunk_trailer = nil - @chunking = nil - end - - def send_request - az = @args[:authorization] and az = "Authorization: #{az}\r\n" - - r = [ - "#{@args[:verb]} #{@args[:uri]} HTTP/#{@args[:version] || "1.1"}\r\n", - "Host: #{@args[:host_header] || "_"}\r\n", - az || "", - "\r\n" - ] - @conn.send_data r.join - end - - - #-- - # - def receive_line ln - if @chunk_trailer - receive_chunk_trailer(ln) - elsif @chunking - receive_chunk_header(ln) - else - receive_header_line(ln) - end - end - - #-- - # - def receive_chunk_trailer ln - if ln.length == 0 - @conn.pop_request - succeed(self) - else - p "Received chunk trailer line" - end - end - - #-- - # Allow up to ten blank lines before we get a real response line. - # Allow no more than 100 lines in the header. - # - def receive_header_line ln - if ln.length == 0 - if @header_lines.length > 0 - process_header - else - @blanks += 1 - if @blanks > 10 - @conn.close_connection - end - end - else - @header_lines << ln - if @header_lines.length > 100 - @internal_error = :bad_header - @conn.close_connection - end - end - end - - #-- - # Cf RFC 2616 pgh 3.6.1 for the format of HTTP chunks. - # - def receive_chunk_header ln - if ln.length > 0 - chunksize = ln.to_i(16) - if chunksize > 0 - @conn.set_text_mode(ln.to_i(16)) - else - @content = @content ? @content.join : '' - @chunk_trailer = true - end - else - # We correctly come here after each chunk gets read. - # p "Got A BLANK chunk line" - end - - end - - - #-- - # We get a single chunk. Append it to the incoming content and switch back to line mode. - # - def receive_chunked_text text - # p "RECEIVED #{text.length} CHUNK" - (@content ||= []) << text - end - - - #-- - # TODO, inefficient how we're handling this. Part of it is done so as to - # make sure we don't have problems in detecting chunked-encoding, content-length, - # etc. - # - HttpResponseRE = /\AHTTP\/(1.[01]) ([\d]{3})/i - ClenRE = /\AContent-length:\s*(\d+)/i - ChunkedRE = /\ATransfer-encoding:\s*chunked/i - ColonRE = /\:\s*/ - - def process_header - unless @header_lines.first =~ HttpResponseRE - @conn.close_connection - @internal_error = :bad_request - end - @version = $1.dup - @status = $2.dup.to_i - - clen = nil - chunks = nil - @header_lines.each_with_index do |e,ix| - if ix > 0 - hdr,val = e.split(ColonRE,2) - (@headers[hdr.downcase] ||= []) << val - end - - if clen == nil and e =~ ClenRE - clen = $1.dup.to_i - end - if e =~ ChunkedRE - chunks = true - end - end - - if clen - # If the content length is zero we should not call set_text_mode, - # because a value of zero will make it wait forever, hanging the - # connection. Just return success instead, with empty content. - if clen == 0 then - @content = "" - @conn.pop_request - succeed(self) - else - @conn.set_text_mode clen - end - elsif chunks - @chunking = true - else - # Chunked transfer, multipart, or end-of-connection. - # For end-of-connection, we need to go the unbind - # method and suppress its desire to fail us. - p "NO CLEN" - p @args[:uri] - p @header_lines - @internal_error = :unsupported_clen - @conn.close_connection - end - end - private :process_header - - - def receive_text text - @chunking ? receive_chunked_text(text) : receive_sized_text(text) - end - - #-- - # At the present time, we only handle contents that have a length - # specified by the content-length header. - # - def receive_sized_text text - @content = text - @conn.pop_request - succeed(self) - end - end - - # Make a connection to a remote HTTP server. - # Can take either a pair of arguments (which will be interpreted as - # a hostname/ip-address and a port), or a hash. - # If the arguments are a hash, then supported values include: - # :host => a hostname or ip-address - # :port => a port number - # :ssl => true to enable ssl - def self.connect *args - if args.length == 2 - args = {:host=>args[0], :port=>args[1]} - else - args = args.first - end - - h,prt,ssl = args[:host], Integer(args[:port]), (args[:tls] || args[:ssl]) - conn = EM.connect( h, prt, self ) - conn.start_tls if ssl - conn.set_default_host_header( h, prt, ssl ) - conn - end - - # Get a url - # - # req = conn.get(:uri => '/') - # req.callback{|response| puts response.content } - # - def get args - if args.is_a?(String) - args = {:uri=>args} - end - args[:verb] = "GET" - request args - end - - # Post to a url - # - # req = conn.post('/data') - # req.callback{|response| puts response.content } - #-- - # XXX there's no way to supply a POST body.. wtf? - def post args - if args.is_a?(String) - args = {:uri=>args} - end - args[:verb] = "POST" - request args - end - - - #-- - # Compute and remember a string to be used as the host header in HTTP requests - # unless the user overrides it with an argument to #request. - # - # @private - def set_default_host_header host, port, ssl - if (ssl and port != 443) or (!ssl and port != 80) - @host_header = "#{host}:#{port}" - else - @host_header = host - end - end - - - # @private - def post_init - super - @connected = EM::DefaultDeferrable.new - end - - # @private - def connection_completed - super - @connected.succeed - end - - #-- - # All pending requests, if any, must fail. - # We might come here without ever passing through connection_completed - # in case we can't connect to the server. We'll also get here when the - # connection closes (either because the server closes it, or we close it - # due to detecting an internal error or security violation). - # In either case, run down all pending requests, if any, and signal failure - # on them. - # - # Set and remember a flag (@closed) so we can immediately fail any - # subsequent requests. - # - # @private - def unbind - super - @closed = true - (@requests || []).each {|r| r.fail} - end - - # @private - def request args - args[:host_header] = @host_header unless args.has_key?(:host_header) - args[:authorization] = @authorization unless args.has_key?(:authorization) - r = Request.new self, args - if @closed - r.fail - else - (@requests ||= []).unshift r - @connected.callback {r.send_request} - end - r - end - - # @private - def receive_line ln - if req = @requests.last - req.receive_line ln - else - p "??????????" - p ln - end - end - - # @private - def receive_binary_data text - @requests.last.receive_text text - end - - #-- - # Called by a Request object when it completes. - # - # @private - def pop_request - @requests.pop - end - end - - -=begin - class HttpClient2x < Connection - include LineText2 - - # TODO: Make this behave appropriate in case a #connect fails. - # Currently, this produces no errors. - - # Make a connection to a remote HTTP server. - # Can take either a pair of arguments (which will be interpreted as - # a hostname/ip-address and a port), or a hash. - # If the arguments are a hash, then supported values include: - # :host => a hostname or ip-address; - # :port => a port number - #-- - # TODO, support optional encryption arguments like :ssl - def self.connect *args - if args.length == 2 - args = {:host=>args[0], :port=>args[1]} - else - args = args.first - end - - h,prt = args[:host],Integer(args[:port]) - EM.connect( h, prt, self, h, prt ) - end - - - #-- - # Sugars a connection that makes a single request and then - # closes the connection. Matches the behavior and the arguments - # of the original implementation of class HttpClient. - # - # Intended primarily for back compatibility, but the idiom - # is probably useful so it's not deprecated. - # We return a Deferrable, as did the original implementation. - # - # Because we're improving the way we deal with errors and exceptions - # (specifically, HTTP response codes other than 2xx will trigger the - # errback rather than the callback), this may break some existing code. - # - def self.request args - c = connect args - end - - #-- - # Requests can be pipelined. When we get a request, add it to the - # front of a queue as an array. The last element of the @requests - # array is always the oldest request received. Each element of the - # @requests array is a two-element array consisting of a hash with - # the original caller's arguments, and an initially-empty Ostruct - # containing the data we retrieve from the server's response. - # Maintain the instance variable @current_response, which is the response - # of the oldest pending request. That's just to make other code a little - # easier. If the variable doesn't exist when we come here, we're - # obviously the first request being made on the connection. - # - # The reason for keeping this method private (and requiring use of the - # convenience methods #get, #post, #head, etc) is to avoid the small - # performance penalty of canonicalizing the verb. - # - def request args - d = EventMachine::DefaultDeferrable.new - - if @closed - d.fail - return d - end - - o = OpenStruct.new - o.deferrable = d - (@requests ||= []).unshift [args, o] - @current_response ||= @requests.last.last - @connected.callback { - az = args[:authorization] and az = "Authorization: #{az}\r\n" - - r = [ - "#{args[:verb]} #{args[:uri]} HTTP/#{args[:version] || "1.1"}\r\n", - "Host: #{args[:host_header] || @host_header}\r\n", - az || "", - "\r\n" - ] - p r - send_data r.join - } - o.deferrable - end - private :request - - def get args - if args.is_a?(String) - args = {:uri=>args} - end - args[:verb] = "GET" - request args - end - - def initialize host, port - super - @host_header = "#{host}:#{port}" - end - def post_init - super - @connected = EM::DefaultDeferrable.new - end - - - def connection_completed - super - @connected.succeed - end - - #-- - # Make sure to throw away any leftover incoming data if we've - # been closed due to recognizing an error. - # - # Generate an internal error if we get an unreasonable number of - # header lines. It could be malicious. - # - def receive_line ln - p ln - return if @closed - - if ln.length > 0 - (@current_response.headers ||= []).push ln - abort_connection if @current_response.headers.length > 100 - else - process_received_headers - end - end - - #-- - # We come here when we've seen all the headers for a particular request. - # What we do next depends on the response line (which should be the - # first line in the header set), and whether there is content to read. - # We may transition into a text-reading state to read content, or - # we may abort the connection, or we may go right back into parsing - # responses for the next response in the chain. - # - # We make an ASSUMPTION that the first line is an HTTP response. - # Anything else produces an error that aborts the connection. - # This may not be enough, because it may be that responses to pipelined - # requests will come with a blank-line delimiter. - # - # Any non-2xx response will be treated as a fatal error, and abort the - # connection. We will set up the status and other response parameters. - # TODO: we will want to properly support 1xx responses, which some versions - # of IIS copiously generate. - # TODO: We need to give the option of not aborting the connection with certain - # non-200 responses, in order to work with NTLM and other authentication - # schemes that work at the level of individual connections. - # - # Some error responses will get sugarings. For example, we'll return the - # Location header in the response in case of a 301/302 response. - # - # Possible dispositions here: - # 1) No content to read (either content-length is zero or it's a HEAD request); - # 2) Switch to text mode to read a specific number of bytes; - # 3) Read a chunked or multipart response; - # 4) Read till the server closes the connection. - # - # Our reponse to the client can be either to wait till all the content - # has been read and then to signal caller's deferrable, or else to signal - # it when we finish the processing the headers and then expect the caller - # to have given us a block to call as the content comes in. And of course - # the latter gets stickier with chunks and multiparts. - # - HttpResponseRE = /\AHTTP\/(1.[01]) ([\d]{3})/i - ClenRE = /\AContent-length:\s*(\d+)/i - def process_received_headers - abort_connection unless @current_response.headers.first =~ HttpResponseRE - @current_response.version = $1.dup - st = $2.dup - @current_response.status = st.to_i - abort_connection unless st[0,1] == "2" - - clen = nil - @current_response.headers.each do |e| - if clen == nil and e =~ ClenRE - clen = $1.dup.to_i - end - end - - if clen - set_text_mode clen - end - end - private :process_received_headers - - - def receive_binary_data text - @current_response.content = text - @current_response.deferrable.succeed @current_response - @requests.pop - @current_response = (@requests.last || []).last - set_line_mode - end - - - - # We've received either a server error or an internal error. - # Close the connection and abort any pending requests. - #-- - # When should we call close_connection? It will cause #unbind - # to be fired. Should the user expect to see #unbind before - # we call #receive_http_error, or the other way around? - # - # Set instance variable @closed. That's used to inhibit further - # processing of any inbound data after an error has been recognized. - # - # We shouldn't have to worry about any leftover outbound data, - # because we call close_connection (not close_connection_after_writing). - # That ensures that any pipelined requests received after an error - # DO NOT get streamed out to the server on this connection. - # Very important. TODO, write a unit-test to establish that behavior. - # - def abort_connection - close_connection - @closed = true - @current_response.deferrable.fail( @current_response ) - end - - - #------------------------ - # Below here are user-overridable methods. - - end -=end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_and_text.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_and_text.rb deleted file mode 100644 index 784daf2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_and_text.rb +++ /dev/null @@ -1,125 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 November 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# -# - -module EventMachine - module Protocols - # A protocol that handles line-oriented data with interspersed binary text. - # - # This version is optimized for performance. See EventMachine::Protocols::LineText2 - # for a version which is optimized for correctness with regard to binary text blocks - # that can switch back to line mode. - class LineAndTextProtocol < Connection - MaxBinaryLength = 32*1024*1024 - - def initialize *args - super - lbp_init_line_state - end - - def receive_data data - if @lbp_mode == :lines - begin - @lpb_buffer.extract(data).each do |line| - receive_line(line.chomp) if respond_to?(:receive_line) - end - rescue - receive_error('overlength line') if respond_to?(:receive_error) - close_connection - return - end - else - if @lbp_binary_limit > 0 - wanted = @lbp_binary_limit - @lbp_binary_bytes_received - chunk = nil - if data.length > wanted - chunk = data.slice!(0...wanted) - else - chunk = data - data = "" - end - @lbp_binary_buffer[@lbp_binary_bytes_received...(@lbp_binary_bytes_received+chunk.length)] = chunk - @lbp_binary_bytes_received += chunk.length - if @lbp_binary_bytes_received == @lbp_binary_limit - receive_binary_data(@lbp_binary_buffer) if respond_to?(:receive_binary_data) - lbp_init_line_state - end - receive_data(data) if data.length > 0 - else - receive_binary_data(data) if respond_to?(:receive_binary_data) - data = "" - end - end - end - - def unbind - if @lbp_mode == :binary and @lbp_binary_limit > 0 - if respond_to?(:receive_binary_data) - receive_binary_data( @lbp_binary_buffer[0...@lbp_binary_bytes_received] ) - end - end - end - - # Set up to read the supplied number of binary bytes. - # This recycles all the data currently waiting in the line buffer, if any. - # If the limit is nil, then ALL subsequent data will be treated as binary - # data and passed to the upstream protocol handler as we receive it. - # If a limit is given, we'll hold the incoming binary data and not - # pass it upstream until we've seen it all, or until there is an unbind - # (in which case we'll pass up a partial). - # Specifying nil for the limit (the default) means there is no limit. - # Specifiyng zero for the limit will cause an immediate transition back to line mode. - # - def set_binary_mode size = nil - if @lbp_mode == :lines - if size == 0 - receive_binary_data("") if respond_to?(:receive_binary_data) - # Do no more work here. Stay in line mode and keep consuming data. - else - @lbp_binary_limit = size.to_i # (nil will be stored as zero) - if @lbp_binary_limit > 0 - raise "Overlength" if @lbp_binary_limit > MaxBinaryLength # arbitrary sanity check - @lbp_binary_buffer = "\0" * @lbp_binary_limit - @lbp_binary_bytes_received = 0 - end - - @lbp_mode = :binary - receive_data @lpb_buffer.flush - end - else - raise "invalid operation" - end - end - - #-- - # For internal use, establish protocol baseline for handling lines. - def lbp_init_line_state - @lpb_buffer = BufferedTokenizer.new("\n") - @lbp_mode = :lines - end - private :lbp_init_line_state - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_protocol.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_protocol.rb deleted file mode 100644 index dfddae8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/line_protocol.rb +++ /dev/null @@ -1,29 +0,0 @@ -module EventMachine - module Protocols - # LineProtocol will parse out newline terminated strings from a receive_data stream - # - # module Server - # include EM::P::LineProtocol - # - # def receive_line(line) - # send_data("you said: #{line}") - # end - # end - # - module LineProtocol - # @private - def receive_data data - (@buf ||= '') << data - - while @buf.slice!(/(.*?)\r?\n/) - receive_line($1) - end - end - - # Invoked with lines received over the network - def receive_line(line) - # stub - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/linetext2.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/linetext2.rb deleted file mode 100644 index 9fdf28b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/linetext2.rb +++ /dev/null @@ -1,179 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 November 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Protocols - # In the grand, time-honored tradition of re-inventing the wheel, we offer - # here YET ANOTHER protocol that handles line-oriented data with interspersed - # binary text. This one trades away some of the performance optimizations of - # EventMachine::Protocols::LineAndTextProtocol in order to get better correctness - # with regard to binary text blocks that can switch back to line mode. It also - # permits the line-delimiter to change in midstream. - # This was originally written to support Stomp. - module LineText2 - # TODO! We're not enforcing the limits on header lengths and text-lengths. - # When we get around to that, call #receive_error if the user defined it, otherwise - # throw exceptions. - - MaxBinaryLength = 32*1024*1024 - - #-- - # Will loop internally until there's no data left to read. - # That way the user-defined handlers we call can modify the - # handling characteristics on a per-token basis. - # - def receive_data data - return unless (data and data.length > 0) - - # Do this stuff in lieu of a constructor. - @lt2_mode ||= :lines - @lt2_delimiter ||= "\n" - @lt2_linebuffer ||= [] - - remaining_data = data - - while remaining_data.length > 0 - if @lt2_mode == :lines - delimiter_string = case @lt2_delimiter - when Regexp - remaining_data.slice(@lt2_delimiter) - else - @lt2_delimiter - end - ix = remaining_data.index(delimiter_string) if delimiter_string - if ix - @lt2_linebuffer << remaining_data[0...ix] - ln = @lt2_linebuffer.join - @lt2_linebuffer.clear - if @lt2_delimiter == "\n" - ln.chomp! - end - receive_line ln - remaining_data = remaining_data[(ix+delimiter_string.length)..-1] - else - @lt2_linebuffer << remaining_data - remaining_data = "" - end - elsif @lt2_mode == :text - if @lt2_textsize - needed = @lt2_textsize - @lt2_textpos - will_take = if remaining_data.length > needed - needed - else - remaining_data.length - end - - @lt2_textbuffer << remaining_data[0...will_take] - tail = remaining_data[will_take..-1] - - @lt2_textpos += will_take - if @lt2_textpos >= @lt2_textsize - # Reset line mode (the default behavior) BEFORE calling the - # receive_binary_data. This makes it possible for user code - # to call set_text_mode, enabling chains of text blocks - # (which can possibly be of different sizes). - set_line_mode - receive_binary_data @lt2_textbuffer.join - receive_end_of_binary_data - end - - remaining_data = tail - else - receive_binary_data remaining_data - remaining_data = "" - end - end - end - end - - # The line delimiter may be a regular expression or a string. Anything - # passed to set_delimiter other than a regular expression will be - # converted to a string. - def set_delimiter delim - @lt2_delimiter = case delim - when Regexp - delim - else - delim.to_s - end - end - - # Called internally but also exposed to user code, for the case in which - # processing of binary data creates a need to transition back to line mode. - # We support an optional parameter to "throw back" some data, which might - # be an umprocessed chunk of the transmitted binary data, or something else - # entirely. - def set_line_mode data="" - @lt2_mode = :lines - (@lt2_linebuffer ||= []).clear - receive_data data.to_s - end - - def set_text_mode size=nil - if size == 0 - set_line_mode - else - @lt2_mode = :text - (@lt2_textbuffer ||= []).clear - @lt2_textsize = size # which can be nil, signifying no limit - @lt2_textpos = 0 - end - end - - # Alias for #set_text_mode, added for back-compatibility with LineAndTextProtocol. - def set_binary_mode size=nil - set_text_mode size - end - - # In case of a dropped connection, we'll send a partial buffer to user code - # when in sized text mode. User overrides of #receive_binary_data need to - # be aware that they may get a short buffer. - def unbind - @lt2_mode ||= nil - if @lt2_mode == :text and @lt2_textpos > 0 - receive_binary_data @lt2_textbuffer.join - end - end - - # Stub. Should be subclassed by user code. - def receive_line ln - # no-op - end - - # Stub. Should be subclassed by user code. - def receive_binary_data data - # no-op - end - - # Stub. Should be subclassed by user code. - # This is called when transitioning internally from text mode - # back to line mode. Useful when client code doesn't want - # to keep track of how much data it's received. - def receive_end_of_binary_data - # no-op - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/memcache.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/memcache.rb deleted file mode 100644 index 1f81aaf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/memcache.rb +++ /dev/null @@ -1,331 +0,0 @@ -module EventMachine - module Protocols - # Implements the Memcache protocol (http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt). - # Requires memcached >= 1.2.4 w/ noreply support - # - # == Usage example - # - # EM.run{ - # cache = EM::P::Memcache.connect 'localhost', 11211 - # - # cache.set :a, 'hello' - # cache.set :b, 'hi' - # cache.set :c, 'how are you?' - # cache.set :d, '' - # - # cache.get(:a){ |v| p v } - # cache.get_hash(:a, :b, :c, :d){ |v| p v } - # cache.get(:a,:b,:c,:d){ |a,b,c,d| p [a,b,c,d] } - # - # cache.get(:a,:z,:b,:y,:d){ |a,z,b,y,d| p [a,z,b,y,d] } - # - # cache.get(:missing){ |m| p [:missing=, m] } - # cache.set(:missing, 'abc'){ p :stored } - # cache.get(:missing){ |m| p [:missing=, m] } - # cache.del(:missing){ p :deleted } - # cache.get(:missing){ |m| p [:missing=, m] } - # } - # - module Memcache - include EM::Deferrable - - ## - # constants - - unless defined? Cempty - # @private - Cstored = 'STORED'.freeze - # @private - Cend = 'END'.freeze - # @private - Cdeleted = 'DELETED'.freeze - # @private - Cunknown = 'NOT_FOUND'.freeze - # @private - Cerror = 'ERROR'.freeze - - # @private - Cempty = ''.freeze - # @private - Cdelimiter = "\r\n".freeze - end - - ## - # commands - - # Get the value associated with one or multiple keys - # - # cache.get(:a){ |v| p v } - # cache.get(:a,:b,:c,:d){ |a,b,c,d| p [a,b,c,d] } - # - def get *keys - raise ArgumentError unless block_given? - - callback{ - keys = keys.map{|k| k.to_s.gsub(/\s/,'_') } - send_data "get #{keys.join(' ')}\r\n" - @get_cbs << [keys, proc{ |values| - yield *keys.map{ |k| values[k] } - }] - } - end - - # Set the value for a given key - # - # cache.set :a, 'hello' - # cache.set(:missing, 'abc'){ puts "stored the value!" } - # - def set key, val, exptime = 0, &cb - callback{ - val = val.to_s - send_cmd :set, key, 0, exptime, val.respond_to?(:bytesize) ? val.bytesize : val.size, !block_given? - send_data val - send_data Cdelimiter - @set_cbs << cb if cb - } - end - - # Gets multiple values as a hash - # - # cache.get_hash(:a, :b, :c, :d){ |h| puts h[:a] } - # - def get_hash *keys - raise ArgumentError unless block_given? - - get *keys do |*values| - yield keys.inject({}){ |hash, k| hash.update k => values[keys.index(k)] } - end - end - - # Delete the value associated with a key - # - # cache.del :a - # cache.del(:b){ puts "deleted the value!" } - # - def delete key, expires = 0, &cb - callback{ - send_data "delete #{key} #{expires}#{cb ? '' : ' noreply'}\r\n" - @del_cbs << cb if cb - } - end - alias del delete - - # Connect to a memcached server (must support NOREPLY, memcached >= 1.2.4) - def self.connect host = 'localhost', port = 11211 - EM.connect host, port, self, host, port - end - - def send_cmd cmd, key, flags = 0, exptime = 0, bytes = 0, noreply = false - send_data "#{cmd} #{key} #{flags} #{exptime} #{bytes}#{noreply ? ' noreply' : ''}\r\n" - end - private :send_cmd - - ## - # errors - - # @private - class ParserError < StandardError - end - - ## - # em hooks - - # @private - def initialize host, port = 11211 - @host, @port = host, port - end - - # @private - def connection_completed - @get_cbs = [] - @set_cbs = [] - @del_cbs = [] - - @values = {} - - @reconnecting = false - @connected = true - succeed - # set_delimiter "\r\n" - # set_line_mode - end - - #-- - # 19Feb09 Switched to a custom parser, LineText2 is recursive and can cause - # stack overflows when there is too much data. - # include EM::P::LineText2 - # @private - def receive_data data - (@buffer||='') << data - - while index = @buffer.index(Cdelimiter) - begin - line = @buffer.slice!(0,index+2) - process_cmd line - rescue ParserError - @buffer[0...0] = line - break - end - end - end - - #-- - # def receive_line line - # @private - def process_cmd line - case line.strip - when /^VALUE\s+(.+?)\s+(\d+)\s+(\d+)/ # VALUE - bytes = Integer($3) - # set_binary_mode bytes+2 - # @cur_key = $1 - if @buffer.size >= bytes + 2 - @values[$1] = @buffer.slice!(0,bytes) - @buffer.slice!(0,2) # \r\n - else - raise ParserError - end - - when Cend # END - if entry = @get_cbs.shift - keys, cb = entry - cb.call(@values) - end - @values = {} - - when Cstored # STORED - if cb = @set_cbs.shift - cb.call(true) - end - - when Cdeleted # DELETED - if cb = @del_cbs.shift - cb.call(true) - end - - when Cunknown # NOT_FOUND - if cb = @del_cbs.shift - cb.call(false) - end - - else - p [:MEMCACHE_UNKNOWN, line] - end - end - - #-- - # def receive_binary_data data - # @values[@cur_key] = data[0..-3] - # end - - # @private - def unbind - if @connected or @reconnecting - EM.add_timer(1){ reconnect @host, @port } - @connected = false - @reconnecting = true - @deferred_status = nil - else - raise 'Unable to connect to memcached server' - end - end - end - end -end - -if __FILE__ == $0 - # ruby -I ext:lib -r eventmachine -rubygems lib/protocols/memcache.rb - require 'em/spec' - - # @private - class TestConnection - include EM::P::Memcache - def send_data data - sent_data << data - end - def sent_data - @sent_data ||= '' - end - - def initialize - connection_completed - end - end - - EM.describe EM::Protocols::Memcache do - - before{ - @c = TestConnection.new - } - - should 'send get requests' do - @c.get('a'){} - @c.sent_data.should == "get a\r\n" - done - end - - should 'send set requests' do - @c.set('a', 1){} - @c.sent_data.should == "set a 0 0 1\r\n1\r\n" - done - end - - should 'use noreply on set without block' do - @c.set('a', 1) - @c.sent_data.should == "set a 0 0 1 noreply\r\n1\r\n" - done - end - - should 'send delete requests' do - @c.del('a') - @c.sent_data.should == "delete a 0 noreply\r\n" - done - end - - should 'work when get returns no values' do - @c.get('a'){ |a| - a.should.be.nil - done - } - - @c.receive_data "END\r\n" - end - - should 'invoke block on set' do - @c.set('a', 1){ - done - } - - @c.receive_data "STORED\r\n" - end - - should 'invoke block on delete' do - @c.delete('a'){ |found| - found.should.be.false - } - @c.delete('b'){ |found| - found.should.be.true - done - } - - @c.receive_data "NOT_FOUND\r\n" - @c.receive_data "DELETED\r\n" - end - - should 'parse split responses' do - @c.get('a'){ |a| - a.should == 'abc' - done - } - - @c.receive_data "VAL" - @c.receive_data "UE a 0 " - @c.receive_data "3\r\n" - @c.receive_data "ab" - @c.receive_data "c" - @c.receive_data "\r\n" - @c.receive_data "EN" - @c.receive_data "D\r\n" - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/object_protocol.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/object_protocol.rb deleted file mode 100644 index ec79cb4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/object_protocol.rb +++ /dev/null @@ -1,46 +0,0 @@ -module EventMachine - module Protocols - # ObjectProtocol allows for easy communication using marshaled ruby objects - # - # module RubyServer - # include EM::P::ObjectProtocol - # - # def receive_object obj - # send_object({'you said' => obj}) - # end - # end - # - module ObjectProtocol - # By default returns Marshal, override to return JSON or YAML, or any - # other serializer/deserializer responding to #dump and #load. - def serializer - Marshal - end - - # @private - def receive_data data - (@buf ||= '') << data - - while @buf.size >= 4 - if @buf.size >= 4+(size=@buf.unpack('N').first) - @buf.slice!(0,4) - receive_object serializer.load(@buf.slice!(0,size)) - else - break - end - end - end - - # Invoked with ruby objects received over the network - def receive_object obj - # stub - end - - # Sends a ruby object over the network - def send_object obj - data = serializer.dump(obj) - send_data [data.respond_to?(:bytesize) ? data.bytesize : data.size, data].pack('Na*') - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/postgres3.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/postgres3.rb deleted file mode 100644 index 7d87505..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/postgres3.rb +++ /dev/null @@ -1,246 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 November 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-08 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# -# - -require 'postgres-pr/message' -require 'postgres-pr/connection' -require 'stringio' - -# @private -class StringIO - # Reads exactly +n+ bytes. - # - # If the data read is nil an EOFError is raised. - # - # If the data read is too short an IOError is raised - def readbytes(n) - str = read(n) - if str == nil - raise EOFError, "End of file reached" - end - if str.size < n - raise IOError, "data truncated" - end - str - end - alias read_exactly_n_bytes readbytes -end - - -module EventMachine - module Protocols - # PROVISIONAL IMPLEMENTATION of an evented Postgres client. - # This implements version 3 of the Postgres wire protocol, which will work - # with any Postgres version from roughly 7.4 onward. - # - # Objective: we want to access Postgres databases without requiring threads. - # Until now this has been a problem because the Postgres client implementations - # have all made use of blocking I/O calls, which is incompatible with a - # thread-free evented model. - # - # But rather than re-implement the Postgres Wire3 protocol, we're taking advantage - # of the existing postgres-pr library, which was originally written by Michael - # Neumann but (at this writing) appears to be no longer maintained. Still, it's - # in basically a production-ready state, and the wire protocol isn't that complicated - # anyway. - # - # We're tucking in a bunch of require statements that may not be present in garden-variety - # EM installations. Until we find a good way to only require these if a program - # requires postgres, this file will need to be required explicitly. - # - # We need to monkeypatch StringIO because it lacks the #readbytes method needed - # by postgres-pr. - # The StringIO monkeypatch is lifted from the standard library readbytes.rb, - # which adds method #readbytes directly to class IO. But StringIO is not a subclass of IO. - # It is modified to raise an IOError instead of TruncatedDataException since the exception is unused. - # - # We cloned the handling of postgres messages from lib/postgres-pr/connection.rb - # in the postgres-pr library, and modified it for event-handling. - # - # TODO: The password handling in dispatch_conn_message is totally incomplete. - # - # - # We return Deferrables from the user-level operations surfaced by this interface. - # Experimentally, we're using the pattern of always returning a boolean value as the - # first argument of a deferrable callback to indicate success or failure. This is - # instead of the traditional pattern of calling Deferrable#succeed or #fail, and - # requiring the user to define both a callback and an errback function. - # - # === Usage - # EM.run { - # db = EM.connect_unix_domain( "/tmp/.s.PGSQL.5432", EM::P::Postgres3 ) - # db.connect( dbname, username, psw ).callback do |status| - # if status - # db.query( "select * from some_table" ).callback do |status, result, errors| - # if status - # result.rows.each do |row| - # p row - # end - # end - # end - # end - # end - # } - class Postgres3 < EventMachine::Connection - include PostgresPR - - def initialize - @data = "" - @params = {} - end - - def connect db, user, psw=nil - d = EM::DefaultDeferrable.new - d.timeout 15 - - if @pending_query || @pending_conn - d.succeed false, "Operation already in progress" - else - @pending_conn = d - prms = {"user"=>user, "database"=>db} - @user = user - if psw - @password = psw - #prms["password"] = psw - end - send_data PostgresPR::StartupMessage.new( 3 << 16, prms ).dump - end - - d - end - - def query sql - d = EM::DefaultDeferrable.new - d.timeout 15 - - if @pending_query || @pending_conn - d.succeed false, "Operation already in progress" - else - @r = PostgresPR::Connection::Result.new - @e = [] - @pending_query = d - send_data PostgresPR::Query.dump(sql) - end - - d - end - - - def receive_data data - @data << data - while @data.length >= 5 - pktlen = @data[1...5].unpack("N").first - if @data.length >= (1 + pktlen) - pkt = @data.slice!(0...(1+pktlen)) - m = StringIO.open( pkt, "r" ) {|io| PostgresPR::Message.read( io ) } - if @pending_conn - dispatch_conn_message m - elsif @pending_query - dispatch_query_message m - else - raise "Unexpected message from database" - end - else - break # very important, break out of the while - end - end - end - - - def unbind - if o = (@pending_query || @pending_conn) - o.succeed false, "lost connection" - end - end - - # Cloned and modified from the postgres-pr. - def dispatch_conn_message msg - case msg - when AuthentificationClearTextPassword - raise ArgumentError, "no password specified" if @password.nil? - send_data PasswordMessage.new(@password).dump - - when AuthentificationCryptPassword - raise ArgumentError, "no password specified" if @password.nil? - send_data PasswordMessage.new(@password.crypt(msg.salt)).dump - - when AuthentificationMD5Password - raise ArgumentError, "no password specified" if @password.nil? - require 'digest/md5' - - m = Digest::MD5.hexdigest(@password + @user) - m = Digest::MD5.hexdigest(m + msg.salt) - m = 'md5' + m - send_data PasswordMessage.new(m).dump - - when AuthentificationKerberosV4, AuthentificationKerberosV5, AuthentificationSCMCredential - raise "unsupported authentification" - - when AuthentificationOk - when ErrorResponse - raise msg.field_values.join("\t") - when NoticeResponse - @notice_processor.call(msg) if @notice_processor - when ParameterStatus - @params[msg.key] = msg.value - when BackendKeyData - # TODO - #p msg - when ReadyForQuery - # TODO: use transaction status - pc,@pending_conn = @pending_conn,nil - pc.succeed true - else - raise "unhandled message type" - end - end - - # Cloned and modified from the postgres-pr. - def dispatch_query_message msg - case msg - when DataRow - @r.rows << msg.columns - when CommandComplete - @r.cmd_tag = msg.cmd_tag - when ReadyForQuery - pq,@pending_query = @pending_query,nil - pq.succeed true, @r, @e - when RowDescription - @r.fields = msg.fields - when CopyInResponse - when CopyOutResponse - when EmptyQueryResponse - when ErrorResponse - # TODO - @e << msg - when NoticeResponse - @notice_processor.call(msg) if @notice_processor - else - # TODO - end - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/saslauth.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/saslauth.rb deleted file mode 100644 index 9cabc51..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/saslauth.rb +++ /dev/null @@ -1,175 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 November 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# -# - -module EventMachine - module Protocols - - # Implements SASL authd. - # This is a very, very simple protocol that mimics the one used - # by saslauthd and pwcheck, two outboard daemons included in the - # standard SASL library distro. - # The only thing this is really suitable for is SASL PLAIN - # (user+password) authentication, but the SASL libs that are - # linked into standard servers (like imapd and sendmail) implement - # the other ones. - # - # SASL-auth is intended for reasonably fast operation inside a - # single machine, so it has no transport-security (although there - # have been multi-machine extensions incorporating transport-layer - # encryption). - # - # The standard saslauthd module generally runs privileged and does - # its work by referring to the system-account files. - # - # This feature was added to EventMachine to enable the development - # of custom authentication/authorization engines for standard servers. - # - # To use SASLauth, include it in a class that subclasses EM::Connection, - # and reimplement the validate method. - # - # The typical way to incorporate this module into an authentication - # daemon would be to set it as the handler for a UNIX-domain socket. - # The code might look like this: - # - # EM.start_unix_domain_server( "/var/run/saslauthd/mux", MyHandler ) - # File.chmod( 0777, "/var/run/saslauthd/mux") - # - # The chmod is probably needed to ensure that unprivileged clients can - # access the UNIX-domain socket. - # - # It's also a very good idea to drop superuser privileges (if any), after - # the UNIX-domain socket has been opened. - #-- - # Implementation details: assume the client can send us pipelined requests, - # and that the client will close the connection. - # - # The client sends us four values, each encoded as a two-byte length field in - # network order followed by the specified number of octets. - # The fields specify the username, password, service name (such as imap), - # and the "realm" name. We send back the barest minimum reply, a single - # field also encoded as a two-octet length in network order, followed by - # either "NO" or "OK" - simplicity itself. - # - # We enforce a maximum field size just as a sanity check. - # We do NOT automatically time out the connection. - # - # The code we use to parse out the values is ugly and probably slow. - # Improvements welcome. - # - module SASLauth - - MaxFieldSize = 128*1024 - def post_init - super - @sasl_data = "" - @sasl_values = [] - end - - def receive_data data - @sasl_data << data - while @sasl_data.length >= 2 - len = (@sasl_data[0,2].unpack("n")).first - raise "SASL Max Field Length exceeded" if len > MaxFieldSize - if @sasl_data.length >= (len + 2) - @sasl_values << @sasl_data[2,len] - @sasl_data.slice!(0...(2+len)) - if @sasl_values.length == 4 - send_data( validate(*@sasl_values) ? "\0\002OK" : "\0\002NO" ) - @sasl_values.clear - end - else - break - end - end - end - - def validate username, psw, sysname, realm - p username - p psw - p sysname - p realm - true - end - end - - # Implements the SASL authd client protocol. - # This is a very, very simple protocol that mimics the one used - # by saslauthd and pwcheck, two outboard daemons included in the - # standard SASL library distro. - # The only thing this is really suitable for is SASL PLAIN - # (user+password) authentication, but the SASL libs that are - # linked into standard servers (like imapd and sendmail) implement - # the other ones. - # - # You can use this module directly as a handler for EM Connections, - # or include it in a module or handler class of your own. - # - # First connect to a SASL server (it's probably a TCP server, or more - # likely a Unix-domain socket). Then call the #validate? method, - # passing at least a username and a password. #validate? returns - # a Deferrable which will either succeed or fail, depending - # on the status of the authentication operation. - # - module SASLauthclient - MaxFieldSize = 128*1024 - - def validate? username, psw, sysname=nil, realm=nil - - str = [username, psw, sysname, realm].map {|m| - [(m || "").length, (m || "")] - }.flatten.pack( "nA*" * 4 ) - send_data str - - d = EM::DefaultDeferrable.new - @queries.unshift d - d - end - - def post_init - @sasl_data = "" - @queries = [] - end - - def receive_data data - @sasl_data << data - - while @sasl_data.length > 2 - len = (@sasl_data[0,2].unpack("n")).first - raise "SASL Max Field Length exceeded" if len > MaxFieldSize - if @sasl_data.length >= (len + 2) - val = @sasl_data[2,len] - @sasl_data.slice!(0...(2+len)) - q = @queries.pop - (val == "NO") ? q.fail : q.succeed - else - break - end - end - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpclient.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpclient.rb deleted file mode 100644 index 25ad17a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpclient.rb +++ /dev/null @@ -1,394 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 July 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -require 'ostruct' - -module EventMachine - module Protocols - - # Simple SMTP client - # - # @example - # email = EM::Protocols::SmtpClient.send( - # :domain=>"example.com", - # :host=>'localhost', - # :port=>25, # optional, defaults 25 - # :starttls=>true, # use ssl - # :from=>"sender@example.com", - # :to=> ["to_1@example.com", "to_2@example.com"], - # :header=> {"Subject" => "This is a subject line"}, - # :body=> "This is the body of the email" - # ) - # email.callback{ - # puts 'Email sent!' - # } - # email.errback{ |e| - # puts 'Email failed!' - # } - # - # Sending generated emails (using Mail) - # - # mail = Mail.new do - # from 'alice@example.com' - # to 'bob@example.com' - # subject 'This is a test email' - # body 'Hello, world!' - # end - # - # email = EM::P::SmtpClient.send( - # :domain=>'example.com', - # :from=>mail.from.first, - # :to=>mail.to, - # :message=>mail.to_s - # ) - # - class SmtpClient < Connection - include EventMachine::Deferrable - include EventMachine::Protocols::LineText2 - - def initialize - @succeeded = nil - @responder = nil - @code = nil - @msg = nil - end - - # :host => required String - # a string containing the IP address or host name of the SMTP server to connect to. - # :port => optional - # defaults to 25. - # :domain => required String - # This is passed as the argument to the EHLO command. - # :starttls => optional Boolean - # If it evaluates true, then the client will initiate STARTTLS with - # the server, and abort the connection if the negotiation doesn't succeed. - # TODO, need to be able to pass certificate parameters with this option. - # :auth => optional Hash of auth parameters - # If not given, then no auth will be attempted. - # (In that case, the connection will be aborted if the server requires auth.) - # Specify the hash value :type to determine the auth type, along with additional parameters - # depending on the type. - # Currently only :type => :plain is supported. Pass additional parameters :username (String), - # and :password (either a String or a Proc that will be called at auth-time). - # - # @example - # :auth => {:type=>:plain, :username=>"mickey@disney.com", :password=>"mouse"} - # - # :from => required String - # Specifies the sender of the message. Will be passed as the argument - # to the MAIL FROM. Do NOT enclose the argument in angle-bracket (<>) characters. - # The connection will abort if the server rejects the value. - # :to => required String or Array of Strings - # The recipient(s) of the message. Do NOT enclose - # any of the values in angle-brackets (<>) characters. It's NOT a fatal error if one or more - # recipients are rejected by the server. (Of course, if ALL of them are, the server will most - # likely trigger an error when we try to send data.) An array of codes containing the status - # of each requested recipient is available after the call completes. TODO, we should define - # an overridable stub that will be called on rejection of a recipient or a sender, giving - # user code the chance to try again or abort the connection. - # - # One of either :message, :content, or :header and :body is required: - # - # :message => String - # A valid RFC2822 Internet Message. - # :content => String - # Raw data which MUST be in correct SMTP body format, with escaped leading dots and a trailing - # dot line. - # :header => String or Hash of values to be transmitted in the header of the message. - # The hash keys are the names of the headers (do NOT append a trailing colon), and the values - # are strings containing the header values. TODO, support Arrays of header values, which would - # cause us to send that specific header line more than once. - # - # @example - # :header => {"Subject" => "Bogus", "CC" => "myboss@example.com"} - # - # :body => Optional String or Array of Strings, defaults blank. - # This will be passed as the body of the email message. - # TODO, this needs to be significantly beefed up. As currently written, this requires the caller - # to properly format the input into CRLF-delimited lines of 7-bit characters in the standard - # SMTP transmission format. We need to be able to automatically convert binary data, and add - # correct line-breaks to text data. - # - # :verbose => Optional. - # If true, will cause a lot of information (including the server-side of the - # conversation) to be dumped to $>. - # - def self.send args={} - args[:port] ||= 25 - args[:body] ||= "" - -=begin - (I don't think it's possible for EM#connect to throw an exception under normal - circumstances, so this original code is stubbed out. A connect-failure will result - in the #unbind method being called without calling #connection_completed.) - begin - EventMachine.connect( args[:host], args[:port], self) {|c| - # According to the EM docs, we will get here AFTER post_init is called. - c.args = args - c.set_comm_inactivity_timeout 60 - } - rescue - # We'll get here on a connect error. This code mimics the effect - # of a call to invoke_internal_error. Would be great to DRY this up. - # (Actually, it may be that we never get here, if EM#connect catches - # its errors internally.) - d = EM::DefaultDeferrable.new - d.set_deferred_status(:failed, {:error=>[:connect, 500, "unable to connect to server"]}) - d - end -=end - EventMachine.connect( args[:host], args[:port], self) {|c| - # According to the EM docs, we will get here AFTER post_init is called. - c.args = args - c.set_comm_inactivity_timeout 60 - } - end - - attr_writer :args - - # @private - def post_init - @return_values = OpenStruct.new - @return_values.start_time = Time.now - end - - # @private - def connection_completed - @responder = :receive_signon - @msg = [] - end - - # We can get here in a variety of ways, all of them being failures unless - # the @succeeded flag is set. If a protocol success was recorded, then don't - # set a deferred success because the caller will already have done it - # (no need to wait until the connection closes to invoke the callbacks). - # - # @private - def unbind - unless @succeeded - @return_values.elapsed_time = Time.now - @return_values.start_time - @return_values.responder = @responder - @return_values.code = @code - @return_values.message = @msg - set_deferred_status(:failed, @return_values) - end - end - - # @private - def receive_line ln - $>.puts ln if @args[:verbose] - @range = ln[0...1].to_i - @code = ln[0...3].to_i - @msg << ln[4..-1] - unless ln[3...4] == '-' - $>.puts @responder if @args[:verbose] - send @responder - @msg.clear - end - end - - private - - # We encountered an error from the server and will close the connection. - # Use the error and message the server returned. - # - def invoke_error - @return_values.elapsed_time = Time.now - @return_values.start_time - @return_values.responder = @responder - @return_values.code = @code - @return_values.message = @msg - set_deferred_status :failed, @return_values - send_data "QUIT\r\n" - close_connection_after_writing - end - - # We encountered an error on our side of the protocol and will close the connection. - # Use an extra-protocol error code (900) and use the message from the caller. - # - def invoke_internal_error msg = "???" - @return_values.elapsed_time = Time.now - @return_values.start_time - @return_values.responder = @responder - @return_values.code = 900 - @return_values.message = msg - set_deferred_status :failed, @return_values - send_data "QUIT\r\n" - close_connection_after_writing - end - - def send_ehlo - send_data "EHLO #{@args[:domain]}\r\n" - end - - def receive_signon - return invoke_error unless @range == 2 - send_ehlo - @responder = :receive_ehlo_response - end - def receive_ehlo_response - return invoke_error unless @range == 2 - @server_caps = @msg - invoke_starttls - end - - def invoke_starttls - if @args[:starttls] - # It would be more sociable to first ask if @server_caps contains - # the string "STARTTLS" before we invoke it, but hey, life's too short. - send_data "STARTTLS\r\n" - @responder = :receive_starttls_response - else - invoke_auth - end - end - def receive_starttls_response - return invoke_error unless @range == 2 - start_tls - invoke_ehlo_over_tls - end - - def invoke_ehlo_over_tls - send_ehlo - @responder = :receive_ehlo_over_tls_response - end - def receive_ehlo_over_tls_response - return invoke_error unless @range == 2 - invoke_auth - end - - # Perform an authentication. If the caller didn't request one, then fall through - # to the mail-from state. - def invoke_auth - if @args[:auth] - if @args[:auth][:type] == :plain - psw = @args[:auth][:password] - if psw.respond_to?(:call) - psw = psw.call - end - #str = Base64::encode64("\0#{@args[:auth][:username]}\0#{psw}").chomp - str = ["\0#{@args[:auth][:username]}\0#{psw}"].pack("m").gsub(/\n/, '') - send_data "AUTH PLAIN #{str}\r\n" - @responder = :receive_auth_response - else - return invoke_internal_error("unsupported auth type") - end - else - invoke_mail_from - end - end - def receive_auth_response - return invoke_error unless @range == 2 - invoke_mail_from - end - - def invoke_mail_from - send_data "MAIL FROM: <#{@args[:from]}>\r\n" - @responder = :receive_mail_from_response - end - def receive_mail_from_response - return invoke_error unless @range == 2 - invoke_rcpt_to - end - - def invoke_rcpt_to - @rcpt_responses ||= [] - l = @rcpt_responses.length - to = @args[:to].is_a?(Array) ? @args[:to] : [@args[:to].to_s] - if l < to.length - send_data "RCPT TO: <#{to[l]}>\r\n" - @responder = :receive_rcpt_to_response - else - e = @rcpt_responses.select {|rr| rr.last == 2} - if e and e.length > 0 - invoke_data - else - invoke_error - end - end - end - def receive_rcpt_to_response - @rcpt_responses << [@code, @msg, @range] - invoke_rcpt_to - end - - def escape_leading_dots(s) - s.gsub(/^\./, '..') - end - - def invoke_data - send_data "DATA\r\n" - @responder = :receive_data_response - end - def receive_data_response - return invoke_error unless @range == 3 - - # The data to send can be given in either @args[:message], @args[:content], or the - # combination of @args[:header] and @args[:body]. - # - # - @args[:message] (String) MUST be a valid RFC2822 Internet Message - # - # - @args[:content] (String) MUST be in correct SMTP body format, with escaped - # leading dots and a trailing dot line - # - # - @args[:header] (Hash or String) - # - @args[:body] (Array or String) - if @args[:message] - send_data escape_leading_dots(@args[:message].to_s) - send_data "\r\n.\r\n" - elsif @args[:content] - send_data @args[:content].to_s - else - # The header can be a hash or an array. - if @args[:header].is_a?(Hash) - (@args[:header] || {}).each {|k,v| send_data escape_leading_dots("#{k}: #{v}\r\n") } - else - send_data escape_leading_dots(@args[:header].to_s) - end - send_data "\r\n" - - if @args[:body].is_a?(Array) - @args[:body].each {|e| send_data escape_leading_dots(e)} - else - send_data escape_leading_dots(@args[:body].to_s) - end - - send_data "\r\n.\r\n" - end - - @responder = :receive_message_response - end - def receive_message_response - return invoke_error unless @range == 2 - send_data "QUIT\r\n" - close_connection_after_writing - @succeeded = true - @return_values.elapsed_time = Time.now - @return_values.start_time - @return_values.responder = @responder - @return_values.code = @code - @return_values.message = @msg - set_deferred_status :succeeded, @return_values - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpserver.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpserver.rb deleted file mode 100644 index e0f1f05..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/smtpserver.rb +++ /dev/null @@ -1,666 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 July 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - module Protocols - - # This is a protocol handler for the server side of SMTP. - # It's NOT a complete SMTP server obeying all the semantics of servers conforming to - # RFC2821. Rather, it uses overridable method stubs to communicate protocol states - # and data to user code. User code is responsible for doing the right things with the - # data in order to get complete and correct SMTP server behavior. - # - # Simple SMTP server example: - # - # class EmailServer < EM::P::SmtpServer - # def receive_plain_auth(user, pass) - # true - # end - # - # def get_server_domain - # "mock.smtp.server.local" - # end - # - # def get_server_greeting - # "mock smtp server greets you with impunity" - # end - # - # def receive_sender(sender) - # current.sender = sender - # true - # end - # - # def receive_recipient(recipient) - # current.recipient = recipient - # true - # end - # - # def receive_message - # current.received = true - # current.completed_at = Time.now - # - # p [:received_email, current] - # @current = OpenStruct.new - # true - # end - # - # def receive_ehlo_domain(domain) - # @ehlo_domain = domain - # true - # end - # - # def receive_data_command - # current.data = "" - # true - # end - # - # def receive_data_chunk(data) - # current.data << data.join("\n") - # true - # end - # - # def receive_transaction - # if @ehlo_domain - # current.ehlo_domain = @ehlo_domain - # @ehlo_domain = nil - # end - # true - # end - # - # def current - # @current ||= OpenStruct.new - # end - # - # def self.start(host = 'localhost', port = 1025) - # require 'ostruct' - # @server = EM.start_server host, port, self - # end - # - # def self.stop - # if @server - # EM.stop_server @server - # @server = nil - # end - # end - # - # def self.running? - # !!@server - # end - # end - # - # EM.run{ EmailServer.start } - # - #-- - # Useful paragraphs in RFC-2821: - # 4.3.2: Concise list of command-reply sequences, in essence a text representation - # of the command state-machine. - # - # STARTTLS is defined in RFC2487. - # Observe that there are important rules governing whether a publicly-referenced server - # (meaning one whose Internet address appears in public MX records) may require the - # non-optional use of TLS. - # Non-optional TLS does not apply to EHLO, NOOP, QUIT or STARTTLS. - class SmtpServer < EventMachine::Connection - include Protocols::LineText2 - - HeloRegex = /\AHELO\s*/i - EhloRegex = /\AEHLO\s*/i - QuitRegex = /\AQUIT/i - MailFromRegex = /\AMAIL FROM:\s*/i - RcptToRegex = /\ARCPT TO:\s*/i - DataRegex = /\ADATA/i - NoopRegex = /\ANOOP/i - RsetRegex = /\ARSET/i - VrfyRegex = /\AVRFY\s+/i - ExpnRegex = /\AEXPN\s+/i - HelpRegex = /\AHELP/i - StarttlsRegex = /\ASTARTTLS/i - AuthRegex = /\AAUTH\s+/i - - - # Class variable containing default parameters that can be overridden - # in application code. - # Individual objects of this class will make an instance-local copy of - # the class variable, so that they can be reconfigured on a per-instance - # basis. - # - # Chunksize is the number of data lines we'll buffer before - # sending them to the application. TODO, make this user-configurable. - # - @@parms = { - :chunksize => 4000, - :verbose => false - } - def self.parms= parms={} - @@parms.merge!(parms) - end - - - - def initialize *args - super - @parms = @@parms - init_protocol_state - end - - def parms= parms={} - @parms.merge!(parms) - end - - # In SMTP, the server talks first. But by a (perhaps flawed) axiom in EM, - # #post_init will execute BEFORE the block passed to #start_server, for any - # given accepted connection. Since in this class we'll probably be getting - # a lot of initialization parameters, we want the guts of post_init to - # run AFTER the application has initialized the connection object. So we - # use a spawn to schedule the post_init to run later. - # It's a little weird, I admit. A reasonable alternative would be to set - # parameters as a class variable and to do that before accepting any connections. - # - # OBSOLETE, now we have @@parms. But the spawn is nice to keep as an illustration. - # - def post_init - #send_data "220 #{get_server_greeting}\r\n" (ORIGINAL) - #(EM.spawn {|x| x.send_data "220 #{x.get_server_greeting}\r\n"}).notify(self) - (EM.spawn {|x| x.send_server_greeting}).notify(self) - end - - def send_server_greeting - send_data "220 #{get_server_greeting}\r\n" - end - - def receive_line ln - @@parms[:verbose] and $>.puts ">>> #{ln}" - - return process_data_line(ln) if @state.include?(:data) - return process_auth_line(ln) if @state.include?(:auth_incomplete) - - case ln - when EhloRegex - process_ehlo $'.dup - when HeloRegex - process_helo $'.dup - when MailFromRegex - process_mail_from $'.dup - when RcptToRegex - process_rcpt_to $'.dup - when DataRegex - process_data - when RsetRegex - process_rset - when VrfyRegex - process_vrfy - when ExpnRegex - process_expn - when HelpRegex - process_help - when NoopRegex - process_noop - when QuitRegex - process_quit - when StarttlsRegex - process_starttls - when AuthRegex - process_auth $'.dup - else - process_unknown - end - end - - # TODO - implement this properly, the implementation is a stub! - def process_help - send_data "250 Ok, but unimplemented\r\n" - end - - # RFC2821, 3.5.3 Meaning of VRFY or EXPN Success Response: - # A server MUST NOT return a 250 code in response to a VRFY or EXPN - # command unless it has actually verified the address. In particular, - # a server MUST NOT return 250 if all it has done is to verify that the - # syntax given is valid. In that case, 502 (Command not implemented) - # or 500 (Syntax error, command unrecognized) SHOULD be returned. - # - # TODO - implement this properly, the implementation is a stub! - def process_vrfy - send_data "502 Command not implemented\r\n" - end - # TODO - implement this properly, the implementation is a stub! - def process_expn - send_data "502 Command not implemented\r\n" - end - - #-- - # This is called at several points to restore the protocol state - # to a pre-transaction state. In essence, we "forget" having seen - # any valid command except EHLO and STARTTLS. - # We also have to callback user code, in case they're keeping track - # of senders, recipients, and whatnot. - # - # We try to follow the convention of avoiding the verb "receive" for - # internal method names except receive_line (which we inherit), and - # using only receive_xxx for user-overridable stubs. - # - # init_protocol_state is called when we initialize the connection as - # well as during reset_protocol_state. It does NOT call the user - # override method. This enables us to promise the users that they - # won't see the overridable fire except after EHLO and RSET, and - # after a message has been received. Although the latter may be wrong. - # The standard may allow multiple DATA segments with the same set of - # senders and recipients. - # - def reset_protocol_state - init_protocol_state - s,@state = @state,[] - @state << :starttls if s.include?(:starttls) - @state << :ehlo if s.include?(:ehlo) - receive_transaction - end - def init_protocol_state - @state ||= [] - end - - - #-- - # EHLO/HELO is always legal, per the standard. On success - # it always clears buffers and initiates a mail "transaction." - # Which means that a MAIL FROM must follow. - # - # Per the standard, an EHLO/HELO or a RSET "initiates" an email - # transaction. Thereafter, MAIL FROM must be received before - # RCPT TO, before DATA. Not sure what this specific ordering - # achieves semantically, but it does make it easier to - # implement. We also support user-specified requirements for - # STARTTLS and AUTH. We make it impossible to proceed to MAIL FROM - # without fulfilling tls and/or auth, if the user specified either - # or both as required. We need to check the extension standard - # for auth to see if a credential is discarded after a RSET along - # with all the rest of the state. We'll behave as if it is. - # Now clearly, we can't discard tls after its been negotiated - # without dropping the connection, so that flag doesn't get cleared. - # - def process_ehlo domain - if receive_ehlo_domain domain - send_data "250-#{get_server_domain}\r\n" - if @@parms[:starttls] - send_data "250-STARTTLS\r\n" - end - if @@parms[:auth] - send_data "250-AUTH PLAIN\r\n" - end - send_data "250-NO-SOLICITING\r\n" - # TODO, size needs to be configurable. - send_data "250 SIZE 20000000\r\n" - reset_protocol_state - @state << :ehlo - else - send_data "550 Requested action not taken\r\n" - end - end - - def process_helo domain - if receive_ehlo_domain domain.dup - send_data "250 #{get_server_domain}\r\n" - reset_protocol_state - @state << :ehlo - else - send_data "550 Requested action not taken\r\n" - end - end - - def process_quit - send_data "221 Ok\r\n" - close_connection_after_writing - end - - def process_noop - send_data "250 Ok\r\n" - end - - def process_unknown - send_data "500 Unknown command\r\n" - end - - #-- - # So far, only AUTH PLAIN is supported but we should do at least LOGIN as well. - # TODO, support clients that send AUTH PLAIN with no parameter, expecting a 3xx - # response and a continuation of the auth conversation. - # - def process_auth str - if @state.include?(:auth) - send_data "503 auth already issued\r\n" - elsif str =~ /\APLAIN\s?/i - if $'.length == 0 - # we got a partial response, so let the client know to send the rest - @state << :auth_incomplete - send_data("334 \r\n") - else - # we got the initial response, so go ahead & process it - process_auth_line($') - end - #elsif str =~ /\ALOGIN\s+/i - else - send_data "504 auth mechanism not available\r\n" - end - end - - def process_auth_line(line) - plain = line.unpack("m").first - _,user,psw = plain.split("\000") - - succeeded = proc { - send_data "235 authentication ok\r\n" - @state << :auth - } - failed = proc { - send_data "535 invalid authentication\r\n" - } - auth = receive_plain_auth user,psw - - if auth.respond_to?(:callback) - auth.callback(&succeeded) - auth.errback(&failed) - else - (auth ? succeeded : failed).call - end - - @state.delete :auth_incomplete - end - - #-- - # Unusually, we can deal with a Deferrable returned from the user application. - # This was added to deal with a special case in a particular application, but - # it would be a nice idea to add it to the other user-code callbacks. - # - def process_data - unless @state.include?(:rcpt) - send_data "503 Operation sequence error\r\n" - else - succeeded = proc { - send_data "354 Send it\r\n" - @state << :data - @databuffer = [] - } - failed = proc { - send_data "550 Operation failed\r\n" - } - - d = receive_data_command - - if d.respond_to?(:callback) - d.callback(&succeeded) - d.errback(&failed) - else - (d ? succeeded : failed).call - end - end - end - - def process_rset - reset_protocol_state - receive_reset - send_data "250 Ok\r\n" - end - - def unbind - connection_ended - end - - #-- - # STARTTLS may not be issued before EHLO, or unless the user has chosen - # to support it. - # - # If :starttls_options is present and :starttls is set in the parms - # pass the options in :starttls_options to start_tls. Do this if you want to use - # your own certificate - # e.g. {:cert_chain_file => "/etc/ssl/cert.pem", :private_key_file => "/etc/ssl/private/cert.key"} - - def process_starttls - if @@parms[:starttls] - if @state.include?(:starttls) - send_data "503 TLS Already negotiated\r\n" - elsif ! @state.include?(:ehlo) - send_data "503 EHLO required before STARTTLS\r\n" - else - send_data "220 Start TLS negotiation\r\n" - start_tls(@@parms[:starttls_options] || {}) - @state << :starttls - end - else - process_unknown - end - end - - - #-- - # Requiring TLS is touchy, cf RFC2784. - # Requiring AUTH seems to be much more reasonable. - # We don't currently support any notion of deriving an authentication from the TLS - # negotiation, although that would certainly be reasonable. - # We DON'T allow MAIL FROM to be given twice. - # We DON'T enforce all the various rules for validating the sender or - # the reverse-path (like whether it should be null), and notifying the reverse - # path in case of delivery problems. All of that is left to the calling application. - # - def process_mail_from sender - if (@@parms[:starttls]==:required and !@state.include?(:starttls)) - send_data "550 This server requires STARTTLS before MAIL FROM\r\n" - elsif (@@parms[:auth]==:required and !@state.include?(:auth)) - send_data "550 This server requires authentication before MAIL FROM\r\n" - elsif @state.include?(:mail_from) - send_data "503 MAIL already given\r\n" - else - unless receive_sender sender - send_data "550 sender is unacceptable\r\n" - else - send_data "250 Ok\r\n" - @state << :mail_from - end - end - end - - #-- - # Since we require :mail_from to have been seen before we process RCPT TO, - # we don't need to repeat the tests for TLS and AUTH. - # Note that we don't remember or do anything else with the recipients. - # All of that is on the user code. - # TODO: we should enforce user-definable limits on the total number of - # recipients per transaction. - # We might want to make sure that a given recipient is only seen once, but - # for now we'll let that be the user's problem. - # - # User-written code can return a deferrable from receive_recipient. - # - def process_rcpt_to rcpt - unless @state.include?(:mail_from) - send_data "503 MAIL is required before RCPT\r\n" - else - succeeded = proc { - send_data "250 Ok\r\n" - @state << :rcpt unless @state.include?(:rcpt) - } - failed = proc { - send_data "550 recipient is unacceptable\r\n" - } - - d = receive_recipient rcpt - - if d.respond_to?(:set_deferred_status) - d.callback(&succeeded) - d.errback(&failed) - else - (d ? succeeded : failed).call - end - -=begin - unless receive_recipient rcpt - send_data "550 recipient is unacceptable\r\n" - else - send_data "250 Ok\r\n" - @state << :rcpt unless @state.include?(:rcpt) - end -=end - end - end - - - # Send the incoming data to the application one chunk at a time, rather than - # one line at a time. That lets the application be a little more flexible about - # storing to disk, etc. - # Since we clear the chunk array every time we submit it, the caller needs to be - # aware to do things like dup it if he wants to keep it around across calls. - # - # Resets the transaction upon disposition of the incoming message. - # RFC5321 says this about the MAIL FROM command: - # "This command tells the SMTP-receiver that a new mail transaction is - # starting and to reset all its state tables and buffers, including any - # recipients or mail data." - # - # Equivalent behaviour is implemented by resetting after a completed transaction. - # - # User-written code can return a Deferrable as a response from receive_message. - # - def process_data_line ln - if ln == "." - if @databuffer.length > 0 - receive_data_chunk @databuffer - @databuffer.clear - end - - - succeeded = proc { - send_data "250 Message accepted\r\n" - reset_protocol_state - } - failed = proc { - send_data "550 Message rejected\r\n" - reset_protocol_state - } - d = receive_message - - if d.respond_to?(:set_deferred_status) - d.callback(&succeeded) - d.errback(&failed) - else - (d ? succeeded : failed).call - end - - @state.delete :data - else - # slice off leading . if any - ln.slice!(0...1) if ln[0] == ?. - @databuffer << ln - if @databuffer.length > @@parms[:chunksize] - receive_data_chunk @databuffer - @databuffer.clear - end - end - end - - - #------------------------------------------ - # Everything from here on can be overridden in user code. - - # The greeting returned in the initial connection message to the client. - def get_server_greeting - "EventMachine SMTP Server" - end - # The domain name returned in the first line of the response to a - # successful EHLO or HELO command. - def get_server_domain - "Ok EventMachine SMTP Server" - end - - # A false response from this user-overridable method will cause a - # 550 error to be returned to the remote client. - # - def receive_ehlo_domain domain - true - end - - # Return true or false to indicate that the authentication is acceptable. - def receive_plain_auth user, password - true - end - - # Receives the argument of the MAIL FROM command. Return false to - # indicate to the remote client that the sender is not accepted. - # This can only be successfully called once per transaction. - # - def receive_sender sender - true - end - - # Receives the argument of a RCPT TO command. Can be given multiple - # times per transaction. Return false to reject the recipient. - # - def receive_recipient rcpt - true - end - - # Sent when the remote peer issues the RSET command. - # Since RSET is not allowed to fail (according to the protocol), - # we ignore any return value from user overrides of this method. - # - def receive_reset - end - - # Sent when the remote peer has ended the connection. - # - def connection_ended - end - - # Called when the remote peer sends the DATA command. - # Returning false will cause us to send a 550 error to the peer. - # This can be useful for dealing with problems that arise from processing - # the whole set of sender and recipients. - # - def receive_data_command - true - end - - # Sent when data from the remote peer is available. The size can be controlled - # by setting the :chunksize parameter. This call can be made multiple times. - # The goal is to strike a balance between sending the data to the application one - # line at a time, and holding all of a very large message in memory. - # - def receive_data_chunk data - @smtps_msg_size ||= 0 - @smtps_msg_size += data.join.length - STDERR.write "<#{@smtps_msg_size}>" - end - - # Sent after a message has been completely received. User code - # must return true or false to indicate whether the message has - # been accepted for delivery. - def receive_message - @@parms[:verbose] and $>.puts "Received complete message" - true - end - - # This is called when the protocol state is reset. It happens - # when the remote client calls EHLO/HELO or RSET. - def receive_transaction - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/socks4.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/socks4.rb deleted file mode 100644 index 132f320..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/socks4.rb +++ /dev/null @@ -1,66 +0,0 @@ -module EventMachine - module Protocols - # Basic SOCKS v4 client implementation - # - # Use as you would any regular connection: - # - # class MyConn < EM::P::Socks4 - # def post_init - # send_data("sup") - # end - # - # def receive_data(data) - # send_data("you said: #{data}") - # end - # end - # - # EM.connect socks_host, socks_port, MyConn, host, port - # - class Socks4 < Connection - def initialize(host, port) - @host = Socket.gethostbyname(host).last - @port = port - @socks_error_code = nil - @buffer = '' - setup_methods - end - - def setup_methods - class << self - def post_init; socks_post_init; end - def receive_data(*a); socks_receive_data(*a); end - end - end - - def restore_methods - class << self - remove_method :post_init - remove_method :receive_data - end - end - - def socks_post_init - header = [4, 1, @port, @host, 0].flatten.pack("CCnA4C") - send_data(header) - end - - def socks_receive_data(data) - @buffer << data - return if @buffer.size < 8 - - header_resp = @buffer.slice! 0, 8 - _, r = header_resp.unpack("cc") - if r != 90 - @socks_error_code = r - close_connection - return - end - - restore_methods - - post_init - receive_data(@buffer) unless @buffer.empty? - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/stomp.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/stomp.rb deleted file mode 100644 index ca6f078..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/stomp.rb +++ /dev/null @@ -1,205 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 15 November 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# -# - -module EventMachine - module Protocols - - # Implements Stomp (http://docs.codehaus.org/display/STOMP/Protocol). - # - # == Usage example - # - # module StompClient - # include EM::Protocols::Stomp - # - # def connection_completed - # connect :login => 'guest', :passcode => 'guest' - # end - # - # def receive_msg msg - # if msg.command == "CONNECTED" - # subscribe '/some/topic' - # else - # p ['got a message', msg] - # puts msg.body - # end - # end - # end - # - # EM.run{ - # EM.connect 'localhost', 61613, StompClient - # } - # - module Stomp - include LineText2 - - class Message - # The command associated with the message, usually 'CONNECTED' or 'MESSAGE' - attr_accessor :command - # Hash containing headers such as destination and message-id - attr_accessor :header - alias :headers :header - # Body of the message - attr_accessor :body - - # @private - def initialize - @header = {} - @state = :precommand - @content_length = nil - end - # @private - def consume_line line - if @state == :precommand - unless line =~ /\A\s*\Z/ - @command = line - @state = :headers - end - elsif @state == :headers - if line == "" - if @content_length - yield( [:sized_text, @content_length+1] ) - else - @state = :body - yield( [:unsized_text] ) - end - elsif line =~ /\A([^:]+):(.+)\Z/ - k = $1.dup.strip - v = $2.dup.strip - @header[k] = v - if k == "content-length" - @content_length = v.to_i - end - else - # This is a protocol error. How to signal it? - end - elsif @state == :body - @body = line - yield( [:dispatch] ) - end - end - end - - # @private - def send_frame verb, headers={}, body="" - body = body.to_s - ary = [verb, "\n"] - body_bytesize = body.bytesize if body.respond_to? :bytesize - body_bytesize ||= body.size - headers.each {|k,v| ary << "#{k}:#{v}\n" } - ary << "content-length: #{body_bytesize}\n" - ary << "content-type: text/plain; charset=UTF-8\n" unless headers.has_key? 'content-type' - ary << "\n" - ary << body - ary << "\0" - send_data ary.join - end - - # @private - def receive_line line - @stomp_initialized || init_message_reader - @stomp_message.consume_line(line) {|outcome| - if outcome.first == :sized_text - set_text_mode outcome[1] - elsif outcome.first == :unsized_text - set_delimiter "\0" - elsif outcome.first == :dispatch - receive_msg(@stomp_message) if respond_to?(:receive_msg) - init_message_reader - end - } - end - - # @private - def receive_binary_data data - @stomp_message.body = data[0..-2] - receive_msg(@stomp_message) if respond_to?(:receive_msg) - init_message_reader - end - - # @private - def init_message_reader - @stomp_initialized = true - set_delimiter "\n" - set_line_mode - @stomp_message = Message.new - end - - # Invoked with an incoming Stomp::Message received from the STOMP server - def receive_msg msg - # stub, overwrite this in your handler - end - - # CONNECT command, for authentication - # - # connect :login => 'guest', :passcode => 'guest' - # - def connect parms={} - send_frame "CONNECT", parms - end - - # SEND command, for publishing messages to a topic - # - # send '/topic/name', 'some message here' - # - def send destination, body, parms={} - send_frame "SEND", parms.merge( :destination=>destination ), body.to_s - end - - # SUBSCRIBE command, for subscribing to topics - # - # subscribe '/topic/name', false - # - def subscribe dest, ack=false - send_frame "SUBSCRIBE", {:destination=>dest, :ack=>(ack ? "client" : "auto")} - end - - # ACK command, for acknowledging receipt of messages - # - # module StompClient - # include EM::P::Stomp - # - # def connection_completed - # connect :login => 'guest', :passcode => 'guest' - # # subscribe with ack mode - # subscribe '/some/topic', true - # end - # - # def receive_msg msg - # if msg.command == "MESSAGE" - # ack msg.headers['message-id'] - # puts msg.body - # end - # end - # end - # - def ack msgid - send_frame "ACK", 'message-id'=> msgid - end - - end - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/tcptest.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/tcptest.rb deleted file mode 100644 index 3187893..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/protocols/tcptest.rb +++ /dev/null @@ -1,54 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 16 July 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# -# - -module EventMachine - module Protocols - - # @private - class TcpConnectTester < Connection - include EventMachine::Deferrable - - def self.test( host, port ) - EventMachine.connect( host, port, self ) - end - - def post_init - @start_time = Time.now - end - - def connection_completed - @completed = true - set_deferred_status :succeeded, (Time.now - @start_time) - close_connection - end - - def unbind - set_deferred_status :failed, (Time.now - @start_time) unless @completed - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pure_ruby.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pure_ruby.rb deleted file mode 100644 index 94fd175..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/pure_ruby.rb +++ /dev/null @@ -1,1284 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 8 Apr 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#------------------------------------------------------------------- -# -# - -# TODO List: -# TCP-connects currently assume non-blocking connect is available- need to -# degrade automatically on versions of Ruby prior to June 2006. -# - -require 'singleton' -require 'forwardable' -require 'socket' -require 'fcntl' -require 'set' -require 'openssl' - -module EventMachine - # @private - class Error < Exception; end - # @private - class UnknownTimerFired < RuntimeError; end - # @private - class Unsupported < RuntimeError; end - # @private - class ConnectionError < RuntimeError; end - # @private - class ConnectionNotBound < RuntimeError; end - - # Older versions of Ruby may not provide the SSLErrorWaitReadable - # OpenSSL class. Create an error class to act as a "proxy". - if defined?(OpenSSL::SSL::SSLErrorWaitReadable) - SSLConnectionWaitReadable = OpenSSL::SSL::SSLErrorWaitReadable - else - SSLConnectionWaitReadable = IO::WaitReadable - end - - # Older versions of Ruby may not provide the SSLErrorWaitWritable - # OpenSSL class. Create an error class to act as a "proxy". - if defined?(OpenSSL::SSL::SSLErrorWaitWritable) - SSLConnectionWaitWritable = OpenSSL::SSL::SSLErrorWaitWritable - else - SSLConnectionWaitWritable = IO::WaitWritable - end -end - -module EventMachine - class CertificateCreator - attr_reader :cert, :key - - def initialize - @key = OpenSSL::PKey::RSA.new(1024) - public_key = @key.public_key - subject = "/C=EventMachine/O=EventMachine/OU=EventMachine/CN=EventMachine" - @cert = OpenSSL::X509::Certificate.new - @cert.subject = @cert.issuer = OpenSSL::X509::Name.parse(subject) - @cert.not_before = Time.now - @cert.not_after = Time.now + 365 * 24 * 60 * 60 - @cert.public_key = public_key - @cert.serial = 0x0 - @cert.version = 2 - factory = OpenSSL::X509::ExtensionFactory.new - factory.subject_certificate = @cert - factory.issuer_certificate = @cert - @cert.extensions = [ - factory.create_extension("basicConstraints","CA:TRUE", true), - factory.create_extension("subjectKeyIdentifier", "hash") - ] - @cert.add_extension factory.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") - @cert.sign(@key, OpenSSL::Digest::SHA1.new) - end - end - - # @private - DefaultCertificate = CertificateCreator.new - - # @private - DefaultDHKey1024 = OpenSSL::PKey::DH.new <<-_end_of_pem_ ------BEGIN DH PARAMETERS----- -MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ -AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR -T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC ------END DH PARAMETERS----- - _end_of_pem_ - - # @private - DefaultDHKey2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY -JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab -VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6 -YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 -1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD -7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg== ------END DH PARAMETERS----- - _end_of_pem_ -end - -# @private -module EventMachine - class << self - # This is mostly useful for automated tests. - # Return a distinctive symbol so the caller knows whether he's dealing - # with an extension or with a pure-Ruby library. - # @private - def library_type - :pure_ruby - end - - # @private - def initialize_event_machine - Reactor.instance.initialize_for_run - end - - # Changed 04Oct06: intervals from the caller are now in milliseconds, but our native-ruby - # processor still wants them in seconds. - # @private - def add_oneshot_timer interval - Reactor.instance.install_oneshot_timer(interval / 1000) - end - - # @private - def run_machine - Reactor.instance.run - end - - # @private - def release_machine - end - - - def stopping? - return Reactor.instance.stop_scheduled - end - - # @private - def stop - Reactor.instance.stop - end - - # @private - def connect_server host, port - bind_connect_server nil, nil, host, port - end - - # @private - def bind_connect_server bind_addr, bind_port, host, port - EvmaTCPClient.connect(bind_addr, bind_port, host, port).uuid - end - - # @private - def send_data target, data, datalength - selectable = Reactor.instance.get_selectable( target ) or raise "unknown send_data target" - selectable.send_data data - end - - # @private - def close_connection target, after_writing - selectable = Reactor.instance.get_selectable( target ) - selectable.schedule_close after_writing if selectable - end - - # @private - def start_tcp_server host, port - (s = EvmaTCPServer.start_server host, port) or raise "no acceptor" - s.uuid - end - - # @private - def stop_tcp_server sig - s = Reactor.instance.get_selectable(sig) - s.schedule_close - end - - # @private - def start_unix_server chain - (s = EvmaUNIXServer.start_server chain) or raise "no acceptor" - s.uuid - end - - # @private - def connect_unix_server chain - EvmaUNIXClient.connect(chain).uuid - end - - # @private - def signal_loopbreak - Reactor.instance.signal_loopbreak - end - - # @private - def get_peername sig - selectable = Reactor.instance.get_selectable( sig ) or raise "unknown get_peername target" - selectable.get_peername - end - - # @private - def get_sockname sig - selectable = Reactor.instance.get_selectable( sig ) or raise "unknown get_sockname target" - selectable.get_sockname - end - - # @private - def open_udp_socket host, port - EvmaUDPSocket.create(host, port).uuid - end - - # This is currently only for UDP! - # We need to make it work with unix-domain sockets as well. - # @private - def send_datagram target, data, datalength, host, port - selectable = Reactor.instance.get_selectable( target ) or raise "unknown send_data target" - selectable.send_datagram data, Socket::pack_sockaddr_in(port, host) - end - - - # Sets reactor quantum in milliseconds. The underlying Reactor function wants a (possibly - # fractional) number of seconds. - # @private - def set_timer_quantum interval - Reactor.instance.set_timer_quantum(( 1.0 * interval) / 1000.0) - end - - # This method is a harmless no-op in the pure-Ruby implementation. This is intended to ensure - # that user code behaves properly across different EM implementations. - # @private - def epoll - end - - # @private - def ssl? - true - end - - def tls_parm_set?(parm) - !(parm.nil? || parm.empty?) - end - - # This method takes a series of positional arguments for specifying such - # things as private keys and certificate chains. It's expected that the - # parameter list will grow as we add more supported features. ALL of these - # parameters are optional, and can be specified as empty or nil strings. - # @private - def set_tls_parms signature, priv_key, cert_chain, verify_peer, fail_if_no_peer_cert, sni_hostname, cipher_list, ecdh_curve, dhparam, protocols_bitmask - bitmask = protocols_bitmask - ssl_options = OpenSSL::SSL::OP_ALL - ssl_options |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2) && EM_PROTO_SSLv2 & bitmask == 0 - ssl_options |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3) && EM_PROTO_SSLv3 & bitmask == 0 - ssl_options |= OpenSSL::SSL::OP_NO_TLSv1 if defined?(OpenSSL::SSL::OP_NO_TLSv1) && EM_PROTO_TLSv1 & bitmask == 0 - ssl_options |= OpenSSL::SSL::OP_NO_TLSv1_1 if defined?(OpenSSL::SSL::OP_NO_TLSv1_1) && EM_PROTO_TLSv1_1 & bitmask == 0 - ssl_options |= OpenSSL::SSL::OP_NO_TLSv1_2 if defined?(OpenSSL::SSL::OP_NO_TLSv1_2) && EM_PROTO_TLSv1_2 & bitmask == 0 - @tls_parms ||= {} - @tls_parms[signature] = { - :verify_peer => verify_peer, - :fail_if_no_peer_cert => fail_if_no_peer_cert, - :ssl_options => ssl_options - } - @tls_parms[signature][:priv_key] = File.read(priv_key) if tls_parm_set?(priv_key) - @tls_parms[signature][:cert_chain] = File.read(cert_chain) if tls_parm_set?(cert_chain) - @tls_parms[signature][:sni_hostname] = sni_hostname if tls_parm_set?(sni_hostname) - @tls_parms[signature][:cipher_list] = cipher_list.gsub(/,\s*/, ':') if tls_parm_set?(cipher_list) - @tls_parms[signature][:dhparam] = File.read(dhparam) if tls_parm_set?(dhparam) - @tls_parms[signature][:ecdh_curve] = ecdh_curve if tls_parm_set?(ecdh_curve) - end - - def start_tls signature - selectable = Reactor.instance.get_selectable(signature) or raise "unknown io selectable for start_tls" - tls_parms = @tls_parms[signature] - ctx = OpenSSL::SSL::SSLContext.new - ctx.options = tls_parms[:ssl_options] - ctx.cert = DefaultCertificate.cert - ctx.key = DefaultCertificate.key - ctx.cert_store = OpenSSL::X509::Store.new - ctx.cert_store.set_default_paths - ctx.cert = OpenSSL::X509::Certificate.new(tls_parms[:cert_chain]) if tls_parms[:cert_chain] - ctx.key = OpenSSL::PKey::RSA.new(tls_parms[:priv_key]) if tls_parms[:priv_key] - verify_mode = OpenSSL::SSL::VERIFY_NONE - if tls_parms[:verify_peer] - verify_mode |= OpenSSL::SSL::VERIFY_PEER - end - if tls_parms[:fail_if_no_peer_cert] - verify_mode |= OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT - end - ctx.verify_mode = verify_mode - ctx.servername_cb = Proc.new do |_, server_name| - tls_parms[:server_name] = server_name - nil - end - ctx.ciphers = tls_parms[:cipher_list] if tls_parms[:cipher_list] - if selectable.is_server - ctx.tmp_dh_callback = Proc.new do |_, _, key_length| - if tls_parms[:dhparam] - OpenSSL::PKey::DH.new(tls_parms[:dhparam]) - else - case key_length - when 1024 then DefaultDHKey1024 - when 2048 then DefaultDHKey2048 - else - nil - end - end - end - if tls_parms[:ecdh_curve] && ctx.respond_to?(:tmp_ecdh_callback) - ctx.tmp_ecdh_callback = Proc.new do - OpenSSL::PKey::EC.new(tls_parms[:ecdh_curve]) - end - end - end - ssl_io = OpenSSL::SSL::SSLSocket.new(selectable, ctx) - ssl_io.sync_close = true - if tls_parms[:sni_hostname] - ssl_io.hostname = tls_parms[:sni_hostname] if ssl_io.respond_to?(:hostname=) - end - begin - selectable.is_server ? ssl_io.accept_nonblock : ssl_io.connect_nonblock - rescue; end - selectable.io = ssl_io - end - - def get_peer_cert signature - selectable = Reactor.instance.get_selectable(signature) or raise "unknown get_peer_cert target" - if selectable.io.respond_to?(:peer_cert) && selectable.io.peer_cert - selectable.io.peer_cert.to_pem - else - nil - end - end - - def get_cipher_name signature - selectable = Reactor.instance.get_selectable(signature) or raise "unknown get_cipher_name target" - selectable.io.respond_to?(:cipher) ? selectable.io.cipher[0] : nil - end - - def get_cipher_protocol signature - selectable = Reactor.instance.get_selectable(signature) or raise "unknown get_cipher_protocol target" - selectable.io.respond_to?(:cipher) ? selectable.io.cipher[1] : nil - end - - def get_cipher_bits signature - selectable = Reactor.instance.get_selectable(signature) or raise "unknown get_cipher_bits target" - selectable.io.respond_to?(:cipher) ? selectable.io.cipher[2] : nil - end - - def get_sni_hostname signature - @tls_parms ||= {} - if @tls_parms[signature] - @tls_parms[signature][:server_name] - else - nil - end - end - - # This method is a no-op in the pure-Ruby implementation. We simply return Ruby's built-in - # per-process file-descriptor limit. - # @private - def set_rlimit_nofile n - 1024 - end - - # This method is a harmless no-op in pure Ruby, which doesn't have a built-in limit - # on the number of available timers. - # @private - def set_max_timer_count n - end - - # @private - def get_sock_opt signature, level, optname - selectable = Reactor.instance.get_selectable( signature ) or raise "unknown get_sock_opt target" - selectable.getsockopt level, optname - end - - # @private - def set_sock_opt signature, level, optname, optval - selectable = Reactor.instance.get_selectable( signature ) or raise "unknown set_sock_opt target" - selectable.setsockopt level, optname, optval - end - - # @private - def send_file_data sig, filename - sz = File.size(filename) - raise "file too large" if sz > 32*1024 - data = - begin - File.read filename - rescue - "" - end - send_data sig, data, data.length - end - - # @private - def get_outbound_data_size sig - r = Reactor.instance.get_selectable( sig ) or raise "unknown get_outbound_data_size target" - r.get_outbound_data_size - end - - # @private - def read_keyboard - EvmaKeyboard.open.uuid - end - - # @private - def set_comm_inactivity_timeout sig, tm - r = Reactor.instance.get_selectable( sig ) or raise "unknown set_comm_inactivity_timeout target" - r.set_inactivity_timeout tm - end - - # @private - def set_pending_connect_timeout sig, tm - # Needs to be implemented. Currently a no-op stub to allow - # certain software to operate with the EM pure-ruby. - end - - # @private - def report_connection_error_status signature - get_sock_opt(signature, Socket::SOL_SOCKET, Socket::SO_ERROR).int - end - end -end - -module EventMachine - # @private - class Connection - # @private - def get_outbound_data_size - EventMachine::get_outbound_data_size @signature - end - end -end - -module EventMachine - - # Factored out so we can substitute other implementations - # here if desired, such as the one in ActiveRBAC. - # @private - module UuidGenerator - def self.generate - @ix ||= 0 - @ix += 1 - end - end -end - - -module EventMachine - # @private - TimerFired = 100 - # @private - ConnectionData = 101 - # @private - ConnectionUnbound = 102 - # @private - ConnectionAccepted = 103 - # @private - ConnectionCompleted = 104 - # @private - LoopbreakSignalled = 105 - # @private - ConnectionNotifyReadable = 106 - # @private - ConnectionNotifyWritable = 107 - # @private - SslHandshakeCompleted = 108 - # @private - SslVerify = 109 - # @private - EM_PROTO_SSLv2 = 2 - # @private - EM_PROTO_SSLv3 = 4 - # @private - EM_PROTO_TLSv1 = 8 - # @private - EM_PROTO_TLSv1_1 = 16 - # @private - EM_PROTO_TLSv1_2 = 32 -end - -module EventMachine - # @private - class Reactor - include Singleton - - HeartbeatInterval = 2 - - attr_reader :current_loop_time, :stop_scheduled - - def initialize - initialize_for_run - end - - def install_oneshot_timer interval - uuid = UuidGenerator::generate - #@timers << [Time.now + interval, uuid] - #@timers.sort! {|a,b| a.first <=> b.first} - @timers.add([Time.now + interval, uuid]) - uuid - end - - # Called before run, this is a good place to clear out arrays - # with cruft that may be left over from a previous run. - # @private - def initialize_for_run - @running = false - @stop_scheduled = false - @selectables ||= {}; @selectables.clear - @timers = SortedSet.new # [] - set_timer_quantum(0.1) - @current_loop_time = Time.now - @next_heartbeat = @current_loop_time + HeartbeatInterval - end - - def add_selectable io - @selectables[io.uuid] = io - end - - def get_selectable uuid - @selectables[uuid] - end - - def run - raise Error.new( "already running" ) if @running - @running = true - - begin - open_loopbreaker - - loop { - @current_loop_time = Time.now - - break if @stop_scheduled - run_timers - break if @stop_scheduled - crank_selectables - break if @stop_scheduled - run_heartbeats - } - ensure - close_loopbreaker - @selectables.each {|k, io| io.close} - @selectables.clear - - @running = false - end - - end - - def run_timers - @timers.each {|t| - if t.first <= @current_loop_time - @timers.delete t - EventMachine::event_callback "", TimerFired, t.last - else - break - end - } - #while @timers.length > 0 and @timers.first.first <= now - # t = @timers.shift - # EventMachine::event_callback "", TimerFired, t.last - #end - end - - def run_heartbeats - if @next_heartbeat <= @current_loop_time - @next_heartbeat = @current_loop_time + HeartbeatInterval - @selectables.each {|k,io| io.heartbeat} - end - end - - def crank_selectables - #$stderr.write 'R' - - readers = @selectables.values.select {|io| io.select_for_reading?} - writers = @selectables.values.select {|io| io.select_for_writing?} - - s = select( readers, writers, nil, @timer_quantum) - - s and s[1] and s[1].each {|w| w.eventable_write } - s and s[0] and s[0].each {|r| r.eventable_read } - - @selectables.delete_if {|k,io| - if io.close_scheduled? - io.close - begin - EventMachine::event_callback io.uuid, ConnectionUnbound, nil - rescue ConnectionNotBound; end - true - end - } - end - - # #stop - def stop - raise Error.new( "not running") unless @running - @stop_scheduled = true - end - - def open_loopbreaker - # Can't use an IO.pipe because they can't be set nonselectable in Windows. - # Pick a random localhost UDP port. - #@loopbreak_writer.close if @loopbreak_writer - #rd,@loopbreak_writer = IO.pipe - @loopbreak_reader = UDPSocket.new - @loopbreak_writer = UDPSocket.new - bound = false - 100.times { - @loopbreak_port = rand(10000) + 40000 - begin - @loopbreak_reader.bind "127.0.0.1", @loopbreak_port - bound = true - break - rescue - end - } - raise "Unable to bind Loopbreaker" unless bound - LoopbreakReader.new(@loopbreak_reader) - end - - def close_loopbreaker - @loopbreak_writer.close - @loopbreak_writer = nil - end - - def signal_loopbreak - begin - @loopbreak_writer.send('+',0,"127.0.0.1",@loopbreak_port) if @loopbreak_writer - rescue IOError; end - end - - def set_timer_quantum interval_in_seconds - @timer_quantum = interval_in_seconds - end - - end - -end - -# @private -class IO - extend Forwardable - def_delegator :@my_selectable, :close_scheduled? - def_delegator :@my_selectable, :select_for_reading? - def_delegator :@my_selectable, :select_for_writing? - def_delegator :@my_selectable, :eventable_read - def_delegator :@my_selectable, :eventable_write - def_delegator :@my_selectable, :uuid - def_delegator :@my_selectable, :is_server - def_delegator :@my_selectable, :is_server= - def_delegator :@my_selectable, :send_data - def_delegator :@my_selectable, :schedule_close - def_delegator :@my_selectable, :get_peername - def_delegator :@my_selectable, :get_sockname - def_delegator :@my_selectable, :send_datagram - def_delegator :@my_selectable, :get_outbound_data_size - def_delegator :@my_selectable, :set_inactivity_timeout - def_delegator :@my_selectable, :heartbeat - def_delegator :@my_selectable, :io - def_delegator :@my_selectable, :io= -end - -module EventMachine - # @private - class Selectable - - attr_accessor :io, :is_server - attr_reader :uuid - - def initialize io - @io = io - @uuid = UuidGenerator.generate - @is_server = false - @last_activity = Reactor.instance.current_loop_time - - if defined?(Fcntl::F_GETFL) - m = @io.fcntl(Fcntl::F_GETFL, 0) - @io.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK | m) - else - # Windows doesn't define F_GETFL. - # It's not very reliable about setting descriptors nonblocking either. - begin - s = Socket.for_fd(@io.fileno) - s.fcntl( Fcntl::F_SETFL, Fcntl::O_NONBLOCK ) - rescue Errno::EINVAL, Errno::EBADF - warn "Serious error: unable to set descriptor non-blocking" - end - end - # TODO, should set CLOEXEC on Unix? - - @close_scheduled = false - @close_requested = false - - se = self; @io.instance_eval { @my_selectable = se } - Reactor.instance.add_selectable @io - end - - def close_scheduled? - @close_scheduled - end - - def select_for_reading? - false - end - - def select_for_writing? - false - end - - def get_peername - nil - end - - def get_sockname - nil - end - - def set_inactivity_timeout tm - @inactivity_timeout = tm - end - - def heartbeat - end - - def schedule_close(after_writing=false) - if after_writing - @close_requested = true - else - @close_scheduled = true - end - end - end - -end - -module EventMachine - # @private - class StreamObject < Selectable - def initialize io - super io - @outbound_q = [] - end - - # If we have to close, or a close-after-writing has been requested, - # then don't read any more data. - def select_for_reading? - true unless (@close_scheduled || @close_requested) - end - - # If we have to close, don't select for writing. - # Otherwise, see if the protocol is ready to close. - # If not, see if he has data to send. - # If a close-after-writing has been requested and the outbound queue - # is empty, convert the status to close_scheduled. - def select_for_writing? - unless @close_scheduled - if @outbound_q.empty? - @close_scheduled = true if @close_requested - false - else - true - end - end - end - - # Proper nonblocking I/O was added to Ruby 1.8.4 in May 2006. - # If we have it, then we can read multiple times safely to improve - # performance. - # The last-activity clock ASSUMES that we only come here when we - # have selected readable. - # TODO, coalesce multiple reads into a single event. - # TODO, do the function check somewhere else and cache it. - def eventable_read - @last_activity = Reactor.instance.current_loop_time - begin - if io.respond_to?(:read_nonblock) - 10.times { - data = io.read_nonblock(4096) - EventMachine::event_callback uuid, ConnectionData, data - } - else - data = io.sysread(4096) - EventMachine::event_callback uuid, ConnectionData, data - end - rescue Errno::EAGAIN, Errno::EWOULDBLOCK, SSLConnectionWaitReadable - # no-op - rescue Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError, Errno::EPIPE, OpenSSL::SSL::SSLError - @close_scheduled = true - EventMachine::event_callback uuid, ConnectionUnbound, nil - end - - end - - # Provisional implementation. Will be re-implemented in subclasses. - # TODO: Complete this implementation. As it stands, this only writes - # a single packet per cycle. Highly inefficient, but required unless - # we're running on a Ruby with proper nonblocking I/O (Ruby 1.8.4 - # built from sources from May 25, 2006 or newer). - # We need to improve the loop so it writes multiple times, however - # not more than a certain number of bytes per cycle, otherwise - # one busy connection could hog output buffers and slow down other - # connections. Also we should coalesce small writes. - # URGENT TODO: Coalesce small writes. They are a performance killer. - # The last-activity recorder ASSUMES we'll only come here if we've - # selected writable. - def eventable_write - # coalesce the outbound array here, perhaps - @last_activity = Reactor.instance.current_loop_time - while data = @outbound_q.shift do - begin - data = data.to_s - w = if io.respond_to?(:write_nonblock) - io.write_nonblock data - else - io.syswrite data - end - - if w < data.length - @outbound_q.unshift data[w..-1] - break - end - rescue Errno::EAGAIN, SSLConnectionWaitReadable, SSLConnectionWaitWritable - @outbound_q.unshift data - break - rescue EOFError, Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EPIPE, OpenSSL::SSL::SSLError - @close_scheduled = true - @outbound_q.clear - end - end - - end - - # #send_data - def send_data data - # TODO, coalesce here perhaps by being smarter about appending to @outbound_q.last? - unless @close_scheduled or @close_requested or !data or data.length <= 0 - @outbound_q << data.to_s - end - end - - # #get_peername - # This is defined in the normal way on connected stream objects. - # Return an object that is suitable for passing to Socket#unpack_sockaddr_in or variants. - # We could also use a convenience method that did the unpacking automatically. - def get_peername - io.getpeername - end - - # #get_sockname - # This is defined in the normal way on connected stream objects. - # Return an object that is suitable for passing to Socket#unpack_sockaddr_in or variants. - # We could also use a convenience method that did the unpacking automatically. - def get_sockname - io.getsockname - end - - # #get_outbound_data_size - def get_outbound_data_size - @outbound_q.inject(0) {|memo,obj| memo += (obj || "").length} - end - - def heartbeat - if @inactivity_timeout and @inactivity_timeout > 0 and (@last_activity + @inactivity_timeout) < Reactor.instance.current_loop_time - schedule_close true - end - end - end - - -end - - -#-------------------------------------------------------------- - - - -module EventMachine - # @private - class EvmaTCPClient < StreamObject - - def self.connect bind_addr, bind_port, host, port - sd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 ) - sd.bind( Socket.pack_sockaddr_in( bind_port, bind_addr )) if bind_addr - - begin - # TODO, this assumes a current Ruby snapshot. - # We need to degrade to a nonblocking connect otherwise. - sd.connect_nonblock( Socket.pack_sockaddr_in( port, host )) - rescue Errno::ECONNREFUSED, Errno::EINPROGRESS - end - EvmaTCPClient.new sd - end - - def initialize io - super - @pending = true - @handshake_complete = false - end - - def ready? - if RUBY_PLATFORM =~ /linux/ - io.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO).unpack("i").first == 1 # TCP_ESTABLISHED - else - io.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR).unpack("i").first == 0 # NO ERROR - end - end - - def handshake_complete? - if !@handshake_complete && io.respond_to?(:state) - if io.state =~ /^SSLOK/ - @handshake_complete = true - EventMachine::event_callback uuid, SslHandshakeCompleted, "" - EventMachine::event_callback uuid, SslVerify, io.peer_cert.to_pem if io.peer_cert - end - else - @handshake_complete = true - end - @handshake_complete - end - - def pending? - handshake_complete? - if @pending - if ready? - @pending = false - EventMachine::event_callback uuid, ConnectionCompleted, "" - end - end - @pending - end - - def select_for_writing? - pending? - super - end - - def select_for_reading? - pending? - super - end - end -end - - - -module EventMachine - # @private - class EvmaKeyboard < StreamObject - - def self.open - EvmaKeyboard.new STDIN - end - - - def initialize io - super - end - - - def select_for_writing? - false - end - - def select_for_reading? - true - end - - - end -end - - - -module EventMachine - # @private - class EvmaUNIXClient < StreamObject - - def self.connect chain - sd = Socket.new( Socket::AF_LOCAL, Socket::SOCK_STREAM, 0 ) - begin - # TODO, this assumes a current Ruby snapshot. - # We need to degrade to a nonblocking connect otherwise. - sd.connect_nonblock( Socket.pack_sockaddr_un( chain )) - rescue Errno::EINPROGRESS - end - EvmaUNIXClient.new sd - end - - - def initialize io - super - @pending = true - end - - - def select_for_writing? - @pending ? true : super - end - - def select_for_reading? - @pending ? false : super - end - - def eventable_write - if @pending - @pending = false - if 0 == io.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR).unpack("i").first - EventMachine::event_callback uuid, ConnectionCompleted, "" - end - else - super - end - end - - - - end -end - - -#-------------------------------------------------------------- - -module EventMachine - # @private - class EvmaTCPServer < Selectable - - # TODO, refactor and unify with EvmaUNIXServer. - - class << self - # Versions of ruby 1.8.4 later than May 26 2006 will work properly - # with an object of type TCPServer. Prior versions won't so we - # play it safe and just build a socket. - # - def start_server host, port - sd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 ) - sd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true ) - sd.bind( Socket.pack_sockaddr_in( port, host )) - sd.listen( 50 ) # 5 is what you see in all the books. Ain't enough. - EvmaTCPServer.new sd - end - end - - def initialize io - super io - end - - - def select_for_reading? - true - end - - #-- - # accept_nonblock returns an array consisting of the accepted - # socket and a sockaddr_in which names the peer. - # Don't accept more than 10 at a time. - def eventable_read - begin - 10.times { - descriptor,peername = io.accept_nonblock - sd = EvmaTCPClient.new descriptor - sd.is_server = true - EventMachine::event_callback uuid, ConnectionAccepted, sd.uuid - } - rescue Errno::EWOULDBLOCK, Errno::EAGAIN - end - end - - #-- - # - def schedule_close - @close_scheduled = true - end - - end -end - - -#-------------------------------------------------------------- - -module EventMachine - # @private - class EvmaUNIXServer < Selectable - - # TODO, refactor and unify with EvmaTCPServer. - - class << self - # Versions of ruby 1.8.4 later than May 26 2006 will work properly - # with an object of type TCPServer. Prior versions won't so we - # play it safe and just build a socket. - # - def start_server chain - sd = Socket.new( Socket::AF_LOCAL, Socket::SOCK_STREAM, 0 ) - sd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true ) - sd.bind( Socket.pack_sockaddr_un( chain )) - sd.listen( 50 ) # 5 is what you see in all the books. Ain't enough. - EvmaUNIXServer.new sd - end - end - - def initialize io - super io - end - - - def select_for_reading? - true - end - - #-- - # accept_nonblock returns an array consisting of the accepted - # socket and a sockaddr_in which names the peer. - # Don't accept more than 10 at a time. - def eventable_read - begin - 10.times { - descriptor,peername = io.accept_nonblock - sd = StreamObject.new descriptor - EventMachine::event_callback uuid, ConnectionAccepted, sd.uuid - } - rescue Errno::EWOULDBLOCK, Errno::EAGAIN - end - end - - #-- - # - def schedule_close - @close_scheduled = true - end - - end -end - - - -#-------------------------------------------------------------- - -module EventMachine - # @private - class LoopbreakReader < Selectable - - def select_for_reading? - true - end - - def eventable_read - io.sysread(128) - EventMachine::event_callback "", LoopbreakSignalled, "" - end - - end -end - - - -# @private -module EventMachine - # @private - class DatagramObject < Selectable - def initialize io - super io - @outbound_q = [] - end - - # #send_datagram - def send_datagram data, target - # TODO, coalesce here perhaps by being smarter about appending to @outbound_q.last? - unless @close_scheduled or @close_requested - @outbound_q << [data.to_s, target] - end - end - - # #select_for_writing? - def select_for_writing? - unless @close_scheduled - if @outbound_q.empty? - @close_scheduled = true if @close_requested - false - else - true - end - end - end - - # #select_for_reading? - def select_for_reading? - true - end - - # #get_outbound_data_size - def get_outbound_data_size - @outbound_q.inject(0) {|memo,obj| memo += (obj || "").length} - end - - - end - - -end - - -module EventMachine - # @private - class EvmaUDPSocket < DatagramObject - - class << self - def create host, port - sd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 ) - sd.bind Socket::pack_sockaddr_in( port, host ) - EvmaUDPSocket.new sd - end - end - - # #eventable_write - # This really belongs in DatagramObject, but there is some UDP-specific stuff. - def eventable_write - 40.times { - break if @outbound_q.empty? - begin - data,target = @outbound_q.first - - # This damn better be nonblocking. - io.send data.to_s, 0, target - - @outbound_q.shift - rescue Errno::EAGAIN - # It's not been observed in testing that we ever get here. - # True to the definition, packets will be accepted and quietly dropped - # if the system is under pressure. - break - rescue EOFError, Errno::ECONNRESET - @close_scheduled = true - @outbound_q.clear - end - } - end - - # Proper nonblocking I/O was added to Ruby 1.8.4 in May 2006. - # If we have it, then we can read multiple times safely to improve - # performance. - def eventable_read - begin - if io.respond_to?(:recvfrom_nonblock) - 40.times { - data,@return_address = io.recvfrom_nonblock(16384) - EventMachine::event_callback uuid, ConnectionData, data - @return_address = nil - } - else - raise "unimplemented datagram-read operation on this Ruby" - end - rescue Errno::EAGAIN - # no-op - rescue Errno::ECONNRESET, EOFError - @close_scheduled = true - EventMachine::event_callback uuid, ConnectionUnbound, nil - end - end - - def send_data data - send_datagram data, @return_address - end - end -end - -# load base EM api on top, now that we have the underlying pure ruby -# implementation defined -require 'eventmachine' diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/queue.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/queue.rb deleted file mode 100644 index 9096ed0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/queue.rb +++ /dev/null @@ -1,80 +0,0 @@ -module EventMachine - # A cross thread, reactor scheduled, linear queue. - # - # This class provides a simple queue abstraction on top of the reactor - # scheduler. It services two primary purposes: - # - # * API sugar for stateful protocols - # * Pushing processing onto the reactor thread - # - # @example - # - # q = EM::Queue.new - # q.push('one', 'two', 'three') - # 3.times do - # q.pop { |msg| puts(msg) } - # end - # - class Queue - def initialize - @sink = [] - @drain = [] - @popq = [] - end - - # Pop items off the queue, running the block on the reactor thread. The pop - # will not happen immediately, but at some point in the future, either in - # the next tick, if the queue has data, or when the queue is populated. - # - # @return [NilClass] nil - def pop(*a, &b) - cb = EM::Callback(*a, &b) - EM.schedule do - if @drain.empty? - @drain = @sink - @sink = [] - end - if @drain.empty? - @popq << cb - else - cb.call @drain.shift - end - end - nil # Always returns nil - end - - # Push items onto the queue in the reactor thread. The items will not appear - # in the queue immediately, but will be scheduled for addition during the - # next reactor tick. - def push(*items) - EM.schedule do - @sink.push(*items) - unless @popq.empty? - @drain = @sink - @sink = [] - @popq.shift.call @drain.shift until @drain.empty? || @popq.empty? - end - end - end - alias :<< :push - - # @return [Boolean] - # @note This is a peek, it's not thread safe, and may only tend toward accuracy. - def empty? - @drain.empty? && @sink.empty? - end - - # @return [Integer] Queue size - # @note This is a peek, it's not thread safe, and may only tend toward accuracy. - def size - @drain.size + @sink.size - end - - # @return [Integer] Waiting size - # @note This is a peek at the number of jobs that are currently waiting on the Queue - def num_waiting - @popq.size - end - - end # Queue -end # EventMachine diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/resolver.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/resolver.rb deleted file mode 100644 index 1d2d7aa..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/resolver.rb +++ /dev/null @@ -1,232 +0,0 @@ -module EventMachine - module DNS - class Resolver - - def self.windows? - if RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/ - require 'win32/resolv' - true - else - false - end - end - - HOSTS_FILE = windows? ? Win32::Resolv.get_hosts_path : '/etc/hosts' - - @hosts = nil - @nameservers = nil - @socket = nil - - def self.resolve(hostname) - Request.new(socket, hostname) - end - - def self.socket - if @socket && @socket.error? - @socket = Socket.open - else - @socket ||= Socket.open - end - end - - def self.nameservers=(ns) - @nameservers = ns - end - - def self.nameservers - return @nameservers if @nameservers - - if windows? - _, ns = Win32::Resolv.get_resolv_info - return @nameservers = ns || [] - end - - @nameservers = [] - IO.readlines('/etc/resolv.conf').each do |line| - if line =~ /^nameserver (.+)$/ - @nameservers << $1.split(/\s+/).first - end - end - - @nameservers - rescue - @nameservers = [] - end - - def self.nameserver - nameservers.shuffle.first - end - - def self.hosts - return @hosts if @hosts - - @hosts = {} - IO.readlines(HOSTS_FILE).each do |line| - next if line =~ /^#/ - addr, host = line.split(/\s+/) - - next unless addr && host - @hosts[host] ||= [] - @hosts[host] << addr - end - - @hosts - rescue - @hosts = {} - end - end - - class RequestIdAlreadyUsed < RuntimeError; end - - class Socket < EventMachine::Connection - def self.open - EventMachine::open_datagram_socket('0.0.0.0', 0, self) - end - - def initialize - @nameserver = nil - end - - def post_init - @requests = {} - end - - def start_timer - @timer ||= EM.add_periodic_timer(0.1, &method(:tick)) - end - - def stop_timer - EM.cancel_timer(@timer) - @timer = nil - end - - def unbind - end - - def tick - @requests.each do |id,req| - req.tick - end - end - - def register_request(id, req) - if @requests.has_key?(id) - raise RequestIdAlreadyUsed - else - @requests[id] = req - end - - start_timer - end - - def deregister_request(id, req) - @requests.delete(id) - stop_timer if @requests.length == 0 - end - - def send_packet(pkt) - send_datagram(pkt, nameserver, 53) - end - - def nameserver=(ns) - @nameserver = ns - end - - def nameserver - @nameserver || Resolver.nameserver - end - - # Decodes the packet, looks for the request and passes the - # response over to the requester - def receive_data(data) - msg = nil - begin - msg = Resolv::DNS::Message.decode data - rescue - else - req = @requests[msg.id] - if req - @requests.delete(msg.id) - stop_timer if @requests.length == 0 - req.receive_answer(msg) - end - end - end - end - - class Request - include Deferrable - attr_accessor :retry_interval, :max_tries - - def initialize(socket, hostname) - @socket = socket - @hostname = hostname - @tries = 0 - @last_send = Time.at(0) - @retry_interval = 3 - @max_tries = 5 - - if addrs = Resolver.hosts[hostname] - succeed addrs - else - EM.next_tick { tick } - end - end - - def tick - # Break early if nothing to do - return if @last_send + @retry_interval > Time.now - if @tries < @max_tries - send - else - @socket.deregister_request(@id, self) - fail 'retries exceeded' - end - end - - def receive_answer(msg) - addrs = [] - msg.each_answer do |name,ttl,data| - if data.kind_of?(Resolv::DNS::Resource::IN::A) || - data.kind_of?(Resolv::DNS::Resource::IN::AAAA) - addrs << data.address.to_s - end - end - - if addrs.empty? - fail "rcode=#{msg.rcode}" - else - succeed addrs - end - end - - private - - def send - @tries += 1 - @last_send = Time.now - @socket.send_packet(packet.encode) - end - - def id - begin - @id = rand(65535) - @socket.register_request(@id, self) - rescue RequestIdAlreadyUsed - retry - end unless defined?(@id) - - @id - end - - def packet - msg = Resolv::DNS::Message.new - msg.id = id - msg.rd = 1 - msg.add_question @hostname, Resolv::DNS::Resource::IN::A - msg - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/spawnable.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/spawnable.rb deleted file mode 100644 index 35c087d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/spawnable.rb +++ /dev/null @@ -1,84 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 25 Aug 2007 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -module EventMachine - # Support for Erlang-style processes. - # - class SpawnedProcess - # Send a message to the spawned process - def notify *x - me = self - EM.next_tick { - # A notification executes in the context of this - # SpawnedProcess object. That makes self and notify - # work as one would expect. - # - y = me.call(*x) - if y and y.respond_to?(:pull_out_yield_block) - a,b = y.pull_out_yield_block - set_receiver a - self.notify if b - end - } - end - alias_method :resume, :notify - alias_method :run, :notify # for formulations like (EM.spawn {xxx}).run - - def set_receiver blk - (class << self ; self ; end).class_eval do - remove_method :call if method_defined? :call - define_method :call, blk - end - end - - end - - # @private - class YieldBlockFromSpawnedProcess - def initialize block, notify - @block = [block,notify] - end - def pull_out_yield_block - @block - end - end - - # Spawn an erlang-style process - def self.spawn &block - s = SpawnedProcess.new - s.set_receiver block - s - end - - # @private - def self.yield &block - return YieldBlockFromSpawnedProcess.new( block, false ) - end - - # @private - def self.yield_and_notify &block - return YieldBlockFromSpawnedProcess.new( block, true ) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/streamer.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/streamer.rb deleted file mode 100644 index cf49c88..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/streamer.rb +++ /dev/null @@ -1,118 +0,0 @@ -module EventMachine - # Streams a file over a given connection. Streaming begins once the object is - # instantiated. Typically FileStreamer instances are not reused. - # - # Streaming uses buffering for files larger than 16K and uses so-called fast file reader (a C++ extension) - # if available (it is part of eventmachine gem itself). - # - # @example - # - # module FileSender - # def post_init - # streamer = EventMachine::FileStreamer.new(self, '/tmp/bigfile.tar') - # streamer.callback{ - # # file was sent successfully - # close_connection_after_writing - # } - # end - # end - # - # - # @author Francis Cianfrocca - class FileStreamer - include Deferrable - - # Use mapped streamer for files bigger than 16k - MappingThreshold = 16384 - # Wait until next tick to send more data when 50k is still in the outgoing buffer - BackpressureLevel = 50000 - # Send 16k chunks at a time - ChunkSize = 16384 - - # @param [EventMachine::Connection] connection - # @param [String] filename File path - # - # @option args [Boolean] :http_chunks (false) Use HTTP 1.1 style chunked-encoding semantics. - def initialize connection, filename, args = {} - @connection = connection - @http_chunks = args[:http_chunks] - - if File.exist?(filename) - @size = File.size(filename) - if @size <= MappingThreshold - stream_without_mapping filename - else - stream_with_mapping filename - end - else - fail "file not found" - end - end - - # @private - def stream_without_mapping filename - if @http_chunks - @connection.send_data "#{@size.to_s(16)}\r\n" - @connection.send_file_data filename - @connection.send_data "\r\n0\r\n\r\n" - else - @connection.send_file_data filename - end - succeed - end - private :stream_without_mapping - - # @private - def stream_with_mapping filename - ensure_mapping_extension_is_present - - @position = 0 - @mapping = EventMachine::FastFileReader::Mapper.new filename - stream_one_chunk - end - private :stream_with_mapping - - # Used internally to stream one chunk at a time over multiple reactor ticks - # @private - def stream_one_chunk - loop { - if @position < @size - if @connection.get_outbound_data_size > BackpressureLevel - EventMachine::next_tick {stream_one_chunk} - break - else - len = @size - @position - len = ChunkSize if (len > ChunkSize) - - @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks - @connection.send_data( @mapping.get_chunk( @position, len )) - @connection.send_data("\r\n") if @http_chunks - - @position += len - end - else - @connection.send_data "0\r\n\r\n" if @http_chunks - @mapping.close - succeed - break - end - } - end - - # - # We use an outboard extension class to get memory-mapped files. - # It's outboard to avoid polluting the core distro, but that means - # there's a "hidden" dependency on it. The first time we get here in - # any run, try to load up the dependency extension. User code will see - # a LoadError if it's not available, but code that doesn't require - # mapped files will work fine without it. This is a somewhat difficult - # compromise between usability and proper modularization. - # - # @private - def ensure_mapping_extension_is_present - @@fastfilereader ||= (require 'fastfilereaderext') - end - private :ensure_mapping_extension_is_present - - end # FileStreamer -end # EventMachine diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/threaded_resource.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/threaded_resource.rb deleted file mode 100644 index 87704d5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/threaded_resource.rb +++ /dev/null @@ -1,90 +0,0 @@ -module EventMachine - # = EventMachine::ThreadedResource - # - # A threaded resource is a "quick and dirty" wrapper around the concept of - # wiring up synchronous code into a standard EM::Pool. This is useful to keep - # interfaces coherent and provide a simple approach at "making an interface - # async-ish". - # - # General usage is to wrap libraries that do not support EventMachine, or to - # have a specific number of dedicated high-cpu worker resources. - # - # == Basic Usage example - # - # This example requires the cassandra gem. The cassandra gem contains an - # EventMachine interface, but it's sadly Fiber based and thus only works on - # 1.9. It also requires (potentially) complex stack switching logic to reach - # completion of nested operations. By contrast this approach provides a block - # in which normal synchronous code can occur, but makes no attempt to wire the - # IO into EventMachines C++ IO implementations, instead relying on the reactor - # pattern in rb_thread_select. - # - # cassandra_dispatcher = ThreadedResource.new do - # Cassandra.new('allthethings', '127.0.0.1:9160') - # end - # - # pool = EM::Pool.new - # - # pool.add cassandra_dispatcher - # - # # If we don't care about the result: - # pool.perform do |dispatcher| - # # The following block executes inside a dedicated thread, and should not - # # access EventMachine things: - # dispatcher.dispatch do |cassandra| - # cassandra.insert(:Things, '10', 'stuff' => 'things') - # end - # end - # - # # Example where we care about the result: - # pool.perform do |dispatcher| - # # The dispatch block is executed in the resources thread. - # completion = dispatcher.dispatch do |cassandra| - # cassandra.get(:Things, '10', 'stuff') - # end - # - # # This block will be yielded on the EM thread: - # completion.callback do |result| - # EM.do_something_with(result) - # end - # - # completion - # end - class ThreadedResource - - # The block should return the resource that will be yielded in a dispatch. - def initialize - @resource = yield - - @running = true - @queue = ::Queue.new - @thread = Thread.new do - @queue.pop.call while @running - end - end - - # Called on the EM thread, generally in a perform block to return a - # completion for the work. - def dispatch - completion = EM::Completion.new - @queue << lambda do - begin - result = yield @resource - completion.succeed result - rescue => e - completion.fail e - end - end - completion - end - - # Kill the internal thread. should only be used to cleanup - generally - # only required for tests. - def shutdown - @running = false - @queue << lambda {} - @thread.join - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/tick_loop.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/tick_loop.rb deleted file mode 100644 index a95d516..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/tick_loop.rb +++ /dev/null @@ -1,85 +0,0 @@ -module EventMachine - # Creates and immediately starts an EventMachine::TickLoop - def self.tick_loop(*a, &b) - TickLoop.new(*a, &b).start - end - - # A TickLoop is useful when one needs to distribute amounts of work - # throughout ticks in order to maintain response times. It is also useful for - # simple repeated checks and metrics. - # @example - # # Here we run through an array one item per tick until it is empty, - # # printing each element. - # # When the array is empty, we return :stop from the callback, and the - # # loop will terminate. - # # When the loop terminates, the on_stop callbacks will be called. - # EM.run do - # array = (1..100).to_a - # - # tickloop = EM.tick_loop do - # if array.empty? - # :stop - # else - # puts array.shift - # end - # end - # - # tickloop.on_stop { EM.stop } - # end - # - class TickLoop - - # Arguments: A callback (EM::Callback) to call each tick. If the call - # returns +:stop+ then the loop will be stopped. Any other value is - # ignored. - def initialize(*a, &b) - @work = EM::Callback(*a, &b) - @stops = [] - @stopped = true - end - - # Arguments: A callback (EM::Callback) to call once on the next stop (or - # immediately if already stopped). - def on_stop(*a, &b) - if @stopped - EM::Callback(*a, &b).call - else - @stops << EM::Callback(*a, &b) - end - end - - # Stop the tick loop immediately, and call it's on_stop callbacks. - def stop - @stopped = true - until @stops.empty? - @stops.shift.call - end - end - - # Query if the loop is stopped. - def stopped? - @stopped - end - - # Start the tick loop, will raise argument error if the loop is already - # running. - def start - raise ArgumentError, "double start" unless @stopped - @stopped = false - schedule - end - - private - def schedule - EM.next_tick do - next if @stopped - if @work.call == :stop - stop - else - schedule - end - end - self - end - end -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/timers.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/timers.rb deleted file mode 100644 index 41cd959..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/timers.rb +++ /dev/null @@ -1,61 +0,0 @@ -module EventMachine - # Creates a one-time timer - # - # timer = EventMachine::Timer.new(5) do - # # this will never fire because we cancel it - # end - # timer.cancel - # - class Timer - # Create a new timer that fires after a given number of seconds - def initialize interval, callback=nil, &block - @signature = EventMachine::add_timer(interval, callback || block) - end - - # Cancel the timer - def cancel - EventMachine.send :cancel_timer, @signature - end - end - - # Creates a periodic timer - # - # @example - # n = 0 - # timer = EventMachine::PeriodicTimer.new(5) do - # puts "the time is #{Time.now}" - # timer.cancel if (n+=1) > 5 - # end - # - class PeriodicTimer - # Create a new periodic timer that executes every interval seconds - def initialize interval, callback=nil, &block - @interval = interval - @code = callback || block - @cancelled = false - @work = method(:fire) - schedule - end - - # Cancel the periodic timer - def cancel - @cancelled = true - end - - # Fire the timer every interval seconds - attr_accessor :interval - - # @private - def schedule - EventMachine::add_timer @interval, @work - end - - # @private - def fire - unless @cancelled - @code.call - schedule - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/version.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/version.rb deleted file mode 100644 index ffc4310..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/em/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module EventMachine - VERSION = "1.2.7" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb deleted file mode 100644 index 0873747..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/eventmachine.rb +++ /dev/null @@ -1,1601 +0,0 @@ -if defined?(EventMachine.library_type) and EventMachine.library_type == :pure_ruby - # assume 'em/pure_ruby' was loaded already -elsif RUBY_PLATFORM =~ /java/ - require 'java' - require 'jeventmachine' -else - begin - require 'rubyeventmachine' - rescue LoadError - warn "Unable to load the EventMachine C extension; To use the pure-ruby reactor, require 'em/pure_ruby'" - raise - end -end - -require 'em/version' -require 'em/pool' -require 'em/deferrable' -require 'em/future' -require 'em/streamer' -require 'em/spawnable' -require 'em/processes' -require 'em/iterator' -require 'em/buftok' -require 'em/timers' -require 'em/protocols' -require 'em/connection' -require 'em/callback' -require 'em/queue' -require 'em/channel' -require 'em/file_watch' -require 'em/process_watch' -require 'em/tick_loop' -require 'em/resolver' -require 'em/completion' -require 'em/threaded_resource' - -require 'shellwords' -require 'thread' -require 'resolv' - -# Top-level EventMachine namespace. If you are looking for EventMachine examples, see {file:docs/GettingStarted.md EventMachine tutorial}. -# -# ## Key methods ## -# ### Starting and stopping the event loop ### -# -# * {EventMachine.run} -# * {EventMachine.stop_event_loop} -# -# ### Implementing clients ### -# -# * {EventMachine.connect} -# -# ### Implementing servers ### -# -# * {EventMachine.start_server} -# -# ### Working with timers ### -# -# * {EventMachine.add_timer} -# * {EventMachine.add_periodic_timer} -# * {EventMachine.cancel_timer} -# -# ### Working with blocking tasks ### -# -# * {EventMachine.defer} -# * {EventMachine.next_tick} -# -# ### Efficient proxying ### -# -# * {EventMachine.enable_proxy} -# * {EventMachine.disable_proxy} -module EventMachine - class << self - # Exposed to allow joining on the thread, when run in a multithreaded - # environment. Performing other actions on the thread has undefined - # semantics (read: a dangerous endevor). - # - # @return [Thread] - attr_reader :reactor_thread - end - @next_tick_mutex = Mutex.new - @reactor_running = false - @next_tick_queue = [] - @tails = [] - @threadpool = @threadqueue = @resultqueue = nil - @all_threads_spawned = false - - # System errnos - # @private - ERRNOS = Errno::constants.grep(/^E/).inject(Hash.new(:unknown)) { |hash, name| - errno = Errno.__send__(:const_get, name) - hash[errno::Errno] = errno - hash - } - - # Initializes and runs an event loop. This method only returns if code inside the block passed to this method - # calls {EventMachine.stop_event_loop}. The block is executed after initializing its internal event loop but *before* running the loop, - # therefore this block is the right place to call any code that needs event loop to run, for example, {EventMachine.start_server}, - # {EventMachine.connect} or similar methods of libraries that use EventMachine under the hood - # (like `EventMachine::HttpRequest.new` or `AMQP.start`). - # - # Programs that are run for long periods of time (e.g. servers) usually start event loop by calling {EventMachine.run}, and let it - # run "forever". It's also possible to use {EventMachine.run} to make a single client-connection to a remote server, - # process the data flow from that single connection, and then call {EventMachine.stop_event_loop} to stop, in other words, - # to run event loop for a short period of time (necessary to complete some operation) and then shut it down. - # - # Once event loop is running, it is perfectly possible to start multiple servers and clients simultaneously: content-aware - # proxies like [Proxymachine](https://github.com/mojombo/proxymachine) do just that. - # - # ## Using EventMachine with Ruby on Rails and other Web application frameworks ## - # - # Standalone applications often run event loop on the main thread, thus blocking for their entire lifespan. In case of Web applications, - # if you are running an EventMachine-based app server such as [Thin](http://code.macournoyer.com/thin/) or [Goliath](https://github.com/postrank-labs/goliath/), - # they start event loop for you. Servers like Unicorn, Apache Passenger or Mongrel occupy main Ruby thread to serve HTTP(S) requests. This means - # that calling {EventMachine.run} on the same thread is not an option (it will result in Web server never binding to the socket). - # In that case, start event loop in a separate thread as demonstrated below. - # - # - # @example Starting EventMachine event loop in the current thread to run the "Hello, world"-like Echo server example - # - # #!/usr/bin/env ruby - # - # require 'rubygems' # or use Bundler.setup - # require 'eventmachine' - # - # class EchoServer < EM::Connection - # def receive_data(data) - # send_data(data) - # end - # end - # - # EventMachine.run do - # EventMachine.start_server("0.0.0.0", 10000, EchoServer) - # end - # - # - # @example Starting EventMachine event loop in a separate thread - # - # # doesn't block current thread, can be used with Ruby on Rails, Sinatra, Merb, Rack - # # and any other application server that occupies main Ruby thread. - # Thread.new { EventMachine.run } - # - # - # @note This method blocks calling thread. If you need to start EventMachine event loop from a Web app - # running on a non event-driven server (Unicorn, Apache Passenger, Mongrel), do it in a separate thread like demonstrated - # in one of the examples. - # @see file:docs/GettingStarted.md Getting started with EventMachine - # @see EventMachine.stop_event_loop - def self.run blk=nil, tail=nil, &block - # Obsoleted the use_threads mechanism. - # 25Nov06: Added the begin/ensure block. We need to be sure that release_machine - # gets called even if an exception gets thrown within any of the user code - # that the event loop runs. The best way to see this is to run a unit - # test with two functions, each of which calls {EventMachine.run} and each of - # which throws something inside of #run. Without the ensure, the second test - # will start without release_machine being called and will immediately throw - - # - if @reactor_running and @reactor_pid != Process.pid - # Reactor was started in a different parent, meaning we have forked. - # Clean up reactor state so a new reactor boots up in this child. - stop_event_loop - release_machine - cleanup_machine - @reactor_running = false - end - - tail and @tails.unshift(tail) - - if reactor_running? - (b = blk || block) and b.call # next_tick(b) - else - @conns = {} - @acceptors = {} - @timers = {} - @wrapped_exception = nil - @next_tick_queue ||= [] - @tails ||= [] - begin - initialize_event_machine - @reactor_pid = Process.pid - @reactor_thread = Thread.current - @reactor_running = true - - (b = blk || block) and add_timer(0, b) - if @next_tick_queue && !@next_tick_queue.empty? - add_timer(0) { signal_loopbreak } - end - - # Rubinius needs to come back into "Ruby space" for GC to work, - # so we'll crank the machine here. - if defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx" - while run_machine_once; end - else - run_machine - end - - ensure - until @tails.empty? - @tails.pop.call - end - - release_machine - cleanup_machine - @reactor_running = false - @reactor_thread = nil - end - - raise @wrapped_exception if @wrapped_exception - end - end - - # Sugars a common use case. Will pass the given block to #run, but will terminate - # the reactor loop and exit the function as soon as the code in the block completes. - # (Normally, {EventMachine.run} keeps running indefinitely, even after the block supplied to it - # finishes running, until user code calls {EventMachine.stop}) - # - def self.run_block &block - pr = proc { - block.call - EventMachine::stop - } - run(&pr) - end - - # @return [Boolean] true if the calling thread is the same thread as the reactor. - def self.reactor_thread? - Thread.current == @reactor_thread - end - - # Runs the given callback on the reactor thread, or immediately if called - # from the reactor thread. Accepts the same arguments as {EventMachine::Callback} - def self.schedule(*a, &b) - cb = Callback(*a, &b) - if reactor_running? && reactor_thread? - cb.call - else - next_tick { cb.call } - end - end - - # Forks a new process, properly stops the reactor and then calls {EventMachine.run} inside of it again, passing your block. - def self.fork_reactor &block - # This implementation is subject to change, especially if we clean up the relationship - # of EM#run to @reactor_running. - # Original patch by Aman Gupta. - # - Kernel.fork do - if reactor_running? - stop_event_loop - release_machine - cleanup_machine - @reactor_running = false - @reactor_thread = nil - end - run block - end - end - - # Clean up Ruby space following a release_machine - def self.cleanup_machine - if @threadpool && !@threadpool.empty? - # Tell the threads to stop - @threadpool.each { |t| t.exit } - # Join the threads or bump the stragglers one more time - @threadpool.each { |t| t.join 0.01 || t.exit } - end - @threadpool = nil - @threadqueue = nil - @resultqueue = nil - @all_threads_spawned = false - @next_tick_queue = [] - end - - # Adds a block to call as the reactor is shutting down. - # - # These callbacks are called in the _reverse_ order to which they are added. - # - # @example Scheduling operations to be run when EventMachine event loop is stopped - # - # EventMachine.run do - # EventMachine.add_shutdown_hook { puts "b" } - # EventMachine.add_shutdown_hook { puts "a" } - # EventMachine.stop - # end - # - # # Outputs: - # # a - # # b - # - def self.add_shutdown_hook &block - @tails << block - end - - # Adds a one-shot timer to the event loop. - # Call it with one or two parameters. The first parameters is a delay-time - # expressed in *seconds* (not milliseconds). The second parameter, if - # present, must be an object that responds to :call. If 2nd parameter is not given, then you - # can also simply pass a block to the method call. - # - # This method may be called from the block passed to {EventMachine.run} - # or from any callback method. It schedules execution of the proc or block - # passed to it, after the passage of an interval of time equal to - # *at least* the number of seconds specified in the first parameter to - # the call. - # - # {EventMachine.add_timer} is a non-blocking method. Callbacks can and will - # be called during the interval of time that the timer is in effect. - # There is no built-in limit to the number of timers that can be outstanding at - # any given time. - # - # @example Setting a one-shot timer with EventMachine - # - # EventMachine.run { - # puts "Starting the run now: #{Time.now}" - # EventMachine.add_timer 5, proc { puts "Executing timer event: #{Time.now}" } - # EventMachine.add_timer(10) { puts "Executing timer event: #{Time.now}" } - # } - # - # @param [Integer] delay Delay in seconds - # @see EventMachine::Timer - # @see EventMachine.add_periodic_timer - def self.add_timer *args, &block - interval = args.shift - code = args.shift || block - if code - # check too many timers! - s = add_oneshot_timer((interval.to_f * 1000).to_i) - @timers[s] = code - s - end - end - - # Adds a periodic timer to the event loop. - # It takes the same parameters as the one-shot timer method, {EventMachine.add_timer}. - # This method schedules execution of the given block repeatedly, at intervals - # of time *at least* as great as the number of seconds given in the first - # parameter to the call. - # - # @example Write a dollar-sign to stderr every five seconds, without blocking - # - # EventMachine.run { - # EventMachine.add_periodic_timer( 5 ) { $stderr.write "$" } - # } - # - # @param [Integer] delay Delay in seconds - # - # @see EventMachine::PeriodicTimer - # @see EventMachine.add_timer - # - def self.add_periodic_timer *args, &block - interval = args.shift - code = args.shift || block - - EventMachine::PeriodicTimer.new(interval, code) - end - - - # Cancel a timer (can be a callback or an {EventMachine::Timer} instance). - # - # @param [#cancel, #call] timer_or_sig A timer to cancel - # @see EventMachine::Timer#cancel - def self.cancel_timer timer_or_sig - if timer_or_sig.respond_to? :cancel - timer_or_sig.cancel - else - @timers[timer_or_sig] = false if @timers.has_key?(timer_or_sig) - end - end - - - # Causes the processing loop to stop executing, which will cause all open connections and accepting servers - # to be run down and closed. Connection termination callbacks added using {EventMachine.add_shutdown_hook} - # will be called as part of running this method. - # - # When all of this processing is complete, the call to {EventMachine.run} which started the processing loop - # will return and program flow will resume from the statement following {EventMachine.run} call. - # - # @example Stopping a running EventMachine event loop - # - # require 'rubygems' - # require 'eventmachine' - # - # module Redmond - # def post_init - # puts "We're sending a dumb HTTP request to the remote peer." - # send_data "GET / HTTP/1.1\r\nHost: www.microsoft.com\r\n\r\n" - # end - # - # def receive_data data - # puts "We received #{data.length} bytes from the remote peer." - # puts "We're going to stop the event loop now." - # EventMachine::stop_event_loop - # end - # - # def unbind - # puts "A connection has terminated." - # end - # end - # - # puts "We're starting the event loop now." - # EventMachine.run { - # EventMachine.connect "www.microsoft.com", 80, Redmond - # } - # puts "The event loop has stopped." - # - # # This program will produce approximately the following output: - # # - # # We're starting the event loop now. - # # We're sending a dumb HTTP request to the remote peer. - # # We received 1440 bytes from the remote peer. - # # We're going to stop the event loop now. - # # A connection has terminated. - # # The event loop has stopped. - # - # - def self.stop_event_loop - EventMachine::stop - end - - # Initiates a TCP server (socket acceptor) on the specified IP address and port. - # - # The IP address must be valid on the machine where the program - # runs, and the process must be privileged enough to listen - # on the specified port (on Unix-like systems, superuser privileges - # are usually required to listen on any port lower than 1024). - # Only one listener may be running on any given address/port - # combination. start_server will fail if the given address and port - # are already listening on the machine, either because of a prior call - # to {.start_server} or some unrelated process running on the machine. - # If {.start_server} succeeds, the new network listener becomes active - # immediately and starts accepting connections from remote peers, - # and these connections generate callback events that are processed - # by the code specified in the handler parameter to {.start_server}. - # - # The optional handler which is passed to this method is the key - # to EventMachine's ability to handle particular network protocols. - # The handler parameter passed to start_server must be a Ruby Module - # that you must define. When the network server that is started by - # start_server accepts a new connection, it instantiates a new - # object of an anonymous class that is inherited from {EventMachine::Connection}, - # *into which your handler module have been included*. Arguments passed into start_server - # after the class name are passed into the constructor during the instantiation. - # - # Your handler module may override any of the methods in {EventMachine::Connection}, - # such as {EventMachine::Connection#receive_data}, in order to implement the specific behavior - # of the network protocol. - # - # Callbacks invoked in response to network events *always* take place - # within the execution context of the object derived from {EventMachine::Connection} - # extended by your handler module. There is one object per connection, and - # all of the callbacks invoked for a particular connection take the form - # of instance methods called against the corresponding {EventMachine::Connection} - # object. Therefore, you are free to define whatever instance variables you - # wish, in order to contain the per-connection state required by the network protocol you are - # implementing. - # - # {EventMachine.start_server} is usually called inside the block passed to {EventMachine.run}, - # but it can be called from any EventMachine callback. {EventMachine.start_server} will fail - # unless the EventMachine event loop is currently running (which is why - # it's often called in the block suppled to {EventMachine.run}). - # - # You may call start_server any number of times to start up network - # listeners on different address/port combinations. The servers will - # all run simultaneously. More interestingly, each individual call to start_server - # can specify a different handler module and thus implement a different - # network protocol from all the others. - # - # @example - # - # require 'rubygems' - # require 'eventmachine' - # - # # Here is an example of a server that counts lines of input from the remote - # # peer and sends back the total number of lines received, after each line. - # # Try the example with more than one client connection opened via telnet, - # # and you will see that the line count increments independently on each - # # of the client connections. Also very important to note, is that the - # # handler for the receive_data function, which our handler redefines, may - # # not assume that the data it receives observes any kind of message boundaries. - # # Also, to use this example, be sure to change the server and port parameters - # # to the start_server call to values appropriate for your environment. - # module LineCounter - # MaxLinesPerConnection = 10 - # - # def post_init - # puts "Received a new connection" - # @data_received = "" - # @line_count = 0 - # end - # - # def receive_data data - # @data_received << data - # while @data_received.slice!( /^[^\n]*[\n]/m ) - # @line_count += 1 - # send_data "received #{@line_count} lines so far\r\n" - # @line_count == MaxLinesPerConnection and close_connection_after_writing - # end - # end - # end - # - # EventMachine.run { - # host, port = "192.168.0.100", 8090 - # EventMachine.start_server host, port, LineCounter - # puts "Now accepting connections on address #{host}, port #{port}..." - # EventMachine.add_periodic_timer(10) { $stderr.write "*" } - # } - # - # @param [String] server Host to bind to. - # @param [Integer] port Port to bind to. - # @param [Module, Class] handler A module or class that implements connection callbacks - # - # @note Don't forget that in order to bind to ports < 1024 on Linux, *BSD and Mac OS X your process must have superuser privileges. - # - # @see file:docs/GettingStarted.md EventMachine tutorial - # @see EventMachine.stop_server - def self.start_server server, port=nil, handler=nil, *args, &block - begin - port = Integer(port) - rescue ArgumentError, TypeError - # there was no port, so server must be a unix domain socket - # the port argument is actually the handler, and the handler is one of the args - args.unshift handler if handler - handler = port - port = nil - end if port - - klass = klass_from_handler(Connection, handler, *args) - - s = if port - start_tcp_server server, port - else - start_unix_server server - end - @acceptors[s] = [klass,args,block] - s - end - - # Attach to an existing socket's file descriptor. The socket may have been - # started with {EventMachine.start_server}. - def self.attach_server sock, handler=nil, *args, &block - klass = klass_from_handler(Connection, handler, *args) - sd = sock.respond_to?(:fileno) ? sock.fileno : sock - s = attach_sd(sd) - @acceptors[s] = [klass,args,block,sock] - s - end - - # Stop a TCP server socket that was started with {EventMachine.start_server}. - # @see EventMachine.start_server - def self.stop_server signature - EventMachine::stop_tcp_server signature - end - - # Start a Unix-domain server. - # - # Note that this is an alias for {EventMachine.start_server}, which can be used to start both - # TCP and Unix-domain servers. - # - # @see EventMachine.start_server - def self.start_unix_domain_server filename, *args, &block - start_server filename, *args, &block - end - - # Initiates a TCP connection to a remote server and sets up event handling for the connection. - # {EventMachine.connect} requires event loop to be running (see {EventMachine.run}). - # - # {EventMachine.connect} takes the IP address (or hostname) and - # port of the remote server you want to connect to. - # It also takes an optional handler (a module or a subclass of {EventMachine::Connection}) which you must define, that - # contains the callbacks that will be invoked by the event loop on behalf of the connection. - # - # Learn more about connection lifecycle callbacks in the {file:docs/GettingStarted.md EventMachine tutorial} and - # {file:docs/ConnectionLifecycleCallbacks.md Connection lifecycle guide}. - # - # - # @example - # - # # Here's a program which connects to a web server, sends a naive - # # request, parses the HTTP header of the response, and then - # # (antisocially) ends the event loop, which automatically drops the connection - # # (and incidentally calls the connection's unbind method). - # module DumbHttpClient - # def post_init - # send_data "GET / HTTP/1.1\r\nHost: _\r\n\r\n" - # @data = "" - # @parsed = false - # end - # - # def receive_data data - # @data << data - # if !@parsed and @data =~ /[\n][\r]*[\n]/m - # @parsed = true - # puts "RECEIVED HTTP HEADER:" - # $`.each {|line| puts ">>> #{line}" } - # - # puts "Now we'll terminate the loop, which will also close the connection" - # EventMachine::stop_event_loop - # end - # end - # - # def unbind - # puts "A connection has terminated" - # end - # end - # - # EventMachine.run { - # EventMachine.connect "www.bayshorenetworks.com", 80, DumbHttpClient - # } - # puts "The event loop has ended" - # - # - # @example Defining protocol handler as a class - # - # class MyProtocolHandler < EventMachine::Connection - # def initialize *args - # super - # # whatever else you want to do here - # end - # - # # ... - # end - # - # - # @param [String] server Host to connect to - # @param [Integer] port Port to connect to - # @param [Module, Class] handler A module or class that implements connection lifecycle callbacks - # - # @see EventMachine.start_server - # @see file:docs/GettingStarted.md EventMachine tutorial - def self.connect server, port=nil, handler=nil, *args, &blk - # EventMachine::connect initiates a TCP connection to a remote - # server and sets up event-handling for the connection. - # It internally creates an object that should not be handled - # by the caller. HOWEVER, it's often convenient to get the - # object to set up interfacing to other objects in the system. - # We return the newly-created anonymous-class object to the caller. - # It's expected that a considerable amount of code will depend - # on this behavior, so don't change it. - # - # Ok, added support for a user-defined block, 13Apr06. - # This leads us to an interesting choice because of the - # presence of the post_init call, which happens in the - # initialize method of the new object. We call the user's - # block and pass the new object to it. This is a great - # way to do protocol-specific initiation. It happens - # AFTER post_init has been called on the object, which I - # certainly hope is the right choice. - # Don't change this lightly, because accepted connections - # are different from connected ones and we don't want - # to have them behave differently with respect to post_init - # if at all possible. - - bind_connect nil, nil, server, port, handler, *args, &blk - end - - # This method is like {EventMachine.connect}, but allows for a local address/port - # to bind the connection to. - # - # @see EventMachine.connect - def self.bind_connect bind_addr, bind_port, server, port=nil, handler=nil, *args - begin - port = Integer(port) - rescue ArgumentError, TypeError - # there was no port, so server must be a unix domain socket - # the port argument is actually the handler, and the handler is one of the args - args.unshift handler if handler - handler = port - port = nil - end if port - - klass = klass_from_handler(Connection, handler, *args) - - s = if port - if bind_addr - bind_connect_server bind_addr, bind_port.to_i, server, port - else - connect_server server, port - end - else - connect_unix_server server - end - - c = klass.new s, *args - @conns[s] = c - block_given? and yield c - c - end - - # {EventMachine.watch} registers a given file descriptor or IO object with the eventloop. The - # file descriptor will not be modified (it will remain blocking or non-blocking). - # - # The eventloop can be used to process readable and writable events on the file descriptor, using - # {EventMachine::Connection#notify_readable=} and {EventMachine::Connection#notify_writable=} - # - # {EventMachine::Connection#notify_readable?} and {EventMachine::Connection#notify_writable?} can be used - # to check what events are enabled on the connection. - # - # To detach the file descriptor, use {EventMachine::Connection#detach} - # - # @example - # - # module SimpleHttpClient - # def notify_readable - # header = @io.readline - # - # if header == "\r\n" - # # detach returns the file descriptor number (fd == @io.fileno) - # fd = detach - # end - # rescue EOFError - # detach - # end - # - # def unbind - # EM.next_tick do - # # socket is detached from the eventloop, but still open - # data = @io.read - # end - # end - # end - # - # EventMachine.run { - # sock = TCPSocket.new('site.com', 80) - # sock.write("GET / HTTP/1.0\r\n\r\n") - # conn = EventMachine.watch(sock, SimpleHttpClient) - # conn.notify_readable = true - # } - # - # @author Riham Aldakkak (eSpace Technologies) - def EventMachine::watch io, handler=nil, *args, &blk - attach_io io, true, handler, *args, &blk - end - - # Attaches an IO object or file descriptor to the eventloop as a regular connection. - # The file descriptor will be set as non-blocking, and EventMachine will process - # receive_data and send_data events on it as it would for any other connection. - # - # To watch a fd instead, use {EventMachine.watch}, which will not alter the state of the socket - # and fire notify_readable and notify_writable events instead. - def EventMachine::attach io, handler=nil, *args, &blk - attach_io io, false, handler, *args, &blk - end - - # @private - def EventMachine::attach_io io, watch_mode, handler=nil, *args - klass = klass_from_handler(Connection, handler, *args) - - if !watch_mode and klass.public_instance_methods.any?{|m| [:notify_readable, :notify_writable].include? m.to_sym } - raise ArgumentError, "notify_readable/writable with EM.attach is not supported. Use EM.watch(io){ |c| c.notify_readable = true }" - end - - if io.respond_to?(:fileno) - # getDescriptorByFileno deprecated in JRuby 1.7.x, removed in JRuby 9000 - if defined?(JRuby) && JRuby.runtime.respond_to?(:getDescriptorByFileno) - fd = JRuby.runtime.getDescriptorByFileno(io.fileno).getChannel - else - fd = io.fileno - end - else - fd = io - end - - s = attach_fd fd, watch_mode - c = klass.new s, *args - - c.instance_variable_set(:@io, io) - c.instance_variable_set(:@watch_mode, watch_mode) - c.instance_variable_set(:@fd, fd) - - @conns[s] = c - block_given? and yield c - c - end - - - # Connect to a given host/port and re-use the provided {EventMachine::Connection} instance. - # Consider also {EventMachine::Connection#reconnect}. - # - # @see EventMachine::Connection#reconnect - def self.reconnect server, port, handler - # Observe, the test for already-connected FAILS if we call a reconnect inside post_init, - # because we haven't set up the connection in @conns by that point. - # RESIST THE TEMPTATION to "fix" this problem by redefining the behavior of post_init. - # - # Changed 22Nov06: if called on an already-connected handler, just return the - # handler and do nothing more. Originally this condition raised an exception. - # We may want to change it yet again and call the block, if any. - - raise "invalid handler" unless handler.respond_to?(:connection_completed) - #raise "still connected" if @conns.has_key?(handler.signature) - return handler if @conns.has_key?(handler.signature) - - s = if port - connect_server server, port - else - connect_unix_server server - end - handler.signature = s - @conns[s] = handler - block_given? and yield handler - handler - end - - - # Make a connection to a Unix-domain socket. This method is simply an alias for {.connect}, - # which can connect to both TCP and Unix-domain sockets. Make sure that your process has sufficient - # permissions to open the socket it is given. - # - # @param [String] socketname Unix domain socket (local fully-qualified path) you want to connect to. - # - # @note UNIX sockets, as the name suggests, are not available on Microsoft Windows. - def self.connect_unix_domain socketname, *args, &blk - connect socketname, *args, &blk - end - - - # Used for UDP-based protocols. Its usage is similar to that of {EventMachine.start_server}. - # - # This method will create a new UDP (datagram) socket and - # bind it to the address and port that you specify. - # The normal callbacks (see {EventMachine.start_server}) will - # be called as events of interest occur on the newly-created - # socket, but there are some differences in how they behave. - # - # {Connection#receive_data} will be called when a datagram packet - # is received on the socket, but unlike TCP sockets, the message - # boundaries of the received data will be respected. In other words, - # if the remote peer sent you a datagram of a particular size, - # you may rely on {Connection#receive_data} to give you the - # exact data in the packet, with the original data length. - # Also observe that Connection#receive_data may be called with a - # *zero-length* data payload, since empty datagrams are permitted in UDP. - # - # {Connection#send_data} is available with UDP packets as with TCP, - # but there is an important difference. Because UDP communications - # are *connectionless*, there is no implicit recipient for the packets you - # send. Ordinarily you must specify the recipient for each packet you send. - # However, EventMachine provides for the typical pattern of receiving a UDP datagram - # from a remote peer, performing some operation, and then sending - # one or more packets in response to the same remote peer. - # To support this model easily, just use {Connection#send_data} - # in the code that you supply for {Connection#receive_data}. - # - # EventMachine will provide an implicit return address for any messages sent to - # {Connection#send_data} within the context of a {Connection#receive_data} callback, - # and your response will automatically go to the correct remote peer. - # - # Observe that the port number that you supply to {EventMachine.open_datagram_socket} - # may be zero. In this case, EventMachine will create a UDP socket - # that is bound to an [ephemeral port](http://en.wikipedia.org/wiki/Ephemeral_port). - # This is not appropriate for servers that must publish a well-known - # port to which remote peers may send datagrams. But it can be useful - # for clients that send datagrams to other servers. - # If you do this, you will receive any responses from the remote - # servers through the normal {Connection#receive_data} callback. - # Observe that you will probably have issues with firewalls blocking - # the ephemeral port numbers, so this technique is most appropriate for LANs. - # - # If you wish to send datagrams to arbitrary remote peers (not - # necessarily ones that have sent data to which you are responding), - # then see {Connection#send_datagram}. - # - # DO NOT call send_data from a datagram socket outside of a {Connection#receive_data} method. Use {Connection#send_datagram}. - # If you do use {Connection#send_data} outside of a {Connection#receive_data} method, you'll get a confusing error - # because there is no "peer," as #send_data requires (inside of {EventMachine::Connection#receive_data}, - # {EventMachine::Connection#send_data} "fakes" the peer as described above). - # - # @param [String] address IP address - # @param [String] port Port - # @param [Class, Module] handler A class or a module that implements connection lifecycle callbacks. - def self.open_datagram_socket address, port, handler=nil, *args - # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing - # out that this originally did not take a class but only a module. - - - klass = klass_from_handler(Connection, handler, *args) - s = open_udp_socket address, port.to_i - c = klass.new s, *args - @conns[s] = c - block_given? and yield c - c - end - - - # For advanced users. This function sets the default timer granularity, which by default is - # slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity. - # The function affects the behavior of {EventMachine.add_timer} and {EventMachine.add_periodic_timer}. - # Most applications will not need to call this function. - # - # Avoid setting the quantum to very low values because that may reduce performance under some extreme conditions. - # We recommend that you not use values lower than 10. - # - # This method only can be used if event loop is running. - # - # @param [Integer] mills New timer granularity, in milliseconds - # - # @see EventMachine.add_timer - # @see EventMachine.add_periodic_timer - # @see EventMachine::Timer - # @see EventMachine.run - def self.set_quantum mills - set_timer_quantum mills.to_i - end - - # Sets the maximum number of timers and periodic timers that may be outstanding at any - # given time. You only need to call {.set_max_timers} if you need more than the default - # number of timers, which on most platforms is 1000. - # - # @note This method has to be used *before* event loop is started. - # - # @param [Integer] ct Maximum number of timers that may be outstanding at any given time - # - # @see EventMachine.add_timer - # @see EventMachine.add_periodic_timer - # @see EventMachine::Timer - def self.set_max_timers ct - set_max_timer_count ct - end - - # Gets the current maximum number of allowed timers - # - # @return [Integer] Maximum number of timers that may be outstanding at any given time - def self.get_max_timers - get_max_timer_count - end - - # Returns the total number of connections (file descriptors) currently held by the reactor. - # Note that a tick must pass after the 'initiation' of a connection for this number to increment. - # It's usually accurate, but don't rely on the exact precision of this number unless you really know EM internals. - # - # @example - # - # EventMachine.run { - # EventMachine.connect("rubyeventmachine.com", 80) - # # count will be 0 in this case, because connection is not - # # established yet - # count = EventMachine.connection_count - # } - # - # - # @example - # - # EventMachine.run { - # EventMachine.connect("rubyeventmachine.com", 80) - # - # EventMachine.next_tick { - # # In this example, count will be 1 since the connection has been established in - # # the next loop of the reactor. - # count = EventMachine.connection_count - # } - # } - # - # @return [Integer] Number of connections currently held by the reactor. - def self.connection_count - self.get_connection_count - end - - # The is the responder for the loopback-signalled event. - # It can be fired either by code running on a separate thread ({EventMachine.defer}) or on - # the main thread ({EventMachine.next_tick}). - # It will often happen that a next_tick handler will reschedule itself. We - # consume a copy of the tick queue so that tick events scheduled by tick events - # have to wait for the next pass through the reactor core. - # - # @private - def self.run_deferred_callbacks - until (@resultqueue ||= []).empty? - result,cback = @resultqueue.pop - cback.call result if cback - end - - # Capture the size at the start of this tick... - size = @next_tick_mutex.synchronize { @next_tick_queue.size } - size.times do |i| - callback = @next_tick_mutex.synchronize { @next_tick_queue.shift } - begin - callback.call - rescue - exception_raised = true - raise - ensure - # This is a little nasty. The problem is, if an exception occurs during - # the callback, then we need to send a signal to the reactor to actually - # do some work during the next_tick. The only mechanism we have from the - # ruby side is next_tick itself, although ideally, we'd just drop a byte - # on the loopback descriptor. - next_tick {} if exception_raised - end - end - end - - - # EventMachine.defer is used for integrating blocking operations into EventMachine's control flow. - # The action of {.defer} is to take the block specified in the first parameter (the "operation") - # and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine. - # When the operation completes, it will pass the result computed by the block (if any) back to the - # EventMachine reactor. Then, EventMachine calls the block specified in the second parameter to - # {.defer} (the "callback"), as part of its normal event handling loop. The result computed by the - # operation block is passed as a parameter to the callback. You may omit the callback parameter if - # you don't need to execute any code after the operation completes. If the operation raises an - # unhandled exception, the exception will be passed to the third parameter to {.defer} (the - # "errback"), as part of its normal event handling loop. If no errback is provided, the exception - # will be allowed to blow through to the main thread immediately. - # - # ## Caveats ## - # - # Note carefully that the code in your deferred operation will be executed on a separate - # thread from the main EventMachine processing and all other Ruby threads that may exist in - # your program. Also, multiple deferred operations may be running at once! Therefore, you - # are responsible for ensuring that your operation code is threadsafe. - # - # Don't write a deferred operation that will block forever. If so, the current implementation will - # not detect the problem, and the thread will never be returned to the pool. EventMachine limits - # the number of threads in its pool, so if you do this enough times, your subsequent deferred - # operations won't get a chance to run. - # - # The threads within the EventMachine's thread pool have abort_on_exception set to true. As a result, - # if an unhandled exception is raised by the deferred operation and an errback is not provided, it - # will blow through to the main thread immediately. If the main thread is within an indiscriminate - # rescue block at that time, the exception could be handled improperly by the main thread. - # - # @example - # - # operation = proc { - # # perform a long-running operation here, such as a database query. - # "result" # as usual, the last expression evaluated in the block will be the return value. - # } - # callback = proc {|result| - # # do something with result here, such as send it back to a network client. - # } - # errback = proc {|error| - # # do something with error here, such as re-raising or logging. - # } - # - # EventMachine.defer(operation, callback, errback) - # - # @param [#call] op An operation you want to offload to EventMachine thread pool - # @param [#call] callback A callback that will be run on the event loop thread after `operation` finishes. - # @param [#call] errback An errback that will be run on the event loop thread after `operation` raises an exception. - # - # @see EventMachine.threadpool_size - def self.defer op = nil, callback = nil, errback = nil, &blk - # OBSERVE that #next_tick hacks into this mechanism, so don't make any changes here - # without syncing there. - # - # Running with $VERBOSE set to true gives a warning unless all ivars are defined when - # they appear in rvalues. But we DON'T ever want to initialize @threadqueue unless we - # need it, because the Ruby threads are so heavyweight. We end up with this bizarre - # way of initializing @threadqueue because EventMachine is a Module, not a Class, and - # has no constructor. - - unless @threadpool - @threadpool = [] - @threadqueue = ::Queue.new - @resultqueue = ::Queue.new - spawn_threadpool - end - - @threadqueue << [op||blk,callback,errback] - end - - - # @private - def self.spawn_threadpool - until @threadpool.size == @threadpool_size.to_i - thread = Thread.new do - Thread.current.abort_on_exception = true - while true - begin - op, cback, eback = *@threadqueue.pop - rescue ThreadError - $stderr.puts $!.message - break # Ruby 2.0 may fail at Queue.pop - end - begin - result = op.call - @resultqueue << [result, cback] - rescue Exception => error - raise error unless eback - @resultqueue << [error, eback] - end - signal_loopbreak - end - end - @threadpool << thread - end - @all_threads_spawned = true - end - - ## - # Returns +true+ if all deferred actions are done executing and their - # callbacks have been fired. - # - def self.defers_finished? - return false if @threadpool and !@all_threads_spawned - return false if @threadqueue and not @threadqueue.empty? - return false if @resultqueue and not @resultqueue.empty? - return false if @threadpool and @threadqueue.num_waiting != @threadpool.size - return true - end - - class << self - # @private - attr_reader :threadpool - - # Size of the EventMachine.defer threadpool (defaults to 20) - # @return [Number] - attr_accessor :threadpool_size - EventMachine.threadpool_size = 20 - end - - # Schedules a proc for execution immediately after the next "turn" through the reactor - # core. An advanced technique, this can be useful for improving memory management and/or - # application responsiveness, especially when scheduling large amounts of data for - # writing to a network connection. - # - # This method takes either a single argument (which must be a callable object) or a block. - # - # @param [#call] pr A callable object to run - def self.next_tick pr=nil, &block - # This works by adding to the @resultqueue that's used for #defer. - # The general idea is that next_tick is used when we want to give the reactor a chance - # to let other operations run, either to balance the load out more evenly, or to let - # outbound network buffers drain, or both. So we probably do NOT want to block, and - # we probably do NOT want to be spinning any threads. A program that uses next_tick - # but not #defer shouldn't suffer the penalty of having Ruby threads running. They're - # extremely expensive even if they're just sleeping. - - raise ArgumentError, "no proc or block given" unless ((pr && pr.respond_to?(:call)) or block) - @next_tick_mutex.synchronize do - @next_tick_queue << ( pr || block ) - end - signal_loopbreak if reactor_running? - end - - # A wrapper over the setuid system call. Particularly useful when opening a network - # server on a privileged port because you can use this call to drop privileges - # after opening the port. Also very useful after a call to {.set_descriptor_table_size}, - # which generally requires that you start your process with root privileges. - # - # This method is intended for use in enforcing security requirements, consequently - # it will throw a fatal error and end your program if it fails. - # - # @param [String] username The effective name of the user whose privilege-level your process should attain. - # - # @note This method has no effective implementation on Windows or in the pure-Ruby - # implementation of EventMachine - def self.set_effective_user username - EventMachine::setuid_string username - end - - - # Sets the maximum number of file or socket descriptors that your process may open. - # If you call this method with no arguments, it will simply return - # the current size of the descriptor table without attempting to change it. - # - # The new limit on open descriptors **only** applies to sockets and other descriptors - # that belong to EventMachine. It has **no effect** on the number of descriptors - # you can create in ordinary Ruby code. - # - # Not available on all platforms. Increasing the number of descriptors beyond its - # default limit usually requires superuser privileges. (See {.set_effective_user} - # for a way to drop superuser privileges while your program is running.) - # - # @param [Integer] n_descriptors The maximum number of file or socket descriptors that your process may open - # @return [Integer] The new descriptor table size. - def self.set_descriptor_table_size n_descriptors=nil - EventMachine::set_rlimit_nofile n_descriptors - end - - - - # Runs an external process. - # - # @example - # - # module RubyCounter - # def post_init - # # count up to 5 - # send_data "5\n" - # end - # def receive_data data - # puts "ruby sent me: #{data}" - # end - # def unbind - # puts "ruby died with exit status: #{get_status.exitstatus}" - # end - # end - # - # EventMachine.run { - # EventMachine.popen("ruby -e' $stdout.sync = true; gets.to_i.times{ |i| puts i+1; sleep 1 } '", RubyCounter) - # } - # - # @note This method is not supported on Microsoft Windows - # @see EventMachine::DeferrableChildProcess - # @see EventMachine.system - def self.popen cmd, handler=nil, *args - # At this moment, it's only available on Unix. - # Perhaps misnamed since the underlying function uses socketpair and is full-duplex. - - klass = klass_from_handler(Connection, handler, *args) - w = case cmd - when Array - cmd - when String - Shellwords::shellwords( cmd ) - end - w.unshift( w.first ) if w.first - s = invoke_popen( w ) - c = klass.new s, *args - @conns[s] = c - yield(c) if block_given? - c - end - - - # Tells you whether the EventMachine reactor loop is currently running. - # - # Useful when writing libraries that want to run event-driven code, but may - # be running in programs that are already event-driven. In such cases, if {EventMachine.reactor_running?} - # returns false, your code can invoke {EventMachine.run} and run your application code inside - # the block passed to that method. If this method returns true, just - # execute your event-aware code. - # - # @return [Boolean] true if the EventMachine reactor loop is currently running - def self.reactor_running? - @reactor_running && Process.pid == @reactor_pid - end - - - # (Experimental) - # - # @private - def self.open_keyboard handler=nil, *args - klass = klass_from_handler(Connection, handler, *args) - - s = read_keyboard - c = klass.new s, *args - @conns[s] = c - block_given? and yield c - c - end - - # EventMachine's file monitoring API. Currently supported are the following events - # on individual files, using inotify on Linux systems, and kqueue for *BSD and Mac OS X: - # - # * File modified (written to) - # * File moved/renamed - # * File deleted - # - # EventMachine::watch_file takes a filename and a handler Module containing your custom callback methods. - # This will setup the low level monitoring on the specified file, and create a new EventMachine::FileWatch - # object with your Module mixed in. FileWatch is a subclass of {EventMachine::Connection}, so callbacks on this object - # work in the familiar way. The callbacks that will be fired by EventMachine are: - # - # * file_modified - # * file_moved - # * file_deleted - # - # You can access the filename being monitored from within this object using {FileWatch#path}. - # - # When a file is deleted, {FileWatch#stop_watching} will be called after your file_deleted callback, - # to clean up the underlying monitoring and remove EventMachine's reference to the now-useless {FileWatch} instance. - # This will in turn call unbind, if you wish to use it. - # - # The corresponding system-level Errno will be raised when attempting to monitor non-existent files, - # files with wrong permissions, or if an error occurs dealing with inotify/kqueue. - # - # @example - # - # # Before running this example, make sure we have a file to monitor: - # # $ echo "bar" > /tmp/foo - # - # module Handler - # def file_modified - # puts "#{path} modified" - # end - # - # def file_moved - # puts "#{path} moved" - # end - # - # def file_deleted - # puts "#{path} deleted" - # end - # - # def unbind - # puts "#{path} monitoring ceased" - # end - # end - # - # # for efficient file watching, use kqueue on Mac OS X - # EventMachine.kqueue = true if EventMachine.kqueue? - # - # EventMachine.run { - # EventMachine.watch_file("/tmp/foo", Handler) - # } - # - # # $ echo "baz" >> /tmp/foo => "/tmp/foo modified" - # # $ mv /tmp/foo /tmp/oof => "/tmp/foo moved" - # # $ rm /tmp/oof => "/tmp/foo deleted" - # - # @note The ability to pick up on the new filename after a rename is not yet supported. - # Calling #path will always return the filename you originally used. - # - # @param [String] filename Local path to the file to watch. - # @param [Class, Module] handler A class or module that implements event handlers associated with the file. - def self.watch_file(filename, handler=nil, *args) - klass = klass_from_handler(FileWatch, handler, *args) - - s = EM::watch_filename(filename) - c = klass.new s, *args - # we have to set the path like this because of how Connection.new works - c.instance_variable_set("@path", filename) - @conns[s] = c - block_given? and yield c - c - end - - # EventMachine's process monitoring API. On Mac OS X and *BSD this method is implemented using kqueue. - # - # @example - # - # module ProcessWatcher - # def process_exited - # put 'the forked child died!' - # end - # end - # - # pid = fork{ sleep } - # - # EventMachine.run { - # EventMachine.watch_process(pid, ProcessWatcher) - # EventMachine.add_timer(1){ Process.kill('TERM', pid) } - # } - # - # @param [Integer] pid PID of the process to watch. - # @param [Class, Module] handler A class or module that implements event handlers associated with the file. - def self.watch_process(pid, handler=nil, *args) - pid = pid.to_i - - klass = klass_from_handler(ProcessWatch, handler, *args) - - s = EM::watch_pid(pid) - c = klass.new s, *args - # we have to set the path like this because of how Connection.new works - c.instance_variable_set("@pid", pid) - @conns[s] = c - block_given? and yield c - c - end - - # Catch-all for errors raised during event loop callbacks. - # - # @example - # - # EventMachine.error_handler{ |e| - # puts "Error raised during event loop: #{e.message}" - # } - # - # @param [#call] cb Global catch-all errback - def self.error_handler cb = nil, &blk - if cb or blk - @error_handler = cb || blk - elsif instance_variable_defined? :@error_handler - remove_instance_variable :@error_handler - end - end - - # This method allows for direct writing of incoming data back out to another descriptor, at the C++ level in the reactor. - # This is very efficient and especially useful for proxies where high performance is required. Propogating data from a server response - # all the way up to Ruby, and then back down to the reactor to be sent back to the client, is often unnecessary and - # incurs a significant performance decrease. - # - # The two arguments are instance of {EventMachine::Connection} subclasses, 'from' and 'to'. 'from' is the connection whose inbound data you want - # relayed back out. 'to' is the connection to write it to. - # - # Once you call this method, the 'from' connection will no longer get receive_data callbacks from the reactor, - # except in the case that 'to' connection has already closed when attempting to write to it. You can see - # in the example, that proxy_target_unbound will be called when this occurs. After that, further incoming - # data will be passed into receive_data as normal. - # - # Note also that this feature supports different types of descriptors: TCP, UDP, and pipes. You can relay - # data from one kind to another, for example, feed a pipe from a UDP stream. - # - # @example - # - # module ProxyConnection - # def initialize(client, request) - # @client, @request = client, request - # end - # - # def post_init - # EM::enable_proxy(self, @client) - # end - # - # def connection_completed - # send_data @request - # end - # - # def proxy_target_unbound - # close_connection - # end - # - # def unbind - # @client.close_connection_after_writing - # end - # end - # - # module ProxyServer - # def receive_data(data) - # (@buf ||= "") << data - # if @buf =~ /\r\n\r\n/ # all http headers received - # EventMachine.connect("10.0.0.15", 80, ProxyConnection, self, data) - # end - # end - # end - # - # EventMachine.run { - # EventMachine.start_server("127.0.0.1", 8080, ProxyServer) - # } - # - # @param [EventMachine::Connection] from Source of data to be proxies/streamed. - # @param [EventMachine::Connection] to Destination of data to be proxies/streamed. - # @param [Integer] bufsize Buffer size to use - # @param [Integer] length Maximum number of bytes to proxy. - # - # @see EventMachine.disable_proxy - def self.enable_proxy(from, to, bufsize=0, length=0) - EM::start_proxy(from.signature, to.signature, bufsize, length) - end - - # Takes just one argument, a {Connection} that has proxying enabled via {EventMachine.enable_proxy}. - # Calling this method will remove that functionality and your connection will begin receiving - # data via {Connection#receive_data} again. - # - # @param [EventMachine::Connection] from Source of data that is being proxied - # @see EventMachine.enable_proxy - def self.disable_proxy(from) - EM::stop_proxy(from.signature) - end - - # Retrieve the heartbeat interval. This is how often EventMachine will check for dead connections - # that have had an inactivity timeout set via {Connection#set_comm_inactivity_timeout}. - # Default is 2 seconds. - # - # @return [Integer] Heartbeat interval, in seconds - def self.heartbeat_interval - EM::get_heartbeat_interval - end - - # Set the heartbeat interval. This is how often EventMachine will check for dead connections - # that have had an inactivity timeout set via {Connection#set_comm_inactivity_timeout}. - # Takes a Numeric number of seconds. Default is 2. - # - # @param [Integer] time Heartbeat interval, in seconds - def self.heartbeat_interval=(time) - EM::set_heartbeat_interval time.to_f - end - - # @private - def self.event_callback conn_binding, opcode, data - # - # Changed 27Dec07: Eliminated the hookable error handling. - # No one was using it, and it degraded performance significantly. - # It's in original_event_callback, which is dead code. - # - # Changed 25Jul08: Added a partial solution to the problem of exceptions - # raised in user-written event-handlers. If such exceptions are not caught, - # we must cause the reactor to stop, and then re-raise the exception. - # Otherwise, the reactor doesn't stop and it's left on the call stack. - # This is partial because we only added it to #unbind, where it's critical - # (to keep unbind handlers from being re-entered when a stopping reactor - # runs down open connections). It should go on the other calls to user - # code, but the performance impact may be too large. - # - if opcode == ConnectionUnbound - if c = @conns.delete( conn_binding ) - begin - if c.original_method(:unbind).arity != 0 - c.unbind(data == 0 ? nil : EventMachine::ERRNOS[data]) - else - c.unbind - end - # If this is an attached (but not watched) connection, close the underlying io object. - if c.instance_variable_defined?(:@io) and !c.instance_variable_get(:@watch_mode) - io = c.instance_variable_get(:@io) - begin - io.close - rescue Errno::EBADF, IOError - end - end - # As noted above, unbind absolutely must not raise an exception or the reactor will crash. - # If there is no EM.error_handler, or if the error_handler retrows, then stop the reactor, - # stash the exception in $wrapped_exception, and the exception will be raised after the - # reactor is cleaned up (see the last line of self.run). - rescue Exception => error - if instance_variable_defined? :@error_handler - begin - @error_handler.call error - # No need to stop unless error_handler rethrows - rescue Exception => error - @wrapped_exception = error - stop - end - else - @wrapped_exception = error - stop - end - end - elsif c = @acceptors.delete( conn_binding ) - # no-op - else - if $! # Bubble user generated errors. - @wrapped_exception = $! - stop - else - raise ConnectionNotBound, "received ConnectionUnbound for an unknown signature: #{conn_binding}" - end - end - elsif opcode == ConnectionAccepted - accep,args,blk = @acceptors[conn_binding] - raise NoHandlerForAcceptedConnection unless accep - c = accep.new data, *args - @conns[data] = c - blk and blk.call(c) - c # (needed?) - ## - # The remaining code is a fallback for the pure ruby and java reactors. - # In the C++ reactor, these events are handled in the C event_callback() in rubymain.cpp - elsif opcode == ConnectionCompleted - c = @conns[conn_binding] or raise ConnectionNotBound, "received ConnectionCompleted for unknown signature: #{conn_binding}" - c.connection_completed - elsif opcode == SslHandshakeCompleted - c = @conns[conn_binding] or raise ConnectionNotBound, "received SslHandshakeCompleted for unknown signature: #{conn_binding}" - c.ssl_handshake_completed - elsif opcode == SslVerify - c = @conns[conn_binding] or raise ConnectionNotBound, "received SslVerify for unknown signature: #{conn_binding}" - c.close_connection if c.ssl_verify_peer(data) == false - elsif opcode == TimerFired - t = @timers.delete( data ) - return if t == false # timer cancelled - t or raise UnknownTimerFired, "timer data: #{data}" - t.call - elsif opcode == ConnectionData - c = @conns[conn_binding] or raise ConnectionNotBound, "received data #{data} for unknown signature: #{conn_binding}" - c.receive_data data - elsif opcode == LoopbreakSignalled - run_deferred_callbacks - elsif opcode == ConnectionNotifyReadable - c = @conns[conn_binding] or raise ConnectionNotBound - c.notify_readable - elsif opcode == ConnectionNotifyWritable - c = @conns[conn_binding] or raise ConnectionNotBound - c.notify_writable - end - end - - # - # - # @private - def self._open_file_for_writing filename, handler=nil - klass = klass_from_handler(Connection, handler) - - s = _write_file filename - c = klass.new s - @conns[s] = c - block_given? and yield c - c - end - - # @private - def self.klass_from_handler(klass = Connection, handler = nil, *args) - klass = if handler and handler.is_a?(Class) - raise ArgumentError, "must provide module or subclass of #{klass.name}" unless klass >= handler - handler - elsif handler - if defined?(handler::EM_CONNECTION_CLASS) - handler::EM_CONNECTION_CLASS - else - handler::const_set(:EM_CONNECTION_CLASS, Class.new(klass) {include handler}) - end - else - klass - end - - arity = klass.instance_method(:initialize).arity - expected = arity >= 0 ? arity : -(arity + 1) - if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected) - raise ArgumentError, "wrong number of arguments for #{klass}#initialize (#{args.size} for #{expected})" - end - - klass - end -end # module EventMachine - -# Alias for {EventMachine} -EM = EventMachine -# Alias for {EventMachine::Protocols} -EM::P = EventMachine::Protocols diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/jeventmachine.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/jeventmachine.rb deleted file mode 100644 index 21a267d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/lib/jeventmachine.rb +++ /dev/null @@ -1,316 +0,0 @@ -#-- -# -# Author:: Francis Cianfrocca (gmail: blackhedd) -# Homepage:: http://rubyeventmachine.com -# Date:: 8 Apr 2006 -# -# See EventMachine and EventMachine::Connection for documentation and -# usage examples. -# -#---------------------------------------------------------------------------- -# -# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. -# Gmail: blackhedd -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of either: 1) the GNU General Public License -# as published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version; or 2) Ruby's License. -# -# See the file COPYING for complete licensing information. -# -#--------------------------------------------------------------------------- -# -# - -# This module provides "glue" for the Java version of the EventMachine reactor core. -# For C++ EventMachines, the analogous functionality is found in ext/rubymain.cpp, -# which is a garden-variety Ruby-extension glue module. - -require 'java' -require 'rubyeventmachine' -require 'socket' - -java_import java.io.FileDescriptor -java_import java.nio.channels.SocketChannel -java_import java.lang.reflect.Field - -module JavaFields - def set_field(key, value) - field = getClass.getDeclaredField(key) - field.setAccessible(true) - if field.getType.toString == 'int' - field.setInt(self, value) - else - field.set(self, value) - end - end - - def get_field(key) - field = getClass.getDeclaredField(key) - field.setAccessible(true) - field.get(self) - end -end - -FileDescriptor.send :include, JavaFields -SocketChannel.send :include, JavaFields - -module EventMachine - # TODO: These event numbers are defined in way too many places. - # DRY them up. - # @private - TimerFired = 100 - # @private - ConnectionData = 101 - # @private - ConnectionUnbound = 102 - # @private - ConnectionAccepted = 103 - # @private - ConnectionCompleted = 104 - # @private - LoopbreakSignalled = 105 - # @private - ConnectionNotifyReadable = 106 - # @private - ConnectionNotifyWritable = 107 - # @private - SslHandshakeCompleted = 108 - # @private - SslVerify = 109 - - # @private - EM_PROTO_SSLv2 = 2 - # @private - EM_PROTO_SSLv3 = 4 - # @private - EM_PROTO_TLSv1 = 8 - # @private - EM_PROTO_TLSv1_1 = 16 - # @private - EM_PROTO_TLSv1_2 = 32 - - # Exceptions that are defined in rubymain.cpp - class ConnectionError < RuntimeError; end - class ConnectionNotBound < RuntimeError; end - class UnknownTimerFired < RuntimeError; end - class Unsupported < RuntimeError; end - - # This thunk class used to be called EM, but that caused conflicts with - # the alias "EM" for module EventMachine. (FC, 20Jun08) - class JEM < com.rubyeventmachine.EmReactor - def eventCallback a1, a2, a3, a4 - s = String.from_java_bytes(a3.array[a3.position...a3.limit]) if a3 - EventMachine::event_callback a1, a2, s || a4 - nil - end - end - # class Connection < com.rubyeventmachine.Connection - # def associate_callback_target sig - # # No-op for the time being. - # end - # end - def self.initialize_event_machine - @em = JEM.new - end - def self.release_machine - @em = nil - end - def self.add_oneshot_timer interval - @em.installOneshotTimer interval - end - def self.run_machine - @em.run - end - def self.stop - @em.stop - end - def self.start_tcp_server server, port - @em.startTcpServer server, port - end - def self.stop_tcp_server sig - @em.stopTcpServer sig - end - def self.start_unix_server filename - # TEMPORARILY unsupported until someone figures out how to do it. - raise "unsupported on this platform" - end - def self.send_data sig, data, length - @em.sendData sig, data.to_java_bytes - rescue java.lang.NullPointerException - 0 - end - def self.send_datagram sig, data, length, address, port - @em.sendDatagram sig, data.to_java_bytes, length, address, port - end - def self.connect_server server, port - bind_connect_server nil, nil, server, port - end - def self.bind_connect_server bind_addr, bind_port, server, port - @em.connectTcpServer bind_addr, bind_port.to_i, server, port - end - def self.close_connection sig, after_writing - @em.closeConnection sig, after_writing - end - def self.set_comm_inactivity_timeout sig, interval - @em.setCommInactivityTimeout sig, interval - end - def self.set_pending_connect_timeout sig, val - end - def self.set_heartbeat_interval val - end - def self.start_tls sig - @em.startTls sig - end - def self.ssl? - false - end - def self.signal_loopbreak - @em.signalLoopbreak - end - def self.set_timer_quantum q - @em.setTimerQuantum q - end - def self.epoll - # Epoll is a no-op for Java. - # The latest Java versions run epoll when possible in NIO. - end - def self.epoll= val - end - def self.kqueue - end - def self.kqueue= val - end - def self.epoll? - false - end - def self.kqueue? - false - end - def self.set_rlimit_nofile n_descriptors - # Currently a no-op for Java. - end - def self.open_udp_socket server, port - @em.openUdpSocket server, port - end - def self.invoke_popen cmd - # TEMPORARILY unsupported until someone figures out how to do it. - raise "unsupported on this platform" - end - def self.read_keyboard - # TEMPORARILY unsupported until someone figures out how to do it. - raise "temporarily unsupported on this platform" - end - def self.set_max_timer_count num - # harmless no-op in Java. There's no built-in timer limit. - @max_timer_count = num - end - def self.get_max_timer_count - # harmless no-op in Java. There's no built-in timer limit. - @max_timer_count || 100_000 - end - def self.library_type - :java - end - def self.get_peername sig - if peer = @em.getPeerName(sig) - Socket.pack_sockaddr_in(*peer) - end - end - def self.get_sockname sig - if sockName = @em.getSockName(sig) - Socket.pack_sockaddr_in(*sockName) - end - end - # @private - def self.attach_fd fileno, watch_mode - # 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and - # we would need some logic to make sure detach_fd below didn't clobber it. For now, we just always make a new - # SocketChannel for the underlying file descriptor - # if fileno.java_kind_of? SocketChannel - # ch = fileno - # ch.configureBlocking(false) - # fileno = nil - # elsif fileno.java_kind_of? java.nio.channels.Channel - - if fileno.java_kind_of? java.nio.channels.Channel - field = fileno.getClass.getDeclaredField('fdVal') - field.setAccessible(true) - fileno = field.get(fileno) - else - raise ArgumentError, 'attach_fd requires Java Channel or POSIX fileno' unless fileno.is_a? Integer - end - - if fileno == 0 - raise "can't open STDIN as selectable in Java =(" - elsif fileno.is_a? Integer - # 8Aug09: The following code is specific to the sun jvm's SocketChannelImpl. Is there a cross-platform - # way of implementing this? If so, also remember to update EventableSocketChannel#close and #cleanup - fd = FileDescriptor.new - fd.set_field 'fd', fileno - - ch = SocketChannel.open - ch.configureBlocking(false) - ch.kill - ch.set_field 'fd', fd - ch.set_field 'fdVal', fileno - ch.set_field 'state', ch.get_field('ST_CONNECTED') - end - - @em.attachChannel(ch,watch_mode) - end - def self.detach_fd sig - if ch = @em.detachChannel(sig) - ch.get_field 'fdVal' - end - end - - def self.set_notify_readable sig, mode - @em.setNotifyReadable(sig, mode) - end - def self.set_notify_writable sig, mode - @em.setNotifyWritable(sig, mode) - end - - def self.is_notify_readable sig - @em.isNotifyReadable(sig) - end - def self.is_notify_writable sig - @em.isNotifyWritable(sig) - end - def self.get_connection_count - @em.getConnectionCount - end - - def self.pause_connection(sig) - @em.pauseConnection(sig) - end - def self.resume_connection(sig) - @em.resumeConnection(sig) - end - def self.connection_paused?(sig) - @em.isConnectionPaused(sig) - end - def self._get_outbound_data_size(sig) - @em.getOutboundDataSize(sig) - end - - - def self.set_tls_parms(sig, params) - end - def self.start_tls(sig) - end - def self.send_file_data(sig, filename) - end - - class Connection - def associate_callback_target sig - # No-op for the time being - end - def get_outbound_data_size - EM._get_outbound_data_size @signature - end - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/package.rake b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/package.rake deleted file mode 100644 index 00419d0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/package.rake +++ /dev/null @@ -1,120 +0,0 @@ -require 'rubygems' -require 'rubygems/package_task' - -begin - require 'rake/extensiontask' - require 'rake/javaextensiontask' -rescue LoadError => e - puts <<-MSG -rake-compiler gem seems to be missing. Please install it with - - gem install rake-compiler - -(add sudo if necessary). - MSG -end - -Gem::PackageTask.new(GEMSPEC) do |pkg| -end - -if RUBY_PLATFORM =~ /java/ - Rake::JavaExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext| - ext.ext_dir = 'java/src' - end -else - def setup_cross_compilation(ext) - unless RUBY_PLATFORM =~ /mswin|mingw/ - ext.cross_compile = true - ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] - end - end - def hack_cross_compilation(ext) - # inject 1.8/1.9 pure-ruby entry point - # HACK: add these dependencies to the task instead of using cross_compiling - if ext.cross_platform.is_a?(Array) - ext.cross_platform.each do |platform| - task = "native:#{GEMSPEC.name}:#{platform}" - if Rake::Task.task_defined?(task) - Rake::Task[task].prerequisites.unshift "lib/#{ext.name}.rb" - end - end - end - end - - em = Rake::ExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext| - ext.ext_dir = 'ext' - ext.source_pattern = '*.{h,c,cpp}' - setup_cross_compilation(ext) - end - hack_cross_compilation em - - ff = Rake::ExtensionTask.new("fastfilereaderext", GEMSPEC) do |ext| - ext.ext_dir = 'ext/fastfilereader' - ext.source_pattern = '*.{h,c,cpp}' - setup_cross_compilation(ext) - end - hack_cross_compilation ff -end - -# Setup shim files that require 1.8 vs 1.9 extensions in win32 bin gems -%w[ rubyeventmachine fastfilereaderext ].each do |filename| - file("lib/#{filename}.rb") do |t| - File.open(t.name, 'wb') do |f| - f.write <<-eoruby - RUBY_VERSION =~ /(\\d+.\\d+)/ - require "\#{$1}/#{File.basename(t.name, '.rb')}" - eoruby - end - at_exit{ FileUtils.rm t.name if File.exist?(t.name) } - end -end - -task :cross_cxx do - ENV['CROSS_COMPILING'] = 'yes' - require 'rake/extensioncompiler' - ENV['CXX'] = "#{Rake::ExtensionCompiler.mingw_host}-g++" -end - -if Rake::Task.task_defined?(:cross) - task :cross => 'lib/rubyeventmachine.rb' - task :cross => 'lib/fastfilereaderext.rb' - task :cross => :cross_cxx -end - -def windows?; RUBY_PLATFORM =~ /mswin|mingw/; end -def sudo(cmd) - if windows? || (require 'etc'; Etc.getpwuid.uid == 0) - sh cmd - else - sh "sudo #{cmd}" - end -end -def gem_cmd(action, name, *args) - rb = Gem.ruby rescue nil - rb ||= (require 'rbconfig'; File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])) - sudo "#{rb} -r rubygems -e 'require %{rubygems/gem_runner}; Gem::GemRunner.new.run(%w{#{action} #{name} #{args.join(' ')}})'" -end - -Rake::Task[:clean].enhance [:clobber_package] - -# DevKit task following the example of Luis Lavena's test-ruby-c-extension -task :devkit do - begin - require "devkit" - rescue LoadError => e - abort "Failed to activate RubyInstaller's DevKit required for compilation." - end -end - -if RUBY_PLATFORM =~ /mingw|mswin/ - Rake::Task['compile'].prerequisites.unshift 'devkit' -end - -desc "Build binary gems for Windows with rake-compiler-dock" -task 'gem:windows' do - require 'rake_compiler_dock' - RakeCompilerDock.sh <<-EOT - RUBY_CC_VERSION="${RUBY_CC_VERSION//1.8.7/}" - bundle && rake cross native gem - EOT -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test.rake b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test.rake deleted file mode 100644 index 1185ac7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test.rake +++ /dev/null @@ -1,8 +0,0 @@ -require 'rake/testtask' - -Rake::TestTask.new(:test) do |t| - t.libs << "tests" - t.libs << "lib" - t.pattern = 'tests/**/test_*.rb' - t.warning = true -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test_pure.rake b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test_pure.rake deleted file mode 100644 index 5a84ded..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/rakelib/test_pure.rake +++ /dev/null @@ -1,13 +0,0 @@ -require 'rake/testtask' - -Rake::TestTask.new(:test_pure) do |t| - t.libs << 'tests' - t.libs << 'lib' - t.test_files = Dir.glob('tests/**/test_pure*.rb') + Dir.glob('tests/**/test_ssl*.rb') - t.warning = true -end - -task :test_em_pure_ruby do - ENV['EM_PURE_RUBY'] = 'true' - Rake::Task['test_pure'].execute -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.crt b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.crt deleted file mode 100644 index 1919d97..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.crt +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFRDCCAywCAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCRU0xFTATBgNV -BAgTDEV2ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQL -EwtEZXZlbG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMB4XDTA5MDMyOTAy -MzE0NloXDTEwMDMyOTAyMzE0NlowaDELMAkGA1UEBhMCRU0xFTATBgNVBAgTDEV2 -ZW50TWFjaGluZTEVMBMGA1UEChMMRXZlbnRNYWNoaW5lMRQwEgYDVQQLEwtEZXZl -bG9wbWVudDEVMBMGA1UEAxMMRXZlbnRNYWNoaW5lMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEAv1FSOIX1z7CQtVBFlrB0A3/V29T+22STKKmiRWYkKL5b -+hkrp9IZ5J4phZHgUVM2VDPOO2Oc2PU6dlGGZISg+UPERunTogxQKezCV0vcE9cK -OwzxCFDRvv5rK8aKMscfBLbNKocAXywuRRQmdxPiVRzbyPrl+qCr/EDLXAX3D77l -S8n2AwDg19VyI+IgFUE+Dy5e1eLoY6nV+Mq+vNXdn3ttF3t+ngac5pj5Q9h+pD5p -67baDHSnf/7cy2fa/LKrLolVHQR9G2K6cEfeM99NtcsMbkoPs4iI3FA05OVTQHXg -C8C8cRxrb9APl95I/ep65OIaCJgcdYxJ3QD3qOtQo6/NQsGnjbyiUxaEpjfqyT1N -uzWD81Q8uXGNS8yD6dDynt/lseBjyp2nfC3uQ5fY18VdIcu0MJ9pezBUKrNuhlsy -XXEZ2DXj4sY8QOvIcBqSB/zmS1nGEK55xrtkaiaNrY8fe8wRVpcPLxy+P225NFw+ -B69FJRA0Lj6Jt9BM4hV/3MSIEWwTVhuw4E02ywDYTzz1wq3ITf0tsbIPn0hXQMxD -ohhAoKioM6u+yHtqsxD0eYaAWmHTVn5oDvOSGpvCpBfWHyA7FP5UQak0fKABEAgK -iQYEnb294AXwXymJttfGTIV/Ne4tLN5dIpNma8UO8rlThlcr6xnTQDbR3gkTDRsC -AwEAATANBgkqhkiG9w0BAQUFAAOCAgEAj7J8fy1LUWoVWnrXDAC9jwJ1nI/YjoSU -6ywke3o04+nZC5S+dPnuVy+HAwsU940CoNvP6RStI/bH6JL+NIqEFmwM3M8xIEWV -MYVPkfvQUxxGvDnaY7vv93u+6Q77HV3qlhAQBHChyuXyO7TG3+WzsiT9AnBNtAP0 -4jClt5kCAQXLO/p0SFEZQ8Ru9SM8d1i73Z0VDVzs8jYWlBhiherSgbw1xK4wBOpJ -43XmjZsBSrDpiAXd07Ak3UL2GjfT7eStgebL3UIe39ThE/s/+l43bh0M6WbOBvyQ -i/rZ50kd1GvN0xnZhtv07hIJWO85FGWi7Oet8AzdUZJ17v1Md/f2vdhPVTFN9q+w -mQ6LxjackqCvaJaQfBEbqsn2Tklxk4tZuDioiQbOElT2e6vljQVJWIfNx38Ny2LM -aiXQPQu+4CI7meAh5gXM5nyJGbZvRPsxj89CqYzyHCYs5HBP3AsviBvn26ziOF+c -544VmHd9HkIv8UTC29hh+R64RlgMQQQdaXFaUrFPTs/do0k8n/c2bPc0iTdfi5Q2 -gq6Vi8q6Ay5wGgTtRRbn/mWKuCFjEh94z6pF9Xr06NX0PuEOdf+Ls9vI5vz6G0w6 -0Li7devEN7EKBY+7Mcjg918yq9i5tEiMkUgT68788t3fTC+4iUQ5fDtdrHsaOlIR -8bs/XQVNE/s= ------END CERTIFICATE----- diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.key b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.key deleted file mode 100644 index 87a2531..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/client.key +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIJKAIBAAKCAgEAv1FSOIX1z7CQtVBFlrB0A3/V29T+22STKKmiRWYkKL5b+hkr -p9IZ5J4phZHgUVM2VDPOO2Oc2PU6dlGGZISg+UPERunTogxQKezCV0vcE9cKOwzx -CFDRvv5rK8aKMscfBLbNKocAXywuRRQmdxPiVRzbyPrl+qCr/EDLXAX3D77lS8n2 -AwDg19VyI+IgFUE+Dy5e1eLoY6nV+Mq+vNXdn3ttF3t+ngac5pj5Q9h+pD5p67ba -DHSnf/7cy2fa/LKrLolVHQR9G2K6cEfeM99NtcsMbkoPs4iI3FA05OVTQHXgC8C8 -cRxrb9APl95I/ep65OIaCJgcdYxJ3QD3qOtQo6/NQsGnjbyiUxaEpjfqyT1NuzWD -81Q8uXGNS8yD6dDynt/lseBjyp2nfC3uQ5fY18VdIcu0MJ9pezBUKrNuhlsyXXEZ -2DXj4sY8QOvIcBqSB/zmS1nGEK55xrtkaiaNrY8fe8wRVpcPLxy+P225NFw+B69F -JRA0Lj6Jt9BM4hV/3MSIEWwTVhuw4E02ywDYTzz1wq3ITf0tsbIPn0hXQMxDohhA -oKioM6u+yHtqsxD0eYaAWmHTVn5oDvOSGpvCpBfWHyA7FP5UQak0fKABEAgKiQYE -nb294AXwXymJttfGTIV/Ne4tLN5dIpNma8UO8rlThlcr6xnTQDbR3gkTDRsCAwEA -AQKCAgB495RDRQB9x6hX3F+DviI8rDGug+h5FAiwJ0IBG2o1kNdbNVsTC5dvpEmg -uPHaugCaEP+PMZbU34mNklKlb+7QbPbH18UGqz5so9TlmYOXz9oaKD6nAWL9nqRo -02pCXQDR3DuxbhbgFnFTIECJ/jqXkl2toGaVp83W+6kZkHP8srkMyLASihWgosc+ -xRWAGvaAZtNz7br+eT5fxuH/SEKPOl1qAZ23kXrXm1XQfizk8MnMTptkUMYv+hfl -TM98BASUsiTs6g+opy43HFn09naOQcqkWZO/8s6Gbvhi2lVfZqi5Ba6g3lVYJ3gU -kGoako4N9qB7WqJz+LYjVR9C4TbkkJ9OD6ArwGAx5IIzC3XKSxCyY/pUn4YumPhY -fjvY/km54TBtx/isS1TAgjSgDUxbzrfbkh7afOXSOniy9bWJMgNqHF61dqxWxmUg -F5Tch9zH3qFFVkXpYzDU/R8ZV+CRouCvhn0eZYDh8IqIAwjH0VjkxjPyQtrdrMd3 -gDKMVKoY31EOMLZzv8a0prjpr15A+uw30tT336qb3fofks4pZKUJw8ru9jJVir2p -+RML6iUHCmIeceF7/N1meooSMLPJe0xgKeMb9M4Wtd/et2UNVtP8nCDG622rf2a0 -F/EudXuFgc3FB8nXRw9TCkw9xKQff38edG5xPFUEgqObbVl5YQKCAQEA5DDKGOmp -EO5Zuf/kZfG6/AMMYwAuv1HrYTV2w/HnI3tyQ34Xkeqo+I/OqmRk68Ztxw4Kx1So -SRavkotrlWhhDpl2+Yn1BjkHktSoOdf9gJ9z9llkLmbOkBjmupig1NUB7fq/4y2k -MdqJXDy3uVKHJ97gxdIheMTyHiKuMJPnuT5lZtlT210Ig82P7sLQb/sgCfKVFTr0 -Z3haQ5/tBNKjq+igT4nMBWupOTD1q2GeZLIZACnmnUIhvu+3/bm0l+wiCB0DqF0T -Wy9tlL3fqQSCqzevL7/k5Lg6tJTaP/XYePB73TsOtAXgIaoltXgRBsBUeE1eaODx -kMT6E1PPtn7EqQKCAQEA1qImmTWGqhKICrwje40awPufFtZ/qXKVCN/V+zYsrJV1 -EnZpUDM+zfitlQCugnrQVHSpgfekI6mmVkmogO3fkNjUFTq+neg7IHOUHnqotx+3 -NMqIsyFInGstu9mfPd26fzZjUtx5wKF38LDTIJJAEJ83U3UpPBfpwKmiOGDXOa54 -2i4em/bb/hrQR6JySruZYLi0fXnGI5ZOfpkHgC/KOFkKNKAg2oh4B9qo7ACyiSNk -yojb2mmn6g1OLPxi7wGUSrkS1HQq4an6RZ+eUO0HXVWag0QStdQ91M9IrIHgSBBG -0e86Ar6jtD579gqsbz4ySpI/FqEI9obTC+E1/b0aIwKCAQAGz334qGCnZLXA22ZR -tJlEFEM2YTcD9snzqMjWqE2hvXl3kjfZ3wsUABbG9yAb+VwlaMHhmSE8rTSoRwj6 -+JaM/P+UCw4JFYKoWzh6IXwrbpbjb1+SEvdvTY71WsDSGVlpZOZ9PUt9QWyAGD/T -hCcMhZZn0RG2rQoc5CQWxxNPcBFOtIXQMkKizGvTUHUwImqeYWMZsxzASdNH2WoV -jsPbyaGfPhmcv83ZKyDp8IvtrXMZkiaT4vlm3Xi8VeKR9jY9z7/gMob1XcEDg3c9 -cCkGOy87WZrXSLhX02mAJzJCycqom66gqNw7pPxjIiY/8VWUEZsTvkL3cymTkhjM -9ZOhAoIBAGUaNqJe01NTrV+ZJgGyAxM6s8LXQYV5IvjuL2bJKxwUvvP2cT9FFGWD -qYiRrKJr5ayS07IUC+58oIzu33/0DSa27JgfduD9HrT3nKMK1mSEfRFSAjiXChQc -bIubRGapBoub/AdxMazqoovvT1R9b84kobQfcVAMV6DYh0CVZWyXYfgsV2DSVOiK -iufjfoDzg5lLCEI+1XW3/LunrB/W4yPN1X/amf8234ublYyt+2ucD4NUGnP05xLa -N6P7M0MwdEEKkvMe0YBBSFH5kWK/dIOjqkgBDes20fVnuuz/tL1dZW7IiIP4dzaV -ZGEOwBEatCfqYetv6b/u3IUxDfS7Wg8CggEBALoOwkn5LGdQg+bpdZAKJspGnJWL -Kyr9Al2tvgc69rxfpZqS5eDLkYYCzWPpspSt0Axm1O7xOUDQDt42luaLNGJzHZ2Q -Hn0ZNMhyHpe8d8mIQngRjD+nuLI/uFUglPzabDOCOln2aycjg1mA6ecXP1XMEVbu -0RB/0IE36XTMfZ+u9+TRjkBLpmUaX1FdIQQWfwUou/LfaXotoQlhSGAcprLrncuJ -T44UATYEgO/q9pMM33bdE3eBYZHoT9mSvqoLCN4s0LuwOYItIxLKUj0GulL0VQOI -SZi+0A1c8cVDXgApkBrWPDQIR9JS4de0gW4hnDoUvHtUc2TYPRnz6N9MtFY= ------END RSA PRIVATE KEY----- diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/dhparam.pem b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/dhparam.pem deleted file mode 100644 index b6464ab..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/dhparam.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIICCAKCAgEAikiatXa5aAteOtd6hOO33npjCvJByD3dwuM8rWzz0DFZdUH9nFJi -b0VvTVweVECb6XZBsrDNLqGQykCrm43swSk5D9XQCGJLxFERD6yk3b90xaeCm3/a -b0Ek5ZVvV73Cc/YbVmpBiOHoTFpUFJLZ7pLMQUSn8y3qUlNcY9/88HuwFi1s1lRM -ovihSRyZMYAuYWOD4yuOuIcroKVjD6gWFrsW9XrALWny6vUXQrhk8Q3rj+wM6ZtE -5afcB0b6ZJtphrDfk3dFjOVG/zVT37VWgrY8GABrpo2ey0W0WIQJ7rDKLaPaI4kc -voOgC2K8Z3kSARZK+jULnwmBeYECz4EH/FF6FEp3GOKtkL4mqEkvh1n5EAesDOGl -iiX+RZXcUrZliSeifSXBTMJWWFVC0fkGIMb9PTZfZHyAC54lpuxzVki0HIyQG9Fs -41zBJ5e8eEoXXlfUYtduUC35YGy2IxSzYLAJE76rctAZSWghha9xLOCDFoLjMr8h -FosKeHKJcBQ0bc8ymOpRIfrYLWhc0Pz2zkpJ/4eYw9t7NYg7S+jP19IE0gUnuM9v -SpoYMtS28tP9nEdokdwuBKD0D3bJEBBefDlHgfXoMgvy9Hivc9PBGGNTNpyFPpwF -sWVAkfhoNMJMC5V7LZsze+lftiDtzVoLSPDa9bO4BK7b/MgwCxfOhGsCAQI= ------END DH PARAMETERS----- diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/em_test_helper.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/em_test_helper.rb deleted file mode 100644 index 20a3e59..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/em_test_helper.rb +++ /dev/null @@ -1,154 +0,0 @@ -require 'em/pure_ruby' if ENV['EM_PURE_RUBY'] -require 'eventmachine' -require 'test/unit' -require 'rbconfig' -require 'socket' - -puts "EM Library Type: #{EM.library_type}" - -class Test::Unit::TestCase - class EMTestTimeout < StandardError ; end - - def setup_timeout(timeout = TIMEOUT_INTERVAL) - EM.schedule { - EM.add_timer(timeout) { - raise EMTestTimeout, "Test was cancelled after #{timeout} seconds." - } - } - end - - def port_in_use?(port, host="127.0.0.1") - s = TCPSocket.new(host, port) - s.close - s - rescue Errno::ECONNREFUSED - false - end - - def next_port - @@port ||= 9000 - begin - @@port += 1 - end while port_in_use?(@@port) - - @@port - end - - # Returns true if the host have a localhost 127.0.0.1 IPv4. - def self.local_ipv4? - return @@has_local_ipv4 if defined?(@@has_local_ipv4) - begin - get_my_ipv4_address "127.0.0.1" - @@has_local_ipv4 = true - rescue - @@has_local_ipv4 = false - end - end - - # Returns true if the host have a public IPv4 and stores it in - # @@public_ipv4. - def self.public_ipv4? - return @@has_public_ipv4 if defined?(@@has_public_ipv4) - begin - @@public_ipv4 = get_my_ipv4_address "1.2.3.4" - @@has_public_ipv4 = true - rescue - @@has_public_ipv4 = false - end - end - - # Returns true if the host have a localhost ::1 IPv6. - def self.local_ipv6? - return @@has_local_ipv6 if defined?(@@has_local_ipv6) - begin - get_my_ipv6_address "::1" - @@has_local_ipv6 = true - rescue - @@has_local_ipv6 = false - end - end - - # Returns true if the host have a public IPv6 and stores it in - # @@public_ipv6. - def self.public_ipv6? - return @@has_public_ipv6 if defined?(@@has_public_ipv6) - begin - @@public_ipv6 = get_my_ipv6_address "2001::1" - @@has_public_ipv6 = true - rescue - @@has_public_ipv6 = false - end - end - - # Returns an array with the localhost addresses (IPv4 and/or IPv6). - def local_ips - return @@local_ips if defined?(@@local_ips) - @@local_ips = [] - @@local_ips << "127.0.0.1" if self.class.local_ipv4? - @@local_ips << "::1" if self.class.local_ipv6? - @@local_ips - end - - def exception_class - jruby? ? NativeException : RuntimeError - end - - module PlatformHelper - # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/ - def windows? - RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ - end - - def solaris? - RUBY_PLATFORM =~ /solaris/ - end - - # http://stackoverflow.com/questions/1342535/how-can-i-tell-if-im-running-from-jruby-vs-ruby/1685970#1685970 - def jruby? - defined? JRUBY_VERSION - end - - def rbx? - defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' - end - end - - include PlatformHelper - extend PlatformHelper - - # Tests run significantly slower on windows. YMMV - TIMEOUT_INTERVAL = windows? ? 1 : 0.25 - - def silent - backup, $VERBOSE = $VERBOSE, nil - begin - yield - ensure - $VERBOSE = backup - end - end - - - private - - def self.get_my_ipv4_address ip - orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily - UDPSocket.open(Socket::AF_INET) do |s| - s.connect ip, 1 - s.addr.last - end - ensure - Socket.do_not_reverse_lookup = orig - end - - def self.get_my_ipv6_address ip - orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily - UDPSocket.open(Socket::AF_INET6) do |s| - s.connect ip, 1 - s.addr.last - end - ensure - Socket.do_not_reverse_lookup = orig - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_attach.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_attach.rb deleted file mode 100644 index 4a55017..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_attach.rb +++ /dev/null @@ -1,151 +0,0 @@ -require 'em_test_helper' -require 'socket' - -class TestAttach < Test::Unit::TestCase - class EchoServer < EM::Connection - def receive_data data - $received_data << data - send_data data - end - end - - class EchoClient < EM::Connection - def initialize socket - self.notify_readable = true - @socket = socket - @socket.write("abc\n") - end - - def notify_readable - $read = @socket.readline - $fd = detach - end - - def unbind - EM.next_tick do - @socket.write("def\n") - EM.add_timer(0.1) { EM.stop } - end - end - end - - def setup - @port = next_port - $read, $r, $w, $fd = nil - $received_data = "" - end - - def teardown - [$r, $w].each do |io| - io.close rescue nil - end - $received_data = nil - end - - def test_attach - socket = nil - - EM.run { - EM.start_server "127.0.0.1", @port, EchoServer - socket = TCPSocket.new "127.0.0.1", @port - EM.watch socket, EchoClient, socket - } - - assert_equal $read, "abc\n" - unless jruby? # jruby filenos are not real - assert_equal $fd, socket.fileno - end - assert_equal false, socket.closed? - assert_equal socket.readline, "def\n" - end - - module PipeWatch - def notify_readable - $read = $r.readline - EM.stop - end - end - - def test_attach_server - omit_if(jruby?) - $before = TCPServer.new("127.0.0.1", @port) - sig = nil - EM.run { - sig = EM.attach_server $before, EchoServer - - handler = Class.new(EM::Connection) do - def initialize - send_data "hello world" - close_connection_after_writing - EM.add_timer(0.1) { EM.stop } - end - end - EM.connect("127.0.0.1", @port, handler) - } - - assert_equal false, $before.closed? - assert_equal "hello world", $received_data - assert sig.is_a?(Integer) - end - - def test_attach_pipe - EM.run{ - $r, $w = IO.pipe - EM.watch $r, PipeWatch do |c| - c.notify_readable = true - end - $w.write("ghi\n") - } - - assert_equal $read, "ghi\n" - end - - def test_set_readable - before, after = nil - - EM.run{ - $r, $w = IO.pipe - c = EM.watch $r, PipeWatch do |con| - con.notify_readable = false - end - - EM.next_tick{ - before = c.notify_readable? - c.notify_readable = true - after = c.notify_readable? - } - - $w.write("jkl\n") - } - - assert !before - assert after - assert_equal $read, "jkl\n" - end - - def test_read_write_pipe - result = nil - - pipe_reader = Module.new do - define_method :receive_data do |data| - result = data - EM.stop - end - end - - r,w = IO.pipe - - EM.run { - EM.attach r, pipe_reader - writer = EM.attach(w) - writer.send_data 'ghi' - - # XXX: Process will hang in Windows without this line - writer.close_connection_after_writing - } - - assert_equal "ghi", result - ensure - [r,w].each {|io| io.close rescue nil } - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_basic.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_basic.rb deleted file mode 100644 index 4d72524..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_basic.rb +++ /dev/null @@ -1,321 +0,0 @@ -require 'em_test_helper' -require 'socket' - -class TestBasic < Test::Unit::TestCase - def setup - @port = next_port - end - - def test_connection_class_cache - mod = Module.new - a, b = nil, nil - EM.run { - EM.start_server '127.0.0.1', @port, mod - a = EM.connect '127.0.0.1', @port, mod - b = EM.connect '127.0.0.1', @port, mod - EM.stop - } - assert_equal a.class, b.class - assert_kind_of EM::Connection, a - end - - #------------------------------------- - - - def test_em - assert_nothing_raised do - EM.run { - setup_timeout - EM.add_timer 0 do - EM.stop - end - } - end - end - - #------------------------------------- - - def test_timer - assert_nothing_raised do - EM.run { - setup_timeout - n = 0 - EM.add_periodic_timer(0.1) { - n += 1 - EM.stop if n == 2 - } - } - end - end - - #------------------------------------- - - # This test once threw an already-running exception. - module Trivial - def post_init - EM.stop - end - end - - def test_server - assert_nothing_raised do - EM.run { - setup_timeout - EM.start_server "127.0.0.1", @port, Trivial - EM.connect "127.0.0.1", @port - } - end - end - - #-------------------------------------- - - # EM#run_block starts the reactor loop, runs the supplied block, and then STOPS - # the loop automatically. Contrast with EM#run, which keeps running the reactor - # even after the supplied block completes. - def test_run_block - assert !EM.reactor_running? - a = nil - EM.run_block { a = "Worked" } - assert a - assert !EM.reactor_running? - end - - class UnbindError < EM::Connection - ERR = Class.new(StandardError) - def initialize *args - super - end - def connection_completed - close_connection_after_writing - end - def unbind - raise ERR - end - end - - def test_unbind_error_during_stop - assert_raises( UnbindError::ERR ) { - EM.run { - EM.start_server "127.0.0.1", @port - EM.connect "127.0.0.1", @port, UnbindError do - EM.stop - end - } - } - end - - def test_unbind_error - EM.run { - EM.error_handler do |e| - assert(e.is_a?(UnbindError::ERR)) - EM.stop - end - EM.start_server "127.0.0.1", @port - EM.connect "127.0.0.1", @port, UnbindError - } - - # Remove the error handler before the next test - EM.error_handler(nil) - end - - module BrsTestSrv - def receive_data data - $received << data - end - def unbind - EM.stop - end - end - module BrsTestCli - def post_init - send_data $sent - close_connection_after_writing - end - end - - # From ticket #50 - def test_byte_range_send - $received = '' - $sent = (0..255).to_a.pack('C*') - EM::run { - EM::start_server "127.0.0.1", @port, BrsTestSrv - EM::connect "127.0.0.1", @port, BrsTestCli - - setup_timeout - } - assert_equal($sent, $received) - end - - def test_bind_connect - pend('FIXME: this test is broken on Windows') if windows? - - local_ip = UDPSocket.open {|s| s.connect('localhost', 80); s.addr.last } - - bind_port = next_port - - port, ip = nil - bound_server = Module.new do - define_method :post_init do - begin - port, ip = Socket.unpack_sockaddr_in(get_peername) - ensure - EM.stop - end - end - end - - EM.run do - setup_timeout - EM.start_server "127.0.0.1", @port, bound_server - EM.bind_connect local_ip, bind_port, "127.0.0.1", @port - end - - assert_equal bind_port, port - assert_equal local_ip, ip - end - - def test_invalid_address_bind_connect_dst - e = nil - EM.run do - begin - EM.bind_connect('localhost', nil, 'invalid.invalid', 80) - rescue Exception => e - # capture the exception - ensure - EM.stop - end - end - - assert_kind_of(EventMachine::ConnectionError, e) - assert_match(/unable to resolve address:.*not known/, e.message) - end - - def test_invalid_address_bind_connect_src - e = nil - EM.run do - begin - EM.bind_connect('invalid.invalid', nil, 'localhost', 80) - rescue Exception => e - # capture the exception - ensure - EM.stop - end - end - - assert_kind_of(EventMachine::ConnectionError, e) - assert_match(/invalid bind address:.*not known/, e.message) - end - - def test_reactor_thread? - assert !EM.reactor_thread? - EM.run { assert EM.reactor_thread?; EM.stop } - assert !EM.reactor_thread? - end - - def test_schedule_on_reactor_thread - x = false - EM.run do - EM.schedule { x = true } - EM.stop - end - assert x - end - - def test_schedule_from_thread - x = false - EM.run do - Thread.new { EM.schedule { x = true; EM.stop } }.join - end - assert x - end - - def test_set_heartbeat_interval - omit_if(jruby?) - interval = 0.5 - EM.run { - EM.set_heartbeat_interval interval - $interval = EM.get_heartbeat_interval - EM.stop - } - assert_equal(interval, $interval) - end - - module PostInitRaiser - ERR = Class.new(StandardError) - def post_init - raise ERR - end - end - - def test_bubble_errors_from_post_init - assert_raises(PostInitRaiser::ERR) do - EM.run do - EM.start_server "127.0.0.1", @port - EM.connect "127.0.0.1", @port, PostInitRaiser - end - end - end - - module InitializeRaiser - ERR = Class.new(StandardError) - def initialize - raise ERR - end - end - - def test_bubble_errors_from_initialize - assert_raises(InitializeRaiser::ERR) do - EM.run do - EM.start_server "127.0.0.1", @port - EM.connect "127.0.0.1", @port, InitializeRaiser - end - end - end - - def test_schedule_close - omit_if(jruby?) - localhost, port = '127.0.0.1', 9000 - timer_ran = false - num_close_scheduled = nil - EM.run do - assert_equal 0, EM.num_close_scheduled - EM.add_timer(1) { timer_ran = true; EM.stop } - EM.start_server localhost, port do |s| - s.close_connection - num_close_scheduled = EM.num_close_scheduled - end - EM.connect localhost, port do |c| - def c.unbind - EM.stop - end - end - end - assert !timer_ran - assert_equal 1, num_close_scheduled - end - - def test_error_handler_idempotent # issue 185 - errors = [] - ticks = [] - EM.error_handler do |e| - errors << e - end - - EM.run do - EM.next_tick do - ticks << :first - raise - end - EM.next_tick do - ticks << :second - end - EM.add_timer(0.001) { EM.stop } - end - - # Remove the error handler before the next test - EM.error_handler(nil) - - assert_equal 1, errors.size - assert_equal [:first, :second], ticks - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_channel.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_channel.rb deleted file mode 100644 index c54bf1d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_channel.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'em_test_helper' - -class TestEMChannel < Test::Unit::TestCase - def test_channel_subscribe - s = 0 - EM.run do - c = EM::Channel.new - c.subscribe { |v| s = v; EM.stop } - c << 1 - end - assert_equal 1, s - end - - def test_channel_unsubscribe - s = 0 - EM.run do - c = EM::Channel.new - subscription = c.subscribe { |v| s = v } - c.unsubscribe(subscription) - c << 1 - EM.next_tick { EM.stop } - end - assert_not_equal 1, s - end - - def test_channel_pop - s = 0 - EM.run do - c = EM::Channel.new - c.pop{ |v| s = v } - c.push(1,2,3) - c << 4 - c << 5 - EM.next_tick { EM.stop } - end - assert_equal 1, s - end - - def test_channel_reactor_thread_push - out = [] - c = EM::Channel.new - c.subscribe { |v| out << v } - Thread.new { c.push(1,2,3) }.join - assert out.empty? - - EM.run { EM.next_tick { EM.stop } } - - assert_equal [1,2,3], out - end - - def test_channel_reactor_thread_callback - out = [] - c = EM::Channel.new - Thread.new { c.subscribe { |v| out << v } }.join - c.push(1,2,3) - assert out.empty? - - EM.run { EM.next_tick { EM.stop } } - - assert_equal [1,2,3], out - end - - def test_channel_num_subscribers - subs = 0 - EM.run do - c = EM::Channel.new - c.subscribe { |v| s = v } - c.subscribe { |v| s = v } - EM.next_tick { EM.stop } - subs = c.num_subscribers - end - - assert_equal subs, 2 - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_completion.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_completion.rb deleted file mode 100644 index 1bd9a8f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_completion.rb +++ /dev/null @@ -1,178 +0,0 @@ -require 'em_test_helper' -require 'em/completion' - -class TestCompletion < Test::Unit::TestCase - def completion - @completion ||= EM::Completion.new - end - - def crank - # This is a slow solution, but this just executes the next tick queue - # once. It's the easiest way for now. - EM.run { EM.stop } - end - - def results - @results ||= [] - end - - def test_state - assert_equal :unknown, completion.state - end - - def test_succeed - completion.callback { |val| results << val } - completion.succeed :object - crank - assert_equal :succeeded, completion.state - assert_equal [:object], results - end - - def test_fail - completion.errback { |val| results << val } - completion.fail :object - crank - assert_equal :failed, completion.state - assert_equal [:object], results - end - - def test_callback - completion.callback { results << :callback } - completion.errback { results << :errback } - completion.succeed - crank - assert_equal [:callback], results - end - - def test_errback - completion.callback { results << :callback } - completion.errback { results << :errback } - completion.fail - crank - assert_equal [:errback], results - end - - def test_stateback - completion.stateback(:magic) { results << :stateback } - completion.change_state(:magic) - crank - assert_equal [:stateback], results - end - - def test_does_not_enqueue_when_completed - completion.callback { results << :callback } - completion.succeed - completion.errback { results << :errback } - completion.fail - crank - assert_equal [:callback], results - end - - def test_completed - assert_equal false, completion.completed? - completion.succeed - assert_equal true, completion.completed? - completion.fail - assert_equal true, completion.completed? - completion.change_state :magic - assert_equal false, completion.completed? - end - - def test_recursive_callbacks - completion.callback do |val| - results << val - completion.succeed :two - end - completion.callback do |val| - results << val - completion.succeed :three - end - completion.callback do |val| - results << val - end - completion.succeed :one - crank - assert_equal [:one, :two, :three], results - end - - def test_late_defined_callbacks - completion.callback { results << :one } - completion.succeed - crank - assert_equal [:one], results - completion.callback { results << :two } - crank - assert_equal [:one, :two], results - end - - def test_cleared_completions - completion.callback { results << :callback } - completion.errback { results << :errback } - - completion.succeed - crank - completion.fail - crank - completion.succeed - crank - - assert_equal [:callback], results - end - - def test_skip_completed_callbacks - completion.callback { results << :callback } - completion.succeed - crank - - completion.errback { results << :errback } - completion.fail - crank - - assert_equal [:callback], results - end - - def test_completions - completion.completion { results << :completion } - completion.succeed - crank - assert_equal [:completion], results - - completion.change_state(:unknown) - results.clear - - completion.completion { results << :completion } - completion.fail - crank - assert_equal [:completion], results - end - - def test_latent_completion - completion.completion { results << :completion } - completion.succeed - crank - completion.completion { results << :completion } - crank - assert_equal [:completion, :completion], results - end - - def test_timeout - args = [1, 2, 3] - EM.run do - completion.timeout(0.0001, *args) - completion.errback { |*errargs| results << errargs } - completion.completion { EM.stop } - EM.add_timer(0.1) { flunk 'test timed out' } - end - assert_equal [[1,2,3]], results - end - - def test_timeout_gets_cancelled - EM.run do - completion.timeout(0.0001, :timeout) - completion.errback { results << :errback } - completion.succeed - EM.add_timer(0.0002) { EM.stop } - end - assert_equal [], results - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_count.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_count.rb deleted file mode 100644 index 350c417..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_count.rb +++ /dev/null @@ -1,83 +0,0 @@ -require 'em_test_helper' - -class TestConnectionCount < Test::Unit::TestCase - def teardown - EM.epoll = false - EM.kqueue = false - end - - def test_idle_connection_count - count = nil - EM.run { - count = EM.connection_count - EM.stop_event_loop - } - assert_equal(0, count) - end - - # Run this again with epoll enabled (if available) - def test_idle_connection_count_epoll - EM.epoll if EM.epoll? - - count = nil - EM.run { - count = EM.connection_count - EM.stop_event_loop - } - assert_equal(0, count) - end - - # Run this again with kqueue enabled (if available) - def test_idle_connection_count_kqueue - EM.kqueue if EM.kqueue? - - count = nil - EM.run { - count = EM.connection_count - EM.stop_event_loop - } - assert_equal(0, count) - end - - module Client - def connection_completed - $client_conns += 1 - EM.stop if $client_conns == 3 - end - end - - def test_with_some_connections - EM.run { - $client_conns = 0 - $initial_conns = EM.connection_count - EM.start_server("127.0.0.1", 9999) - $server_conns = EM.connection_count - 3.times { EM.connect("127.0.0.1", 9999, Client) } - } - - assert_equal(0, $initial_conns) - assert_equal(1, $server_conns) - assert_equal(4, $client_conns + $server_conns) - end - - module DoubleCloseClient - def unbind - close_connection - $num_close_scheduled_1 = EM.num_close_scheduled - EM.next_tick do - $num_close_scheduled_2 = EM.num_close_scheduled - EM.stop - end - end - end - - def test_num_close_scheduled - omit_if(jruby?) - EM.run { - assert_equal(0, EM.num_close_scheduled) - EM.connect("127.0.0.1", 9999, DoubleCloseClient) # nothing listening on 9999 - } - assert_equal(1, $num_close_scheduled_1) - assert_equal(0, $num_close_scheduled_2) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_write.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_write.rb deleted file mode 100644 index 35533b5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_connection_write.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'em_test_helper' - -class TestConnectionWrite < Test::Unit::TestCase - - # This test takes advantage of the fact that EM::_RunSelectOnce iterates over the connections twice: - # - once to determine which ones to call Write() on - # - and once to call Write() on each of them. - # - # But state may change in the meantime before Write() is finally called. - # And that is what we try to exploit to get Write() to be called when bWatchOnly is true, and bNotifyWritable is false, - # to cause an assertion failure. - - module SimpleClient - def notify_writable - $conn2.notify_writable = false # Being naughty in callback - # If this doesn't crash anything, the test passed! - end - end - - def test_with_naughty_callback - EM.run do - r1, _ = IO.pipe - r2, _ = IO.pipe - - # Adding EM.watches - $conn1 = EM.watch(r1, SimpleClient) - $conn2 = EM.watch(r2, SimpleClient) - - $conn1.notify_writable = true - $conn2.notify_writable = true - - EM.stop - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_defer.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_defer.rb deleted file mode 100644 index aeca127..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_defer.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'em_test_helper' - -class TestDefer < Test::Unit::TestCase - - def test_defers - n = 0 - n_times = 20 - EM.run { - n_times.times { - work_proc = proc { n += 1 } - callback = proc { EM.stop if n == n_times } - EM.defer work_proc, callback - } - } - assert_equal( n, n_times ) - end - - def test_errbacks - iterations = 20 - callback_parameter = rand(100) - callback_parameters = [] - callback_op = proc { callback_parameter } - callback = proc { |result| callback_parameters << result } - errback_parameter = Exception.new - errback_parameters = [] - errback_op = proc { raise errback_parameter } - errback = proc { |error| errback_parameters << error } - EventMachine.run do - (1..iterations).each { |index| EventMachine.defer(index.even? ? callback_op : errback_op, callback, errback) } - EventMachine.add_periodic_timer(0.1) { EventMachine.stop if EventMachine.defers_finished? } - end - assert_equal(callback_parameters.select { |parameter| parameter == callback_parameter }.length, iterations * 0.5) - assert_equal(errback_parameters.select{ |parameter| parameter == errback_parameter }.length, iterations * 0.5) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_deferrable.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_deferrable.rb deleted file mode 100644 index 5f286a7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_deferrable.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'em_test_helper' - -class TestDeferrable < Test::Unit::TestCase - class Later - include EM::Deferrable - end - - def test_timeout_without_args - assert_nothing_raised do - EM.run { - df = Later.new - df.timeout(0) - df.errback { EM.stop } - EM.add_timer(0.01) { flunk "Deferrable was not timed out." } - } - end - end - - def test_timeout_with_args - args = nil - - EM.run { - df = Later.new - df.timeout(0, :timeout, :foo) - df.errback do |type, name| - args = [type, name] - EM.stop - end - - EM.add_timer(0.01) { flunk "Deferrable was not timed out." } - } - - assert_equal [:timeout, :foo], args - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_epoll.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_epoll.rb deleted file mode 100644 index 36f5609..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_epoll.rb +++ /dev/null @@ -1,142 +0,0 @@ -require 'em_test_helper' - - -class TestEpoll < Test::Unit::TestCase - - module TestEchoServer - def receive_data data - send_data data - close_connection_after_writing - end - end - - module TestEchoClient - def connection_completed - send_data "ABCDE" - $max += 1 - end - def receive_data data - raise "bad response" unless data == "ABCDE" - end - def unbind - $n -= 1 - EM.stop if $n == 0 - end - end - - - # We can set the rlimit/nofile of a process but we can only set it - # higher if we're running as root. - # On most systems, the default value is 1024. - def test_rlimit - omit_if(windows? || jruby?) - unless EM.set_descriptor_table_size >= 1024 - a = EM.set_descriptor_table_size - assert( a <= 1024 ) - a = EM.set_descriptor_table_size( 1024 ) - assert( a == 1024 ) - end - end - - # Run a high-volume version of this test by kicking the number of connections - # up past 512. (Each connection uses two sockets, a client and a server.) - # (Will require running the test as root) - # This test exercises TCP clients and servers. - # - # XXX this test causes all sort of weird issues on OSX (when run as part of the suite) - def _test_descriptors - EM.epoll - EM.set_descriptor_table_size 60000 - EM.run { - EM.start_server "127.0.0.1", 9800, TestEchoServer - $n = 0 - $max = 0 - 100.times { - EM.connect("127.0.0.1", 9800, TestEchoClient) {$n += 1} - } - } - assert_equal(0, $n) - assert_equal(100, $max) - end - - def setup - @port = next_port - end - - module TestDatagramServer - def receive_data dgm - $in = dgm - send_data "abcdefghij" - end - end - module TestDatagramClient - def initialize port - @port = port - end - - def post_init - send_datagram "1234567890", "127.0.0.1", @port - end - - def receive_data dgm - $out = dgm - EM.stop - end - end - - def test_datagrams - $in = $out = "" - EM.run { - EM.open_datagram_socket "127.0.0.1", @port, TestDatagramServer - EM.open_datagram_socket "127.0.0.1", 0, TestDatagramClient, @port - } - assert_equal( "1234567890", $in ) - assert_equal( "abcdefghij", $out ) - end - - # XXX this test fails randomly... - def _test_unix_domain - fn = "/tmp/xxx.chain" - EM.epoll - EM.set_descriptor_table_size 60000 - EM.run { - # The pure-Ruby version won't let us open the socket if the node already exists. - # Not sure, that actually may be correct and the compiled version is wrong. - # Pure Ruby also oddly won't let us make that many connections. This test used - # to run 100 times. Not sure where that lower connection-limit is coming from in - # pure Ruby. - # Let's not sweat the Unix-ness of the filename, since this test can't possibly - # work on Windows anyway. - # - File.unlink(fn) if File.exist?(fn) - EM.start_unix_domain_server fn, TestEchoServer - $n = 0 - $max = 0 - 50.times { - EM.connect_unix_domain(fn, TestEchoClient) {$n += 1} - } - EM::add_timer(1) { $stderr.puts("test_unix_domain timed out!"); EM::stop } - } - assert_equal(0, $n) - assert_equal(50, $max) - ensure - File.unlink(fn) if File.exist?(fn) - end - - def test_attach_detach - EM.epoll - EM.run { - EM.add_timer(0.01) { EM.stop } - - r, _ = IO.pipe - - # This tests a regression where detach in the same tick as attach crashes EM - EM.watch(r) do |connection| - connection.detach - end - } - - assert true - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_error_handler.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_error_handler.rb deleted file mode 100644 index 23c23f7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_error_handler.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'em_test_helper' - -class TestErrorHandler < Test::Unit::TestCase - def setup - @exception = Class.new(StandardError) - end - - def test_error_handler - error = nil - - EM.error_handler{ |e| - error = e - EM.error_handler(nil) - EM.stop - } - - assert_nothing_raised do - EM.run{ - EM.add_timer(0){ - raise @exception, 'test' - } - } - end - - assert_equal error.class, @exception - assert_equal error.message, 'test' - end - - def test_without_error_handler - assert_raise @exception do - EM.run{ - EM.add_timer(0){ - raise @exception, 'test' - } - } - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_exc.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_exc.rb deleted file mode 100644 index d9c860a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_exc.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'em_test_helper' - -class TestSomeExceptions < Test::Unit::TestCase - class DoomedConnectionError < StandardError - end - class DoomedConnection < EventMachine::Connection - def unbind - raise DoomedConnectionError - end - end - - # Read the commentary in EM#run. - # This test exercises the ensure block in #run that makes sure - # EM#release_machine gets called even if an exception is - # thrown within the user code. Without the ensured call to release_machine, - # the second call to EM#run will fail with a C++ exception - # because the machine wasn't cleaned up properly. - - def test_a - assert_raises(RuntimeError) { - EM.run { - raise "some exception" - } - } - end - - def test_b - assert_raises(RuntimeError) { - EM.run { - raise "some exception" - } - } - end - - def test_exception_on_unbind - assert_raises(DoomedConnectionError) { - EM.run { - EM.connect("localhost", 8888, DoomedConnection) - } - } - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_file_watch.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_file_watch.rb deleted file mode 100644 index 5602071..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_file_watch.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'em_test_helper' -require 'tempfile' - -class TestFileWatch < Test::Unit::TestCase - if windows? - def test_watch_file_raises_unsupported_error - assert_raises(EM::Unsupported) do - EM.run do - file = Tempfile.new("fake_file") - EM.watch_file(file.path) - end - end - end - elsif EM.respond_to? :watch_filename - module FileWatcher - def file_modified - $modified = true - end - def file_deleted - $deleted = true - end - def unbind - $unbind = true - EM.stop - end - end - - def setup - EM.kqueue = true if EM.kqueue? - end - - def teardown - EM.kqueue = false if EM.kqueue? - end - - def test_events - omit_if(solaris?) - EM.run{ - file = Tempfile.new('em-watch') - $tmp_path = file.path - - # watch it - watch = EM.watch_file(file.path, FileWatcher) - $path = watch.path - - # modify it - File.open(file.path, 'w'){ |f| f.puts 'hi' } - - # delete it - EM.add_timer(0.01){ file.close; file.delete } - } - - assert_equal($path, $tmp_path) - assert($modified) - assert($deleted) - assert($unbind) - end - - # Refer: https://github.com/eventmachine/eventmachine/issues/512 - def test_invalid_signature - # This works fine with kqueue, only fails with linux inotify. - omit_if(EM.kqueue?) - - EM.run { - file = Tempfile.new('foo') - - w1 = EventMachine.watch_file(file.path) - w2 = EventMachine.watch_file(file.path) - - assert_raise EventMachine::InvalidSignature do - w2.stop_watching - end - - EM.stop - } - end - else - warn "EM.watch_file not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_watch_file_unsupported - assert true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_fork.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_fork.rb deleted file mode 100644 index 8b15bb5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_fork.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'em_test_helper' - -class TestFork < Test::Unit::TestCase - - def test_fork_safe - omit_if(jruby?) - omit_if(windows?) - - fork_pid = nil - read, write = IO.pipe - EM.run do - fork_pid = fork do - write.puts "forked" - EM.run do - EM.next_tick do - write.puts "EM ran" - EM.stop - end - end - end - EM.stop - end - - sleep 0.1 - begin - Timeout::timeout 1 do - assert_equal "forked\n", read.readline - assert_equal "EM ran\n", read.readline - end - rescue Timeout::Error - Process.kill 'TERM', fork_pid - flunk "Timeout waiting for next_tick in new fork reactor" - end - ensure - read.close rescue nil - write.close rescue nil - end - - def test_fork_reactor - omit_if(jruby?) - omit_if(windows?) - - fork_pid = nil - read, write = IO.pipe - EM.run do - EM.defer do - write.puts Process.pid - EM.defer do - EM.stop - end - end - fork_pid = EM.fork_reactor do - EM.defer do - write.puts Process.pid - EM.stop - end - end - end - - sleep 0.1 - begin - Timeout::timeout 1 do - assert_equal Process.pid.to_s, read.readline.chomp - assert_equal fork_pid.to_s, read.readline.chomp - end - rescue Timeout::Error - Process.kill 'TERM', fork_pid - flunk "Timeout waiting for deferred block in fork_reactor" - end - ensure - read.close rescue nil - write.close rescue nil - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_futures.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_futures.rb deleted file mode 100644 index b494856..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_futures.rb +++ /dev/null @@ -1,170 +0,0 @@ -require 'em_test_helper' - -class TestFutures < Test::Unit::TestCase - - def setup - end - - def teardown - end - - def test_future - assert_equal(100, EM::Deferrable.future(100) ) - - p1 = proc { 100 + 1 } - assert_equal(101, EM::Deferrable.future(p1) ) - end - - class MyFuture - include EM::Deferrable - def initialize *args - super - set_deferred_status :succeeded, 40 - end - end - - class MyErrorFuture - include EM::Deferrable - def initialize *args - super - set_deferred_status :failed, 41 - end - end - - - def test_future_1 - # Call future with one additional argument and it will be treated as a callback. - def my_future - MyFuture.new - end - - value = nil - EM::Deferrable.future my_future, proc {|v| value=v} - assert_equal( 40, value ) - end - - - def test_future_2 - # Call future with two additional arguments and they will be treated as a callback - # and an errback. - value = nil - EM::Deferrable.future MyErrorFuture.new, nil, proc {|v| value=v} - assert_equal( 41, value ) - end - - - def test_future_3 - # Call future with no additional arguments but with a block, and the block will be - # treated as a callback. - value = nil - EM::Deferrable.future MyFuture.new do |v| - value=v - end - assert_equal( 40, value ) - end - - - class RecursiveCallback - include EM::Deferrable - end - - # A Deferrable callback can call #set_deferred_status to change the values - # passed to subsequent callbacks. - # - def test_recursive_callbacks - n = 0 # counter assures that all the tests actually run. - rc = RecursiveCallback.new - rc.callback {|a| - assert_equal(100, a) - n += 1 - rc.set_deferred_status :succeeded, 101, 101 - } - rc.callback {|a,b| - assert_equal(101, a) - assert_equal(101, b) - n += 1 - rc.set_deferred_status :succeeded, 102, 102, 102 - } - rc.callback {|a,b,c| - assert_equal(102, a) - assert_equal(102, b) - assert_equal(102, c) - n += 1 - } - rc.set_deferred_status :succeeded, 100 - assert_equal(3, n) - end - - def test_syntactic_sugar - rc = RecursiveCallback.new - rc.set_deferred_success 100 - rc.set_deferred_failure 200 - end - - # It doesn't raise an error to set deferred status more than once. - # In fact, this is a desired and useful idiom when it happens INSIDE - # a callback or errback. - # However, it's less useful otherwise, and in fact would generally be - # indicative of a programming error. However, we would like to be resistant - # to such errors. So whenever we set deferred status, we also clear BOTH - # stacks of handlers. - # - def test_double_calls - s = 0 - e = 0 - - d = EM::DefaultDeferrable.new - d.callback {s += 1} - d.errback {e += 1} - - d.succeed # We expect the callback to be called, and the errback to be DISCARDED. - d.fail # Presumably an error. We expect the errback NOT to be called. - d.succeed # We expect the callback to have been discarded and NOT to be called again. - - assert_equal(1, s) - assert_equal(0, e) - end - - # Adding a callback to a Deferrable that is already in a success state executes the callback - # immediately. The same applies to a an errback added to an already-failed Deferrable. - # HOWEVER, we expect NOT to be able to add errbacks to succeeded Deferrables, or callbacks - # to failed ones. - # - # We illustrate this with a rather contrived test. The test calls #fail after #succeed, - # which ordinarily would not happen in a real program. - # - # What we're NOT attempting to specify is what happens if a Deferrable is succeeded and then - # failed (or vice-versa). Should we then be able to add callbacks/errbacks of the appropriate - # type for immediate execution? For now at least, the official answer is "don't do that." - # - def test_delayed_callbacks - s1 = 0 - s2 = 0 - e = 0 - - d = EM::DefaultDeferrable.new - d.callback {s1 += 1} - - d.succeed # Triggers and discards the callback. - - d.callback {s2 += 1} # This callback is executed immediately and discarded. - - d.errback {e += 1} # This errback should be DISCARDED and never execute. - d.fail # To prove it, fail and assert e is 0 - - assert_equal( [1,1], [s1,s2] ) - assert_equal( 0, e ) - end - - def test_timeout - n = 0 - EM.run { - d = EM::DefaultDeferrable.new - d.callback {n = 1; EM.stop} - d.errback {n = 2; EM.stop} - d.timeout(0.01) - } - assert_equal( 2, n ) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_handler_check.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_handler_check.rb deleted file mode 100644 index c417694..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_handler_check.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'em_test_helper' - -class TestHandlerCheck < Test::Unit::TestCase - - class Foo < EM::Connection; end; - module TestModule; end; - - def test_with_correct_class - assert_nothing_raised do - EM.run { - EM.connect("127.0.0.1", 80, Foo) - EM.stop_event_loop - } - end - end - - def test_with_incorrect_class - assert_raise(ArgumentError) do - EM.run { - EM.connect("127.0.0.1", 80, String) - EM.stop_event_loop - } - end - end - - def test_with_module - assert_nothing_raised do - EM.run { - EM.connect("127.0.0.1", 80, TestModule) - EM.stop_event_loop - } - end - end - -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_hc.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_hc.rb deleted file mode 100644 index 28e32c9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_hc.rb +++ /dev/null @@ -1,155 +0,0 @@ -require 'em_test_helper' - -class TestHeaderAndContentProtocol < Test::Unit::TestCase - - class SimpleTest < EM::P::HeaderAndContentProtocol - attr_reader :first_header, :my_headers, :request - - def receive_first_header_line hdr - @first_header ||= [] - @first_header << hdr - end - def receive_headers hdrs - @my_headers ||= [] - @my_headers << hdrs - end - def receive_request hdrs, content - @request ||= [] - @request << [hdrs, content] - end - end - - class StopOnUnbind < EM::Connection - def unbind - EM.add_timer(0.01) { EM.stop } - end - end - - def setup - @port = next_port - end - - def test_no_content - the_connection = nil - EM.run { - EM.start_server( "127.0.0.1", @port, SimpleTest ) do |conn| - the_connection = conn - end - setup_timeout - - EM.connect "127.0.0.1", @port, StopOnUnbind do |c| - c.send_data [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join - c.close_connection_after_writing - end - } - assert_equal( ["aaa"], the_connection.first_header ) - assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers ) - assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request ) - end - - def test_content - the_connection = nil - content = "A" * 50 - headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] - EM.run { - EM.start_server( "127.0.0.1", @port, SimpleTest ) do |conn| - the_connection = conn - end - setup_timeout - - EM.connect "127.0.0.1", @port, StopOnUnbind do |c| - headers.each { |h| c.send_data "#{h}\r\n" } - c.send_data "\n" - c.send_data content - c.close_connection_after_writing - end - } - assert_equal( ["aaa"], the_connection.first_header ) - assert_equal( [headers], the_connection.my_headers ) - assert_equal( [[headers, content]], the_connection.request ) - end - - def test_several_requests - the_connection = nil - content = "A" * 50 - headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"] - EM.run { - EM.start_server( "127.0.0.1", @port, SimpleTest ) do |conn| - the_connection = conn - end - setup_timeout - - EM.connect( "127.0.0.1", @port, StopOnUnbind ) do |c| - 5.times do - headers.each { |h| c.send_data "#{h}\r\n" } - c.send_data "\n" - c.send_data content - end - c.close_connection_after_writing - end - } - assert_equal( ["aaa"] * 5, the_connection.first_header ) - assert_equal( [headers] * 5, the_connection.my_headers ) - assert_equal( [[headers, content]] * 5, the_connection.request ) - end - - - # def x_test_multiple_content_length_headers - # # This is supposed to throw a RuntimeError but it throws a C++ exception instead. - # the_connection = nil - # content = "A" * 50 - # headers = ["aaa", "bbb", ["Content-length: #{content.length}"]*2, "ccc"].flatten - # EM.run { - # EM.start_server( "127.0.0.1", @port, SimpleTest ) do |conn| - # the_connection = conn - # end - # EM.add_timer(4) {raise "test timed out"} - # test_proc = proc { - # t = TCPSocket.new "127.0.0.1", @port - # headers.each {|h| t.write "#{h}\r\n" } - # t.write "\n" - # t.write content - # t.close - # } - # EM.defer test_proc, proc { - # EM.stop - # } - # } - # end - - def test_interpret_headers - the_connection = nil - content = "A" * 50 - headers = [ - "GET / HTTP/1.0", - "Accept: aaa", - "User-Agent: bbb", - "Host: ccc", - "x-tempest-header:ddd" - ] - - EM.run { - EM.start_server( "127.0.0.1", @port, SimpleTest ) do |conn| - the_connection = conn - end - setup_timeout - - EM.connect( "127.0.0.1", @port, StopOnUnbind ) do |c| - headers.each { |h| c.send_data "#{h}\r\n" } - c.send_data "\n" - c.send_data content - c.close_connection_after_writing - end - } - - hsh = the_connection.headers_2_hash( the_connection.my_headers.shift ) - expect = { - :accept => "aaa", - :user_agent => "bbb", - :host => "ccc", - :x_tempest_header => "ddd" - } - assert_equal(expect, hsh) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient.rb deleted file mode 100644 index 572a802..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'em_test_helper' - -class TestHttpClient < Test::Unit::TestCase - - def setup - @port = next_port - end - - #------------------------------------- - - def test_http_client - ok = false - EM.run { - c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 } - c.callback { - ok = true - c.close_connection - EM.stop - } - c.errback {EM.stop} # necessary, otherwise a failure blocks the test suite forever. - } - assert ok - end - - #------------------------------------- - - def test_http_client_1 - ok = false - EM.run { - c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 } - c.callback { - ok = true - c.close_connection - EM.stop - } - c.errback {EM.stop} - } - assert ok - end - - #------------------------------------- - - def test_http_client_2 - ok = false - EM.run { - c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 } - c.callback { - ok = true - c.close_connection - EM.stop - } - c.errback {EM.stop} - } - assert ok - end - - - #----------------------------------------- - - # Test a server that returns a page with a zero content-length. - # This caused an early version of the HTTP client not to generate a response, - # causing this test to hang. Observe, there was no problem with responses - # lacking a content-length, just when the content-length was zero. - # - class EmptyContent < EM::Connection - def initialize *args - super - end - def receive_data data - send_data "HTTP/1.0 404 ...\r\nContent-length: 0\r\n\r\n" - close_connection_after_writing - end - end - - def test_http_empty_content - ok = false - EM.run { - EM.start_server "127.0.0.1", @port, EmptyContent - c = silent { EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => @port } - c.callback { - ok = true - c.close_connection - EM.stop - } - } - assert ok - end - - - #--------------------------------------- - - class PostContent < EM::P::LineAndTextProtocol - def initialize *args - super - @lines = [] - end - def receive_line line - if line.length > 0 - @lines << line - else - process_headers - end - end - def receive_binary_data data - @post_content = data - send_response - end - def process_headers - if @lines.first =~ /\APOST ([^\s]+) HTTP\/1.1\Z/ - @uri = $1.dup - else - raise "bad request" - end - - @lines.each {|line| - if line =~ /\AContent-length:\s*(\d+)\Z/i - @content_length = $1.dup.to_i - elsif line =~ /\AContent-type:\s*(\d+)\Z/i - @content_type = $1.dup - end - } - - raise "invalid content length" unless @content_length - set_binary_mode @content_length - end - def send_response - send_data "HTTP/1.1 200 ...\r\nConnection: close\r\nContent-length: 10\r\nContent-type: text/html\r\n\r\n0123456789" - close_connection_after_writing - end - end - - # TODO, this is WRONG. The handler is asserting an HTTP 1.1 request, but the client - # is sending a 1.0 request. Gotta fix the client - def test_post - response = nil - EM.run { - EM.start_server '127.0.0.1', @port, PostContent - setup_timeout(2) - c = silent { EM::P::HttpClient.request( - :host => '127.0.0.1', - :port => @port, - :method => :post, - :request => "/aaa", - :content => "XYZ", - :content_type => "text/plain" - )} - c.callback {|r| - response = r - EM.stop - } - } - - assert_equal( 200, response[:status] ) - assert_equal( "0123456789", response[:content] ) - end - - - # TODO, need a more intelligent cookie tester. - # In fact, this whole test-harness needs a beefier server implementation. - def test_cookie - ok = false - EM.run { - c = silent { EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb" } - c.callback { - ok = true - c.close_connection - EM.stop - } - c.errback {EM.stop} - } - assert ok - end - - # We can tell the client to send an HTTP/1.0 request (default is 1.1). - # This is useful for suppressing chunked responses until those are working. - def test_version_1_0 - ok = false - EM.run { - c = silent { EM::P::HttpClient.request( - :host => "www.google.com", - :port => 80, - :version => "1.0" - )} - c.callback { - ok = true - c.close_connection - EM.stop - } - c.errback {EM.stop} - } - assert ok - end - - #----------------------------------------- - - # Test a server that returns chunked encoding - # - class ChunkedEncodingContent < EventMachine::Connection - def initialize *args - super - end - def receive_data data - send_data ["HTTP/1.1 200 OK", - "Server: nginx/0.7.67", - "Date: Sat, 23 Oct 2010 16:41:32 GMT", - "Content-Type: application/json", - "Transfer-Encoding: chunked", - "Connection: keep-alive", - "", - "1800", - "chunk1" * 1024, - "5a", - "chunk2" * 15, - "0", - ""].join("\r\n") - close_connection_after_writing - end - end - - def test_http_chunked_encoding_content - ok = false - EM.run { - EM.start_server "127.0.0.1", @port, ChunkedEncodingContent - c = silent { EM::P::HttpClient.send :request, :host => "127.0.0.1", :port => @port } - c.callback { |result| - if result[:content] == "chunk1" * 1024 + "chunk2" * 15 - ok = true - end - c.close_connection - EM.stop - } - } - assert ok - end - -end - - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient2.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient2.rb deleted file mode 100644 index a00fcbc..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_httpclient2.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'em_test_helper' - -class TestHttpClient2 < Test::Unit::TestCase - class TestServer < EM::Connection - end - - def setup - @port = next_port - end - - # #connect returns an object which has made a connection to an HTTP server - # and exposes methods for making HTTP requests on that connection. - # #connect can take either a pair of parameters (a host and a port), - # or a single parameter which is a Hash. - # - def test_connect - EM.run { - setup_timeout(1) - EM.start_server '127.0.0.1', @port, TestServer - silent do - EM::P::HttpClient2.connect '127.0.0.1', @port - EM::P::HttpClient2.connect( :host=>'127.0.0.1', :port=>@port ) - end - EM.stop - } - end - - def test_bad_port - EM.run { - setup_timeout(1) - EM.start_server '127.0.0.1', @port, TestServer - assert_raises( ArgumentError ) { - silent { EM::P::HttpClient2.connect '127.0.0.1', "xxx" } - } - EM.stop - } - end - - def test_bad_server - err = nil - EM.run { - setup_timeout(1) - http = silent { EM::P::HttpClient2.connect '127.0.0.1', 9999 } - d = http.get "/" - d.errback { err = true; d.internal_error; EM.stop } - } - assert(err) - end - - def test_get - content = nil - EM.run { - setup_timeout(1) - http = silent { EM::P::HttpClient2.connect :host => "google.com", :port => 80, :version => '1.0' } - d = http.get "/" - d.callback { - content = d.content - EM.stop - } - } - assert(content) - end - - # Not a pipelined request because we wait for one response before we request the next. - # XXX this test is broken because it sends the second request to the first connection - # XXX right before the connection closes - def _test_get_multiple - content = nil - EM.run { - setup_timeout(1) - http = silent { EM::P::HttpClient2.connect "google.com", :version => '1.0' } - d = http.get "/" - d.callback { - e = http.get "/" - e.callback { - content = e.content - EM.stop - } - } - } - assert(content) - end - - def test_get_pipeline - headers, headers2 = nil, nil - EM.run { - setup_timeout(1) - http = silent { EM::P::HttpClient2.connect "google.com", 80 } - d = http.get("/") - d.callback { - headers = d.headers - } - e = http.get("/") - e.callback { - headers2 = e.headers - } - EM.tick_loop { EM.stop if headers && headers2 } - EM.add_timer(1) { EM.stop } - } - assert(headers) - assert(headers2) - end - - def test_authheader - EM.run { - setup_timeout(1) - EM.start_server '127.0.0.1', @port, TestServer - http = silent { EM::P::HttpClient2.connect '127.0.0.1', 18842 } - d = http.get :url=>"/", :authorization=>"Basic xxx" - d.callback {EM.stop} - d.errback {EM.stop} - } - end - - def test_https_get - omit_unless(EM.ssl?) - d = nil - EM.run { - setup_timeout(1) - http = silent { EM::P::HttpClient2.connect :host => 'www.google.com', :port => 443, :ssl => true, :version => '1.0' } - d = http.get "/" - d.callback {EM.stop} - d.errback {EM.stop} - } - assert_equal(200, d.status) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_idle_connection.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_idle_connection.rb deleted file mode 100644 index bfc57cd..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_idle_connection.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'em_test_helper' - -class TestIdleConnection < Test::Unit::TestCase - def setup - @port = next_port - end - - def test_idle_time - omit_if(!EM.respond_to?(:get_idle_time)) - - a, b = nil, nil - EM.run do - EM.start_server '127.0.0.1', @port, Module.new - conn = EM.connect '127.0.0.1', @port - EM.add_timer(0.3) do - a = conn.get_idle_time - conn.send_data 'a' - EM.next_tick do - EM.next_tick do - b = conn.get_idle_time - conn.close_connection - EM.stop - end - end - end - end - - assert_in_delta 0.3, a, 0.1 - assert_in_delta 0, b, 0.1 - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_inactivity_timeout.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_inactivity_timeout.rb deleted file mode 100644 index 15e39a2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_inactivity_timeout.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'em_test_helper' - -class TestInactivityTimeout < Test::Unit::TestCase - - if EM.respond_to? :get_comm_inactivity_timeout - def test_default - EM.run { - c = EM.connect("127.0.0.1", 54321) - assert_equal 0.0, c.comm_inactivity_timeout - EM.stop - } - end - - def test_set_and_get - EM.run { - c = EM.connect("127.0.0.1", 54321) - c.comm_inactivity_timeout = 2.5 - assert_equal 2.5, c.comm_inactivity_timeout - EM.stop - } - end - - def test_for_real - start, finish = nil - - timeout_handler = Module.new do - define_method :unbind do - finish = Time.now - EM.stop - end - end - - EM.run { - setup_timeout - EM.heartbeat_interval = 0.01 - EM.start_server("127.0.0.1", 12345) - EM.add_timer(0.01) { - start = Time.now - c = EM.connect("127.0.0.1", 12345, timeout_handler) - c.comm_inactivity_timeout = 0.02 - } - } - - assert_in_delta(0.02, (finish - start), 0.02) - end - else - warn "EM.comm_inactivity_timeout not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_comm_inactivity_timeout_not_implemented - assert true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv4.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv4.rb deleted file mode 100644 index bd11bbf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv4.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'em_test_helper' - -class TestIPv4 < Test::Unit::TestCase - # Runs a TCP server in the local IPv4 address, connects to it and sends a specific data. - # Timeout in 2 seconds. - def test_ipv4_tcp_local_server - omit_if(!Test::Unit::TestCase.public_ipv4?) - - @@received_data = nil - @local_port = next_port - setup_timeout(2) - - EM.run do - EM::start_server(@@public_ipv4, @local_port) do |s| - def s.receive_data data - @@received_data = data - EM.stop - end - end - - EM::connect(@@public_ipv4, @local_port) do |c| - c.send_data "ipv4/tcp" - end - end - - assert_equal "ipv4/tcp", @@received_data - end - - # Runs a UDP server in the local IPv4 address, connects to it and sends a specific data. - # Timeout in 2 seconds. - def test_ipv4_udp_local_server - omit_if(!Test::Unit::TestCase.public_ipv4?) - - @@received_data = nil - @local_port = next_port - setup_timeout(2) - - EM.run do - EM::open_datagram_socket(@@public_ipv4, @local_port) do |s| - def s.receive_data data - @@received_data = data - EM.stop - end - end - - EM::open_datagram_socket(@@public_ipv4, next_port) do |c| - c.send_datagram "ipv4/udp", @@public_ipv4, @local_port - end - end - - assert_equal "ipv4/udp", @@received_data - end - - # Try to connect via TCP to an invalid IPv4. EM.connect should raise - # EM::ConnectionError. - def test_tcp_connect_to_invalid_ipv4 - omit_if(!Test::Unit::TestCase.public_ipv4?) - - invalid_ipv4 = "9.9:9" - - EM.run do - begin - error = nil - EM.connect(invalid_ipv4, 1234) - rescue => e - error = e - ensure - EM.stop - assert_equal EM::ConnectionError, (error && error.class) - end - end - end - - # Try to send a UDP datagram to an invalid IPv4. EM.send_datagram should raise - # EM::ConnectionError. - def test_udp_send_datagram_to_invalid_ipv4 - omit_if(!Test::Unit::TestCase.public_ipv4?) - - invalid_ipv4 = "9.9:9" - - EM.run do - begin - error = nil - EM.open_datagram_socket(@@public_ipv4, next_port) do |c| - c.send_datagram "hello", invalid_ipv4, 1234 - end - rescue => e - error = e - ensure - EM.stop - assert_equal EM::ConnectionError, (error && error.class) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv6.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv6.rb deleted file mode 100644 index b52fef1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ipv6.rb +++ /dev/null @@ -1,107 +0,0 @@ -require 'em_test_helper' - -class TestIPv6 < Test::Unit::TestCase - - if Test::Unit::TestCase.public_ipv6? - - # Runs a TCP server in the local IPv6 address, connects to it and sends a specific data. - # Timeout in 2 seconds. - def test_ipv6_tcp_local_server - @@received_data = nil - @local_port = next_port - setup_timeout(2) - - EM.run do - EM.start_server(@@public_ipv6, @local_port) do |s| - def s.receive_data data - @@received_data = data - EM.stop - end - end - - EM::connect(@@public_ipv6, @local_port) do |c| - def c.unbind(reason) - warn "unbind: #{reason.inspect}" if reason # XXX at least find out why it failed - end - c.send_data "ipv6/tcp" - end - end - - assert_equal "ipv6/tcp", @@received_data - end - - # Runs a UDP server in the local IPv6 address, connects to it and sends a specific data. - # Timeout in 2 seconds. - def test_ipv6_udp_local_server - @@received_data = nil - @local_port = next_port - @@remote_ip = nil - setup_timeout(2) - - EM.run do - EM.open_datagram_socket(@@public_ipv6, @local_port) do |s| - def s.receive_data data - _port, @@remote_ip = Socket.unpack_sockaddr_in(get_peername) - @@received_data = data - EM.stop - end - end - - EM.open_datagram_socket(@@public_ipv6, next_port) do |c| - c.send_datagram "ipv6/udp", @@public_ipv6, @local_port - end - end - assert_equal @@remote_ip, @@public_ipv6 - assert_equal "ipv6/udp", @@received_data - end - - # Try to connect via TCP to an invalid IPv6. EM.connect should raise - # EM::ConnectionError. - def test_tcp_connect_to_invalid_ipv6 - invalid_ipv6 = "1:A" - - EM.run do - begin - error = nil - EM.connect(invalid_ipv6, 1234) - rescue => e - error = e - ensure - EM.stop - assert_equal EM::ConnectionError, (error && error.class) - end - end - end - - # Try to send a UDP datagram to an invalid IPv6. EM.send_datagram should raise - # EM::ConnectionError. - def test_udp_send_datagram_to_invalid_ipv6 - invalid_ipv6 = "1:A" - - EM.run do - begin - error = nil - EM.open_datagram_socket(@@public_ipv6, next_port) do |c| - c.send_datagram "hello", invalid_ipv6, 1234 - end - rescue => e - error = e - ensure - EM.stop - assert_equal EM::ConnectionError, (error && error.class) - end - end - end - - - else - warn "no IPv6 in this host, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests. - def test_ipv6_unavailable - assert true - end - - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_iterator.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_iterator.rb deleted file mode 100644 index 6ec4e46..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_iterator.rb +++ /dev/null @@ -1,118 +0,0 @@ -require 'em_test_helper' - -class TestIterator < Test::Unit::TestCase - - # By default, format the time with tenths-of-seconds. - # Some tests should ask for extra decimal places to ensure - # that delays between iterations will receive a changed time. - def get_time(n=1) - time = EM.current_time - time.strftime('%H:%M:%S.') + time.tv_usec.to_s[0, n] - end - - def test_default_concurrency - items = {} - list = 1..10 - EM.run { - EM::Iterator.new(list).each( proc {|num,iter| - time = get_time(3) - items[time] ||= [] - items[time] << num - EM::Timer.new(0.02) {iter.next} - }, proc {EM.stop}) - } - assert_equal(10, items.keys.size) - assert_equal(list.to_a.sort, items.values.flatten.sort) - end - - def test_default_concurrency_with_a_proc - items = {} - list = (1..10).to_a - original_list = list.dup - EM.run { - EM::Iterator.new(proc{list.pop || EM::Iterator::Stop}).each( proc {|num,iter| - time = get_time(3) - items[time] ||= [] - items[time] << num - EM::Timer.new(0.02) {iter.next} - }, proc {EM.stop}) - } - assert_equal(10, items.keys.size) - assert_equal(original_list.to_a.sort, items.values.flatten.sort) - end - - def test_concurrency_bigger_than_list_size - items = {} - list = [1,2,3] - EM.run { - EM::Iterator.new(list,10).each(proc {|num,iter| - time = get_time - items[time] ||= [] - items[time] << num - EM::Timer.new(1) {iter.next} - }, proc {EM.stop}) - } - assert_equal(1, items.keys.size) - assert_equal(list.to_a.sort, items.values.flatten.sort) - end - - def test_changing_concurrency_affects_active_iteration - items = {} - list = 1..25 - seen = 0 - EM.run { - i = EM::Iterator.new(list,1) - i.each(proc {|num,iter| - time = get_time - items[time] ||= [] - items[time] << num - if (seen += 1) == 5 - # The first 5 items will be distinct times - # The next 20 items will happen in 2 bursts - i.concurrency = 10 - end - EM::Timer.new(0.2) {iter.next} - }, proc {EM.stop}) - } - assert_in_delta(7, items.keys.size, 1) - assert_equal(list.to_a.sort, items.values.flatten.sort) - end - - def test_map - list = 100..150 - EM.run { - EM::Iterator.new(list).map(proc{ |num,iter| - EM.add_timer(0.01){ iter.return(num) } - }, proc{ |results| - assert_equal(list.to_a.size, results.size) - EM.stop - }) - } - end - - def test_inject - omit_if(windows?) - - list = %w[ pwd uptime uname date ] - EM.run { - EM::Iterator.new(list, 2).inject({}, proc{ |hash,cmd,iter| - EM.system(cmd){ |output,status| - hash[cmd] = status.exitstatus == 0 ? output.strip : nil - iter.return(hash) - } - }, proc{ |results| - assert_equal(results.keys.sort, list.sort) - EM.stop - }) - } - end - - def test_concurrency_is_0 - EM.run { - assert_raise ArgumentError do - EM::Iterator.new(1..5,0) - end - EM.stop - } - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_kb.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_kb.rb deleted file mode 100644 index 9c31f5f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_kb.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'em_test_helper' - -class TestKeyboardEvents < Test::Unit::TestCase - - module KbHandler - include EM::Protocols::LineText2 - def receive_line d - EM::stop if d == "STOP" - end - end - - # This test doesn't actually do anything useful but is here to - # illustrate the usage. If you removed the timer and ran this test - # by itself on a console, and then typed into the console, it would - # work. - # I don't know how to get the test harness to simulate actual keystrokes. - # When someone figures that out, then we can make this a real test. - # - def test_kb - omit_if(jruby?) - omit_if(!$stdout.tty?) # don't run the test unless it stands a chance of validity. - EM.run do - EM.open_keyboard KbHandler - EM::Timer.new(1) { EM.stop } - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_line_protocol.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_line_protocol.rb deleted file mode 100644 index 2067a72..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_line_protocol.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'em_test_helper' - -class TestLineProtocol < Test::Unit::TestCase - class LineProtocolTestClass - include EM::Protocols::LineProtocol - - def lines - @lines ||= [] - end - - def receive_line(line) - lines << line - end - end - - def setup - @proto = LineProtocolTestClass.new - end - - def test_simple_split_line - @proto.receive_data("this is") - assert_equal([], @proto.lines) - - @proto.receive_data(" a test\n") - assert_equal(["this is a test"], @proto.lines) - end - - def test_simple_lines - @proto.receive_data("aaa\nbbb\r\nccc\nddd") - assert_equal(%w(aaa bbb ccc), @proto.lines) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp.rb deleted file mode 100644 index 06c2685..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp.rb +++ /dev/null @@ -1,155 +0,0 @@ -require 'em_test_helper' - -class TestLineAndTextProtocol < Test::Unit::TestCase - - class TLP_LineBuffer < EM::P::LineAndTextProtocol - attr_reader :line_buffer - - def initialize - super - @line_buffer = [] - end - - def receive_line line - @line_buffer << line - end - end - - module StopClient - def set_receive_data(&blk) - @rdb = blk - end - - def receive_data data - @rdb.call(data) if @rdb - end - - def unbind - EM.add_timer(0.1) { EM.stop } - end - end - - def setup - @port = next_port - end - - def test_simple_lines - conn = nil - EM.run { - EM.start_server( "127.0.0.1", @port, TLP_LineBuffer ) do |c| - conn = c - end - setup_timeout - - EM.connect "127.0.0.1", @port, StopClient do |c| - c.send_data "aaa\nbbb\r\nccc\n" - c.close_connection_after_writing - end - } - assert_equal( %w(aaa bbb ccc), conn.line_buffer) - end - - #-------------------------------------------------------------------- - - class TLP_ErrorMessage < EM::P::LineAndTextProtocol - attr_reader :error_message - - def initialize - super - @error_message = [] - end - - def receive_line text - raise - end - - def receive_error text - @error_message << text - end - end - - def test_overlength_lines - conn = nil - EM.run { - EM.start_server( "127.0.0.1", @port, TLP_ErrorMessage ) do |c| - conn = c - end - setup_timeout - EM.connect "127.0.0.1", @port, StopClient do |c| - c.send_data "a" * (16*1024 + 1) - c.send_data "\n" - c.close_connection_after_writing - end - - } - assert_equal( ["overlength line"], conn.error_message ) - end - - - #-------------------------------------------------------------------- - - class LineAndTextTest < EM::P::LineAndTextProtocol - def receive_line line - if line =~ /content-length:\s*(\d+)/i - @content_length = $1.to_i - elsif line.length == 0 - set_binary_mode @content_length - end - end - def receive_binary_data text - send_data "received #{text.length} bytes" - close_connection_after_writing - end - end - - def test_lines_and_text - output = '' - EM.run { - EM.start_server( "127.0.0.1", @port, LineAndTextTest ) - setup_timeout - - EM.connect "127.0.0.1", @port, StopClient do |c| - c.set_receive_data { |data| output << data } - c.send_data "Content-length: 400\n" - c.send_data "\n" - c.send_data "A" * 400 - EM.add_timer(0.1) { c.close_connection_after_writing } - end - } - assert_equal( "received 400 bytes", output ) - end - - #-------------------------------------------------------------------- - - - class BinaryTextTest < EM::P::LineAndTextProtocol - def receive_line line - if line =~ /content-length:\s*(\d+)/i - set_binary_mode $1.to_i - else - raise "protocol error" - end - end - def receive_binary_data text - send_data "received #{text.length} bytes" - close_connection_after_writing - end - end - - def test_binary_text - output = '' - EM.run { - EM.start_server( "127.0.0.1", @port, BinaryTextTest ) - setup_timeout - - EM.connect "127.0.0.1", @port, StopClient do |c| - c.set_receive_data { |data| output << data } - c.send_data "Content-length: 10000\n" - c.send_data "A" * 10000 - EM.add_timer(0.1) { c.close_connection_after_writing } - end - } - assert_equal( "received 10000 bytes", output ) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp2.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp2.rb deleted file mode 100644 index 220fcbe..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ltp2.rb +++ /dev/null @@ -1,332 +0,0 @@ -require 'em_test_helper' - -# TODO!!! Need tests for overlength headers and text bodies. - -class TestLineText2 < Test::Unit::TestCase - - # Run each of these tests two ways: passing in the whole test-dataset in one chunk, - # and passing it in one character at a time. - - class Basic - include EM::Protocols::LineText2 - attr_reader :lines - def receive_line line - (@lines ||= []) << line - end - end - def test_basic - testdata = "Line 1\nLine 2\r\nLine 3\n" - - a = Basic.new - a.receive_data testdata - assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines ) - - a = Basic.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines ) - end - - # The basic test above shows that extra newlines are chomped - # This test shows that newlines are preserved if the delimiter isn't \n - class PreserveNewlines - include EM::Protocols::LineText2 - attr_reader :lines - def initialize *args - super - @delim = "|" - set_delimiter @delim - end - def receive_line line - (@lines ||= []) << line - end - end - def test_preserve_newlines - a = PreserveNewlines.new - a.receive_data "aaa|bbb|ccc|\n|\r\n| \t ||" - assert_equal( ["aaa", "bbb", "ccc", "\n", "\r\n", " \t ", ""], a.lines ) - end - - class ChangeDelimiter - include EM::Protocols::LineText2 - attr_reader :lines - def initialize *args - super - @delim = "A" - set_delimiter @delim - end - def receive_line line - (@lines ||= []) << line - set_delimiter( @delim.succ! ) - end - end - - def test_change_delimiter - testdata = %Q(LineaALinebBLinecCLinedD) - - a = ChangeDelimiter.new - a.receive_data testdata - assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines ) - - a = ChangeDelimiter.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines ) - end - - class RegexDelimiter - include EM::Protocols::LineText2 - attr_reader :lines - def initialize *args - super - @delim = /[A-D]/ - set_delimiter @delim - end - def receive_line line - (@lines ||= []) << line - end - end - - def test_regex_delimiter - testdata = %Q(LineaALinebBLinecCLinedD) - - a = RegexDelimiter.new - a.receive_data testdata - assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines ) - - a = RegexDelimiter.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( ["Linea", "Lineb", "Linec", "Lined"], a.lines ) - end - - #-- - # Test two lines followed by an empty line, ten bytes of binary data, then - # two more lines. - - class Binary - include EM::Protocols::LineText2 - attr_reader :lines, :body - def initialize *args - super - @lines = [] - @body = nil - end - def receive_line ln - if ln == "" - set_text_mode 10 - else - @lines << ln - end - end - def receive_binary_data data - @body = data - end - end - - def test_binary - testdata = %Q(Line 1 -Line 2 - -0000000000Line 3 -Line 4 -) - - a = Binary.new - a.receive_data testdata - assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines) - assert_equal( "0000000000", a.body ) - - a = Binary.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( ["Line 1", "Line 2", "Line 3", "Line 4"], a.lines) - assert_equal( "0000000000", a.body ) - end - - - # Test unsized binary data. The expectation is that each chunk of it - # will be passed to us as it it received. - class UnsizedBinary - include EM::Protocols::LineText2 - attr_reader :n_calls, :body - def initialize *args - super - set_text_mode - end - def receive_binary_data data - @n_calls ||= 0 - @n_calls += 1 - (@body ||= "") << data - end - end - - def test_unsized_binary - testdata = "X\0" * 1000 - - a = UnsizedBinary.new - a.receive_data testdata - assert_equal( 1, a.n_calls ) - assert_equal( testdata, a.body ) - - a = UnsizedBinary.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( 2000, a.n_calls ) - assert_equal( testdata, a.body ) - end - - - # Test binary data with a "throw back" into line-mode. - class ThrowBack - include EM::Protocols::LineText2 - attr_reader :headers - def initialize *args - super - @headers = [] - @n_bytes = 0 - set_text_mode - end - def receive_binary_data data - wanted = 25 - @n_bytes - will_take = if data.length > wanted - data.length - wanted - else - data.length - end - @n_bytes += will_take - - if @n_bytes == 25 - set_line_mode( data[will_take..-1] ) - end - end - def receive_line ln - @headers << ln - end - end - def test_throw_back - testdata = "Line\n" * 10 - - a = ThrowBack.new - a.receive_data testdata - assert_equal( ["Line"] * 5, a.headers ) - - a = ThrowBack.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( ["Line"] * 5, a.headers ) - end - - # Test multi-character line delimiters. - # Also note that the test data has a "tail" with no delimiter, that will be - # discarded, but cf. the BinaryTail test. - # TODO!!! This test doesn't work in the byte-by-byte case. - class Multichar - include EM::Protocols::LineText2 - attr_reader :lines - def initialize *args - super - @lines = [] - set_delimiter "012" - end - def receive_line ln - @lines << ln - end - end - def test_multichar - testdata = "Line012Line012Line012Line" - - a = Multichar.new - a.receive_data testdata - assert_equal( ["Line"]*3, a.lines ) - - a = Multichar.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - # DOESN'T WORK in this case. Multi-character delimiters are broken. - #assert_equal( ["Line"]*3, a.lines ) - end - - # Test a binary "tail," when a sized binary transfer doesn't complete because - # of an unbind. We get a partial result. - class BinaryTail - include EM::Protocols::LineText2 - attr_reader :data - def initialize *args - super - @data = "" - set_text_mode 1000 - end - def receive_binary_data data - # we expect to get all the data in one chunk, even in the byte-by-byte case, - # because sized transfers by definition give us exactly one call to - # #receive_binary_data. - @data = data - end - end - def test_binary_tail - testdata = "0" * 500 - - a = BinaryTail.new - a.receive_data testdata - a.unbind - assert_equal( "0" * 500, a.data ) - - a = BinaryTail.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - a.unbind - assert_equal( "0" * 500, a.data ) - end - - - # Test an end-of-binary call. Arrange to receive binary data but don't bother counting it - # as it comes. Rely on getting receive_end_of_binary_data to signal the transition back to - # line mode. - # At the present time, this isn't strictly necessary with sized binary chunks because by - # definition we accumulate them and make exactly one call to receive_binary_data, but - # we may want to support a mode in the future that would break up large chunks into multiple - # calls. - class LazyBinary - include EM::Protocols::LineText2 - attr_reader :data, :end - def initialize *args - super - @data = "" - set_text_mode 1000 - end - def receive_binary_data data - # we expect to get all the data in one chunk, even in the byte-by-byte case, - # because sized transfers by definition give us exactly one call to - # #receive_binary_data. - @data = data - end - def receive_end_of_binary_data - @end = true - end - end - def test_receive_end_of_binary_data - testdata = "_" * 1000 - a = LazyBinary.new - testdata.length.times {|i| a.receive_data( testdata[i...i+1] ) } - assert_equal( "_" * 1000, a.data ) - assert( a.end ) - end - - - # This tests a bug fix in which calling set_text_mode failed when called - # inside receive_binary_data. - # - class BinaryPair - include EM::Protocols::LineText2 - attr_reader :sizes - def initialize *args - super - set_text_mode 1 - @sizes = [] - end - def receive_binary_data dt - @sizes << dt.length - set_text_mode( (dt.length == 1) ? 2 : 1 ) - end - end - def test_binary_pairs - test_data = "123" * 5 - a = BinaryPair.new - a.receive_data test_data - assert_equal( [1,2,1,2,1,2,1,2,1,2], a.sizes ) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_many_fds.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_many_fds.rb deleted file mode 100644 index 7c126dc..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_many_fds.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'em_test_helper' -require 'socket' - -class TestManyFDs < Test::Unit::TestCase - def setup - @port = next_port - end - - def test_connection_class_cache - mod = Module.new - a = nil - Process.setrlimit(Process::RLIMIT_NOFILE, 4096) rescue nil - EM.run { - EM.start_server '127.0.0.1', @port, mod - 1100.times do - a = EM.connect '127.0.0.1', @port, mod - assert_kind_of EM::Connection, a - end - EM.stop - } - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_next_tick.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_next_tick.rb deleted file mode 100644 index 9b60359..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_next_tick.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'em_test_helper' - -class TestNextTick < Test::Unit::TestCase - - def test_tick_arg - pr = proc {EM.stop} - EM.run { - EM.next_tick pr - } - assert true - end - - def test_tick_block - EM.run { - EM.next_tick {EM.stop} - } - assert true - end - - # This illustrates the solution to a long-standing problem. - # It's now possible to correctly nest calls to EM#run. - # See the source code commentary for EM#run for more info. - # - def test_run_run - EM.run { - EM.run { - EM.next_tick {EM.stop} - } - } - end - - def test_pre_run_queue - x = false - EM.next_tick { EM.stop; x = true } - EM.run { EM.add_timer(0.01) { EM.stop } } - assert x - end - - def test_cleanup_after_stop - x = true - EM.run{ - EM.next_tick{ - EM.stop - EM.next_tick{ x=false } - } - } - EM.run{ - EM.next_tick{ EM.stop } - } - assert x - end - - # We now support an additional parameter for EM#run. - # You can pass two procs to EM#run now. The first is executed as the normal - # run block. The second (if given) is scheduled for execution after the - # reactor loop completes. - # The reason for supporting this is subtle. There has always been an expectation - # that EM#run doesn't return until after the reactor loop ends. But now it's - # possible to nest calls to EM#run, which means that a nested call WILL - # RETURN. In order to write code that will run correctly either way, it's - # recommended to put any code which must execute after the reactor completes - # in the second parameter. - # - def test_run_run_2 - a = proc {EM.stop} - b = proc {assert true} - EM.run a, b - end - - - # This illustrates that EM#run returns when it's called nested. - # This isn't a feature, rather it's something to be wary of when writing code - # that must run correctly even if EM#run is called while a reactor is already - # running. - def test_run_run_3 - a = [] - EM.run { - EM.run proc {EM.stop}, proc {a << 2} - a << 1 - } - assert_equal( [1,2], a ) - end - - - def test_schedule_on_reactor_thread - x = false - EM.run do - EM.schedule { x = true } - EM.stop - end - assert x - end - - def test_schedule_from_thread - x = false - EM.run do - Thread.new { EM.schedule { x = true } }.join - assert !x - EM.next_tick { EM.stop } - end - assert x - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_object_protocol.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_object_protocol.rb deleted file mode 100644 index b1287ea..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_object_protocol.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'em_test_helper' - -class TestObjectProtocol < Test::Unit::TestCase - module Server - include EM::P::ObjectProtocol - def post_init - send_object :hello=>'world' - end - def receive_object obj - $server = obj - EM.stop - end - end - - module Client - include EM::P::ObjectProtocol - def receive_object obj - $client = obj - send_object 'you_said'=>obj - end - end - - def setup - @port = next_port - end - - def test_send_receive - EM.run{ - EM.start_server "127.0.0.1", @port, Server - EM.connect "127.0.0.1", @port, Client - } - - assert($client == {:hello=>'world'}) - assert($server == {'you_said'=>{:hello=>'world'}}) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pause.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pause.rb deleted file mode 100644 index d078a77..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pause.rb +++ /dev/null @@ -1,107 +0,0 @@ -require 'em_test_helper' - -class TestPause < Test::Unit::TestCase - if EM.respond_to? :pause_connection - def setup - @port = next_port - end - - def teardown - assert(!EM.reactor_running?) - end - - def test_pause_resume - server = nil - - s_rx = c_rx = 0 - - test_server = Module.new do - define_method :post_init do - server = self - end - - define_method :receive_data do |data| - s_rx += 1 - - EM.add_periodic_timer(0.01) { send_data 'hi' } - send_data 'hi' - - # pause server, now no outgoing data will actually - # be sent and no more incoming data will be received - pause - end - end - - test_client = Module.new do - def post_init - EM.add_periodic_timer(0.01) do - send_data 'hello' - end - end - - define_method :receive_data do |data| - c_rx += 1 - end - end - - EM.run do - EM.start_server "127.0.0.1", @port, test_server - EM.connect "127.0.0.1", @port, test_client - - EM.add_timer(0.05) do - assert_equal 1, s_rx - assert_equal 0, c_rx - assert server.paused? - - # resume server, queued outgoing and incoming data will be flushed - server.resume - - assert !server.paused? - - EM.add_timer(0.05) do - assert server.paused? - assert s_rx > 1 - assert c_rx > 0 - EM.stop - end - end - end - end - - def test_pause_in_receive_data - incoming = [] - - test_server = Module.new do - define_method(:receive_data) do |data| - incoming << data - pause - EM.add_timer(0.5){ close_connection } - end - define_method(:unbind) do - EM.stop - end - end - - buf = 'a' * 1024 - - EM.run do - EM.start_server "127.0.0.1", @port, test_server - cli = EM.connect "127.0.0.1", @port - 128.times do - cli.send_data buf - end - end - - assert_equal 1, incoming.size - assert incoming[0].bytesize > buf.bytesize - assert incoming[0].bytesize < buf.bytesize * 128 - end - else - warn "EM.pause_connection not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_pause_connection_not_implemented - assert true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pending_connect_timeout.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pending_connect_timeout.rb deleted file mode 100644 index a3f7fa4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pending_connect_timeout.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'em_test_helper' - -class TestPendingConnectTimeout < Test::Unit::TestCase - - if EM.respond_to? :get_pending_connect_timeout - def test_default - EM.run { - c = EM.connect("127.0.0.1", 54321) - assert_equal 20.0, c.pending_connect_timeout - EM.stop - } - end - - def test_set_and_get - EM.run { - c = EM.connect("127.0.0.1", 54321) - c.pending_connect_timeout = 2.5 - assert_equal 2.5, c.pending_connect_timeout - EM.stop - } - end - - def test_for_real - start, finish = nil - - timeout_handler = Module.new do - define_method :unbind do - finish = EM.current_time - EM.stop - end - end - - EM.run { - setup_timeout - EM.heartbeat_interval = 0.1 - start = EM.current_time - c = EM.connect('192.0.2.0', 54321, timeout_handler) - c.pending_connect_timeout = 0.2 - } - - assert_in_delta(0.2, (finish - start), 0.1) - end - else - warn "EM.pending_connect_timeout not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_pending_connect_timeout_not_implemented - assert true - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pool.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pool.rb deleted file mode 100644 index f859a9d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pool.rb +++ /dev/null @@ -1,196 +0,0 @@ -require 'em_test_helper' - -class TestPool < Test::Unit::TestCase - def pool - @pool ||= EM::Pool.new - end - - def go - EM.run { yield } - end - - def stop - EM.stop - end - - def deferrable - @deferrable ||= EM::DefaultDeferrable.new - end - - def test_supports_more_work_than_resources - ran = false - go do - pool.perform do - ran = true - deferrable - end - stop - end - assert_equal false, ran - go do - pool.add :resource - stop - end - assert_equal true, ran - end - - def test_reques_resources_on_error - pooled_res, pooled_res2 = nil - pool.add :res - go do - pool.perform do |res| - pooled_res = res - deferrable - end - stop - end - deferrable.fail - go do - pool.perform do |res| - pooled_res2 = res - deferrable - end - stop - end - assert_equal :res, pooled_res - assert_equal pooled_res, pooled_res2 - end - - def test_supports_custom_on_error - eres = nil - pool.on_error do |res| - eres = res - end - performs = [] - pool.add :res - go do - pool.perform do |res| - performs << res - deferrable - end - pool.perform do |res| - performs << res - deferrable - end - deferrable.fail - stop - end - assert_equal :res, eres - # manual requeues required when error handler is installed: - assert_equal 1, performs.size - assert_equal :res, performs.first - end - - def test_catches_successful_deferrables - performs = [] - pool.add :res - go do - pool.perform { |res| performs << res; deferrable } - pool.perform { |res| performs << res; deferrable } - stop - end - assert_equal [:res], performs - deferrable.succeed - go { stop } - assert_equal [:res, :res], performs - end - - def test_prunes_locked_and_removed_resources - performs = [] - pool.add :res - deferrable.succeed - go do - pool.perform { |res| performs << res; pool.remove res; deferrable } - pool.perform { |res| performs << res; pool.remove res; deferrable } - stop - end - assert_equal [:res], performs - end - - # Contents is only to be used for inspection of the pool! - def test_contents - pool.add :res - assert_equal [:res], pool.contents - # Assert that modifying the contents list does not affect the pools - # contents. - pool.contents.delete(:res) - assert_equal [:res], pool.contents - end - - def test_contents_when_perform_errors_and_on_error_is_not_set - pool.add :res - assert_equal [:res], pool.contents - - pool.perform do |r| - d = EM::DefaultDeferrable.new - d.fail - d - end - - EM.run { EM.next_tick { EM.stop } } - - assert_equal [:res], pool.contents - end - - def test_contents_when_perform_errors_and_on_error_is_set - pool.add :res - res = nil - pool.on_error do |r| - res = r - end - assert_equal [:res], pool.contents - - pool.perform do |r| - d = EM::DefaultDeferrable.new - d.fail 'foo' - d - end - - EM.run { EM.next_tick { EM.stop } } - - assert_equal :res, res - assert_equal [], pool.contents - end - - def test_num_waiting - pool.add :res - assert_equal 0, pool.num_waiting - pool.perform { |r| EM::DefaultDeferrable.new } - assert_equal 0, pool.num_waiting - 10.times { pool.perform { |r| EM::DefaultDeferrable.new } } - EM.run { EM.next_tick { EM.stop } } - assert_equal 10, pool.num_waiting - end - - def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource - pool.add :res - - res = nil - pool.on_error { |r| res = r } - pool.perform { raise 'boom' } - - assert_raises(RuntimeError) do - EM.run { EM.next_tick { EM.stop } } - end - - assert_equal [], pool.contents - assert_equal :res, res - end - - def test_removed_list_does_not_leak_on_errors - pool.add :res - - pool.on_error do |r| - # This is actually the wrong thing to do, and not required, but some users - # might do it. When they do, they would find that @removed would cause a - # slow leak. - pool.remove r - end - - pool.perform { d = EM::DefaultDeferrable.new; d.fail; d } - - EM.run { EM.next_tick { EM.stop } } - assert_equal [], pool.instance_variable_get(:@removed) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_process_watch.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_process_watch.rb deleted file mode 100644 index 6e0c49a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_process_watch.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'em_test_helper' - -if EM.kqueue? - class TestProcessWatch < Test::Unit::TestCase - module ParentProcessWatcher - def process_forked - $forked = true - end - end - - module ChildProcessWatcher - def process_exited - $exited = true - end - def unbind - $unbind = true - EM.stop - end - end - - def setup - EM.kqueue = true - end - - def teardown - EM.kqueue = false - end - - def test_events - omit_if(rbx?) - omit_if(jruby?) - EM.run{ - # watch ourselves for a fork notification - EM.watch_process(Process.pid, ParentProcessWatcher) - $fork_pid = fork{ sleep } - child = EM.watch_process($fork_pid, ChildProcessWatcher) - $pid = child.pid - - EM.add_timer(0.2){ - Process.kill('TERM', $fork_pid) - } - } - - assert_equal($pid, $fork_pid) - assert($forked) - assert($exited) - assert($unbind) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_processes.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_processes.rb deleted file mode 100644 index dd03cf0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_processes.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'em_test_helper' - -class TestProcesses < Test::Unit::TestCase - - if !windows? && !jruby? - - # EM::DeferrableChildProcess is a sugaring of a common use-case - # involving EM::popen. - # Call the #open method on EM::DeferrableChildProcess, passing - # a command-string. #open immediately returns an EM::Deferrable - # object. It also schedules the forking of a child process, which - # will execute the command passed to #open. - # When the forked child terminates, the Deferrable will be signalled - # and execute its callbacks, passing the data that the child process - # wrote to stdout. - # - def test_deferrable_child_process - ls = "" - EM.run { - d = EM::DeferrableChildProcess.open( "ls -ltr" ) - d.callback {|data_from_child| - ls = data_from_child - EM.stop - } - } - assert( ls.length > 0) - end - - def setup - $out = nil - $status = nil - end - - def test_em_system - EM.run{ - EM.system('ls'){ |out,status| $out, $status = out, status; EM.stop } - } - - assert( $out.length > 0 ) - assert_equal(0, $status.exitstatus) - assert_kind_of(Process::Status, $status) - end - - def test_em_system_pid - $pids = [] - - EM.run{ - $pids << EM.system('echo hi', proc{ |out,status|$pids << status.pid; EM.stop }) - } - - assert_equal $pids[0], $pids[1] - end - - def test_em_system_with_proc - EM.run{ - EM.system('ls', proc{ |out,status| $out, $status = out, status; EM.stop }) - } - - assert( $out.length > 0 ) - assert_equal(0, $status.exitstatus) - assert_kind_of(Process::Status, $status) - end - - def test_em_system_with_two_procs - EM.run{ - EM.system('sh', proc{ |process| - process.send_data("echo hello\n") - process.send_data("exit\n") - }, proc{ |out,status| - $out = out - $status = status - EM.stop - }) - } - - assert_equal("hello\n", $out) - end - - def test_em_system_cmd_arguments - EM.run{ - EM.system('echo', '1', '2', 'version', proc{ |process| - }, proc{ |out,status| - $out = out - $status = status - EM.stop - }) - } - - assert_match(/1 2 version/i, $out) - end - - def test_em_system_spaced_arguments - EM.run{ - EM.system('ruby', '-e', 'puts "hello"', proc{ |out,status| - $out = out - EM.stop - }) - } - - assert_equal("hello\n", $out) - end - - def test_em_popen_pause_resume - c_rx = 0 - - test_client = Module.new do - define_method :receive_data do |data| - c_rx += 1 - pause - EM.add_timer(0.5) { EM.stop } - end - end - - EM.run do - EM.popen('echo 1', test_client) - end - - assert_equal 1, c_rx - end - else - warn "EM.popen not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_popen_unsupported - assert true - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_proxy_connection.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_proxy_connection.rb deleted file mode 100644 index 11c0fb4..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_proxy_connection.rb +++ /dev/null @@ -1,180 +0,0 @@ -require 'em_test_helper' - -class TestProxyConnection < Test::Unit::TestCase - - if EM.respond_to?(:start_proxy) - module ProxyConnection - def initialize(client, request) - @client, @request = client, request - end - - def post_init - EM::enable_proxy(self, @client) - end - - def connection_completed - EM.next_tick { - send_data @request - } - end - - def proxy_target_unbound - $unbound_early = true - EM.stop - end - - def unbind - $proxied_bytes = self.get_proxied_bytes - @client.close_connection_after_writing - end - end - - module PartialProxyConnection - def initialize(client, request, length) - @client, @request, @length = client, request, length - end - - def post_init - EM::enable_proxy(self, @client, 0, @length) - end - - def receive_data(data) - $unproxied_data = data - @client.send_data(data) - end - - def connection_completed - EM.next_tick { - send_data @request - } - end - - def proxy_target_unbound - $unbound_early = true - EM.stop - end - - def proxy_completed - $proxy_completed = true - end - - def unbind - @client.close_connection_after_writing - end - end - - module Client - def connection_completed - send_data "EM rocks!" - end - - def receive_data(data) - $client_data = data - end - - def unbind - EM.stop - end - end - - module Client2 - include Client - def unbind; end - end - - module Server - def receive_data(data) - send_data "I know!" if data == "EM rocks!" - close_connection_after_writing - end - end - - module ProxyServer - def initialize port - @port = port - end - - def receive_data(data) - @proxy = EM.connect("127.0.0.1", @port, ProxyConnection, self, data) - end - end - - module PartialProxyServer - def initialize port - @port = port - end - - def receive_data(data) - EM.connect("127.0.0.1", @port, PartialProxyConnection, self, data, 1) - end - end - - module EarlyClosingProxy - def initialize port - @port = port - end - - def receive_data(data) - EM.connect("127.0.0.1", @port, ProxyConnection, self, data) - close_connection - end - end - - def setup - @port = next_port - @proxy_port = next_port - end - - def test_proxy_connection - EM.run { - EM.start_server("127.0.0.1", @port, Server) - EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port) - EM.connect("127.0.0.1", @proxy_port, Client) - } - - assert_equal("I know!", $client_data) - end - - def test_proxied_bytes - EM.run { - EM.start_server("127.0.0.1", @port, Server) - EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port) - EM.connect("127.0.0.1", @proxy_port, Client) - } - - assert_equal("I know!", $client_data) - assert_equal("I know!".bytesize, $proxied_bytes) - end - - def test_partial_proxy_connection - EM.run { - EM.start_server("127.0.0.1", @port, Server) - EM.start_server("127.0.0.1", @proxy_port, PartialProxyServer, @port) - EM.connect("127.0.0.1", @proxy_port, Client) - } - - assert_equal("I know!", $client_data) - assert_equal(" know!", $unproxied_data) - assert($proxy_completed) - end - - def test_early_close - $client_data = nil - EM.run { - EM.start_server("127.0.0.1", @port, Server) - EM.start_server("127.0.0.1", @proxy_port, EarlyClosingProxy, @port) - EM.connect("127.0.0.1", @proxy_port, Client2) - } - - assert($unbound_early) - end - else - warn "EM.start_proxy not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_start_proxy_not_implemented - assert !EM.respond_to?(:start_proxy) - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pure.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pure.rb deleted file mode 100644 index 8863a8d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_pure.rb +++ /dev/null @@ -1,139 +0,0 @@ -require 'em_test_helper' - -class TestPure < Test::Unit::TestCase - - def setup - @port = next_port - end - - # These tests are intended to exercise problems that come up in the - # pure-Ruby implementation. However, we DON'T constrain them such that - # they only run in pure-Ruby. These tests need to work identically in - # any implementation. - - #------------------------------------- - - # The EM reactor needs to run down open connections and release other resources - # when it stops running. Make sure this happens even if user code throws a Ruby - # exception. - # If exception handling is incorrect, the second test will fail with a no-bind error - # because the TCP server opened in the first test will not have been closed. - - def test_exception_handling_releases_resources - exception = Class.new(StandardError) - - 2.times do - assert_raises(exception) do - EM.run do - EM.start_server "127.0.0.1", @port - raise exception - end - end - end - end - - # Under some circumstances, the pure Ruby library would emit an Errno::ECONNREFUSED - # exception on certain kinds of TCP connect-errors. - # It's always been something of an open question whether EM should throw an exception - # in these cases but the defined answer has always been to catch it the unbind method. - # With a connect failure, the latter will always fire, but connection_completed will - # never fire. So even though the point is arguable, it's incorrect for the pure Ruby - # version to throw an exception. - module TestConnrefused - def unbind - EM.stop - end - def connection_completed - raise "should never get here" - end - end - - def test_connrefused - assert_nothing_raised do - EM.run { - setup_timeout(2) - EM.connect "127.0.0.1", @port, TestConnrefused - } - end - end - - # Make sure connection_completed gets called as expected with TCP clients. This is the - # opposite of test_connrefused. - # If the test fails, it will hang because EM.stop never gets called. - # - module TestConnaccepted - def connection_completed - EM.stop - end - end - def test_connaccepted - assert_nothing_raised do - EM.run { - EM.start_server "127.0.0.1", @port - EM.connect "127.0.0.1", @port, TestConnaccepted - setup_timeout(1) - } - end - end - - def test_reactor_running - a = false - EM.run { - a = EM.reactor_running? - EM.next_tick {EM.stop} - } - assert a - end - - module TLSServer - def post_init - start_tls - end - - def ssl_handshake_completed - $server_handshake_completed = true - end - - def receive_data(data) - $server_received_data = data - send_data(data) - end - end - - module TLSClient - def post_init - start_tls - end - - def ssl_handshake_completed - $client_handshake_completed = true - end - - def connection_completed - send_data('Hello World!') - end - - def receive_data(data) - $client_received_data = data - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - def test_start_tls - $client_handshake_completed, $server_handshake_completed = false, false - $client_received_data, $server_received_data = nil, nil - EM.run do - EM.start_server("127.0.0.1", 16789, TLSServer) - EM.connect("127.0.0.1", 16789, TLSClient) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - assert($client_received_data == "Hello World!") - assert($server_received_data == "Hello World!") - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_queue.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_queue.rb deleted file mode 100644 index 34278c0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_queue.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'em_test_helper' - -class TestEMQueue < Test::Unit::TestCase - def test_queue_push - s = 0 - EM.run do - q = EM::Queue.new - q.push(1) - EM.next_tick { s = q.size; EM.stop } - end - assert_equal 1, s - end - - def test_queue_pop - x,y,z = nil - EM.run do - q = EM::Queue.new - q.push(1,2,3) - q.pop { |v| x = v } - q.pop { |v| y = v } - q.pop { |v| z = v; EM.stop } - end - assert_equal 1, x - assert_equal 2, y - assert_equal 3, z - end - - def test_queue_reactor_thread - q = EM::Queue.new - - Thread.new { q.push(1,2,3) }.join - assert q.empty? - EM.run { EM.next_tick { EM.stop } } - assert_equal 3, q.size - - x = nil - Thread.new { q.pop { |v| x = v } }.join - assert_equal nil, x - EM.run { EM.next_tick { EM.stop } } - assert_equal 1, x - end - - def test_num_waiting - q = EM::Queue.new - many = 3 - many.times { q.pop {} } - EM.run { EM.next_tick { EM.stop } } - assert_equal many, q.num_waiting - end - - def test_big_queue - EM.run do - q = EM::Queue.new - 2000.times do |i| - q.push(*0..1000) - q.pop { |v| assert_equal v, i % 1001 } - end - q.pop do - assert_equal 1_999_999, q.size - EM.stop - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_resolver.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_resolver.rb deleted file mode 100644 index 58ed5f5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_resolver.rb +++ /dev/null @@ -1,105 +0,0 @@ -require 'em_test_helper' - -class TestResolver < Test::Unit::TestCase - def test_nameserver - assert_kind_of(String, EM::DNS::Resolver.nameserver) - end - - def test_nameservers - assert_kind_of(Array, EM::DNS::Resolver.nameservers) - end - - def test_hosts - assert_kind_of(Hash, EM::DNS::Resolver.hosts) - - # Make sure that blank or comment lines are skipped - refute(EM::DNS::Resolver.hosts.include? nil) - end - - def test_a - pend('FIXME: this test is broken on Windows') if windows? - - EM.run { - d = EM::DNS::Resolver.resolve "example.com" - d.errback { assert false } - d.callback { |r| - assert r - EM.stop - } - } - end - - def test_bad_host - EM.run { - d = EM::DNS::Resolver.resolve "asdfasasdf" - d.callback { assert false } - d.errback { assert true; EM.stop } - } - end - - def test_garbage - assert_raises( ArgumentError ) { - EM.run { - EM::DNS::Resolver.resolve 123 - } - } - end - - # There isn't a public DNS entry like 'example.com' with an A rrset - def test_a_pair - pend('FIXME: this test is broken on Windows') if windows? - - EM.run { - d = EM::DNS::Resolver.resolve "yahoo.com" - d.errback { |err| assert false, "failed to resolve yahoo.com: #{err}" } - d.callback { |r| - assert_kind_of(Array, r) - assert r.size > 1, "returned #{r.size} results: #{r.inspect}" - EM.stop - } - } - end - - def test_localhost - pend('FIXME: this test is broken on Windows') if windows? - - EM.run { - d = EM::DNS::Resolver.resolve "localhost" - d.errback { assert false } - d.callback { |r| - assert_include(["127.0.0.1", "::1"], r.first) - assert_kind_of(Array, r) - - EM.stop - } - } - end - - def test_timer_cleanup - pend('FIXME: this test is broken on Windows') if windows? - - EM.run { - d = EM::DNS::Resolver.resolve "example.com" - d.errback { |err| assert false, "failed to resolve example.com: #{err}" } - d.callback { |r| - # This isn't a great test, but it's hard to get more canonical - # confirmation that the timer is cancelled - assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer)) - - EM.stop - } - } - end - - def test_failure_timer_cleanup - EM.run { - d = EM::DNS::Resolver.resolve "asdfasdf" - d.callback { assert false } - d.errback { - assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer)) - - EM.stop - } - } - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_running.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_running.rb deleted file mode 100644 index 693b390..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_running.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'em_test_helper' - -class TestRunning < Test::Unit::TestCase - def test_running - assert_equal( false, EM::reactor_running? ) - r = false - EM.run { - r = EM::reactor_running? - EM.stop - } - assert_equal( true, r ) - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sasl.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sasl.rb deleted file mode 100644 index e80f657..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sasl.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'em_test_helper' - - -class TestSASL < Test::Unit::TestCase - - # SASL authentication is usually done with UNIX-domain sockets, but - # we'll use TCP so this test will work on Windows. As far as the - # protocol handlers are concerned, there's no difference. - - TestUser,TestPsw = "someone", "password" - - class SaslServer < EM::Connection - include EM::Protocols::SASLauth - def validate usr, psw, sys, realm - usr == TestUser and psw == TestPsw - end - end - - class SaslClient < EM::Connection - include EM::Protocols::SASLauthclient - end - - def setup - @port = next_port - end - - def test_sasl - resp = nil - EM.run { - EM.start_server( "127.0.0.1", @port, SaslServer ) - - c = EM.connect( "127.0.0.1", @port, SaslClient ) - d = c.validate?( TestUser, TestPsw ) - d.timeout 1 - d.callback { - resp = true - EM.stop - } - d.errback { - resp = false - EM.stop - } - } - assert_equal( true, resp ) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_send_file.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_send_file.rb deleted file mode 100644 index a784b50..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_send_file.rb +++ /dev/null @@ -1,217 +0,0 @@ -require 'em_test_helper' -require 'tempfile' - -class TestSendFile < Test::Unit::TestCase - - if EM.respond_to?(:send_file_data) - module TestModule - def initialize filename - @filename = filename - end - - def post_init - send_file_data @filename - close_connection_after_writing - end - end - - module TestClient - def data_to(&blk) - @data_to = blk - end - - def receive_data(data) - @data_to.call(data) if @data_to - end - - def unbind - EM.stop - end - end - - def setup - @file = Tempfile.new("em_test_file") - @filename = @file.path - @port = next_port - end - - def test_send_file - File.open( @filename, "w" ) {|f| - f << ("A" * 5000) - } - - data = '' - - EM.run { - EM.start_server "127.0.0.1", @port, TestModule, @filename - setup_timeout - - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - assert_equal( "A" * 5000, data ) - end - - # EM::Connection#send_file_data has a strict upper limit on the filesize it will work with. - def test_send_large_file - File.open( @filename, "w" ) {|f| - f << ("A" * 1000000) - } - - data = '' - - assert_raises(RuntimeError) { - EM.run { - EM.start_server "127.0.0.1", @port, TestModule, @filename - setup_timeout - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - } - end - - module StreamTestModule - def initialize filename - @filename = filename - end - - def post_init - EM::Deferrable.future( stream_file_data(@filename)) { - close_connection_after_writing - } - end - end - - module ChunkStreamTestModule - def initialize filename - @filename = filename - end - - def post_init - EM::Deferrable.future( stream_file_data(@filename, :http_chunks=>true)) { - close_connection_after_writing - } - end - end - - def test_stream_file_data - File.open( @filename, "w" ) {|f| - f << ("A" * 1000) - } - - data = '' - - EM.run { - EM.start_server "127.0.0.1", @port, StreamTestModule, @filename - setup_timeout - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - assert_equal( "A" * 1000, data ) - end - - def test_stream_chunked_file_data - File.open( @filename, "w" ) {|f| - f << ("A" * 1000) - } - - data = '' - - EM.run { - EM.start_server "127.0.0.1", @port, ChunkStreamTestModule, @filename - setup_timeout - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - assert_equal( "3e8\r\n#{"A" * 1000}\r\n0\r\n\r\n", data ) - end - - module BadFileTestModule - def initialize filename - @filename = filename - end - - def post_init - de = stream_file_data( @filename+".wrong" ) - de.errback {|msg| - send_data msg - close_connection_after_writing - } - end - end - def test_stream_bad_file - data = '' - EM.run { - EM.start_server "127.0.0.1", @port, BadFileTestModule, @filename - setup_timeout(5) - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - assert_equal( "file not found", data ) - end - else - warn "EM.send_file_data not implemented, skipping tests in #{__FILE__}" - - # Because some rubies will complain if a TestCase class has no tests - def test_em_send_file_data_not_implemented - assert !EM.respond_to?(:send_file_data) - end - end - - begin - require 'fastfilereaderext' - - def test_stream_large_file_data - File.open( @filename, "w" ) {|f| - f << ("A" * 10000) - } - - data = '' - - EM.run { - EM.start_server "127.0.0.1", @port, StreamTestModule, @filename - setup_timeout - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - assert_equal( "A" * 10000, data ) - end - - def test_stream_large_chunked_file_data - File.open( @filename, "w" ) {|f| - f << ("A" * 100000) - } - - data = '' - - EM.run { - EM.start_server "127.0.0.1", @port, ChunkStreamTestModule, @filename - setup_timeout - EM.connect "127.0.0.1", @port, TestClient do |c| - c.data_to { |d| data << d } - end - } - - expected = [ - "4000\r\n#{"A" * 16384}\r\n" * 6, - "6a0\r\n#{"A" * 0x6a0}\r\n", - "0\r\n\r\n" - ].join - assert_equal( expected, data ) - end - rescue LoadError - warn "require 'fastfilereaderext' failed, skipping tests in #{__FILE__}" - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_servers.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_servers.rb deleted file mode 100644 index 2a17050..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_servers.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'em_test_helper' -require 'socket' - -class TestServers < Test::Unit::TestCase - - def setup - @port = next_port - end - - def server_alive? - port_in_use?(@port) - end - - def run_test_stop_server - EM.run { - sig = EM.start_server("127.0.0.1", @port) - assert server_alive?, "Server didn't start" - EM.stop_server sig - # Give the server some time to shutdown. - EM.add_timer(0.1) { - assert !server_alive?, "Server didn't stop" - EM.stop - } - } - end - - def test_stop_server - assert !server_alive?, "Port already in use" - 2.times { run_test_stop_server } - assert !server_alive?, "Servers didn't stop" - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_shutdown_hooks.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_shutdown_hooks.rb deleted file mode 100644 index b0e0c5c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_shutdown_hooks.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'em_test_helper' - -class TestShutdownHooks < Test::Unit::TestCase - def test_shutdown_hooks - r = false - EM.run { - EM.add_shutdown_hook { r = true } - EM.stop - } - assert_equal( true, r ) - end - - def test_hook_order - r = [] - EM.run { - EM.add_shutdown_hook { r << 2 } - EM.add_shutdown_hook { r << 1 } - EM.stop - } - assert_equal( [1, 2], r ) - end -end - diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpclient.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpclient.rb deleted file mode 100644 index 71ed584..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpclient.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'em_test_helper' - -class TestSmtpClient < Test::Unit::TestCase - - Localhost = "127.0.0.1" - Localport = 9801 - - def setup - end - - def teardown - end - - def test_a - # No real tests until we have a server implementation to test against. - # This is what the call looks like, though: - err = nil - EM.run { - d = EM::Protocols::SmtpClient.send :domain=>"example.com", - :host=>Localhost, - :port=>Localport, # optional, defaults 25 - :starttls=>true, - :from=>"sender@example.com", - :to=> ["to_1@example.com", "to_2@example.com"], - :header=> {"Subject" => "This is a subject line"}, - :body=> "This is the body of the email", - :verbose=>true - d.errback {|e| - err = e - EM.stop - } - } - assert(err) - end - - def test_content - err = nil - EM.run { - d = EM::Protocols::SmtpClient.send :domain=>"example.com", - :host=>Localhost, - :port=>Localport, # optional, defaults 25 - :starttls=>true, - :from=>"sender@example.com", - :to=> ["to_1@example.com", "to_2@example.com"], - :content => ["Subject: xxx\r\n\r\ndata\r\n.\r\n"], - :verbose=>true - d.errback {|e| - err = e - EM.stop - } - } - assert(err) - end - - - EM::Protocols::SmtpClient.__send__(:public, :escape_leading_dots) - - def test_escaping - smtp = EM::Protocols::SmtpClient.new :domain => "example.com" - - expectations = { - "Hello\r\n" => "Hello\r\n", - "\r\n.whatever\r\n" => "\r\n..whatever\r\n", - "\r\n.\r\n" => "\r\n..\r\n", - "\r\n.\r\n." => "\r\n..\r\n..", - ".\r\n.\r\n" => "..\r\n..\r\n", - "..\r\n" => "...\r\n" - } - - expectations.each do |input, output| - assert_equal output, smtp.escape_leading_dots(input) - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpserver.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpserver.rb deleted file mode 100644 index 18c50fe..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_smtpserver.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'em_test_helper' - -class TestSmtpServer < Test::Unit::TestCase - - # Don't test on port 25. It requires superuser and there's probably - # a mail server already running there anyway. - Localhost = "127.0.0.1" - Localport = 25001 - - # This class is an example of what you need to write in order - # to implement a mail server. You override the methods you are - # interested in. Some, but not all, of these are illustrated here. - # - class Mailserver < EM::Protocols::SmtpServer - - attr_reader :my_msg_body, :my_sender, :my_recipients - - def initialize *args - super - end - def receive_sender sender - @my_sender = sender - #p sender - true - end - def receive_recipient rcpt - @my_recipients ||= [] - @my_recipients << rcpt - true - end - def receive_data_chunk c - @my_msg_body = c.last - end - def connection_ended - EM.stop - end - end - - def test_mail - c = nil - EM.run { - EM.start_server( Localhost, Localport, Mailserver ) {|conn| c = conn} - EM::Timer.new(2) {EM.stop} # prevent hanging the test suite in case of error - EM::Protocols::SmtpClient.send :host=>Localhost, - :port=>Localport, - :domain=>"bogus", - :from=>"me@example.com", - :to=>"you@example.com", - :header=> {"Subject"=>"Email subject line", "Reply-to"=>"me@example.com"}, - :body=>"Not much of interest here." - - } - assert_equal( "Not much of interest here.", c.my_msg_body ) - assert_equal( "", c.my_sender ) - assert_equal( [""], c.my_recipients ) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sock_opt.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sock_opt.rb deleted file mode 100644 index 60fba35..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_sock_opt.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'em_test_helper' -require 'socket' - -class TestSockOpt < Test::Unit::TestCase - def setup - assert(!EM.reactor_running?) - @port = next_port - end - - def teardown - assert(!EM.reactor_running?) - end - - def test_set_sock_opt - omit_if(windows?) - omit_if(!EM.respond_to?(:set_sock_opt)) - - val = nil - test_module = Module.new do - define_method :post_init do - val = set_sock_opt Socket::SOL_SOCKET, Socket::SO_BROADCAST, true - EM.stop - end - end - - EM.run do - EM.start_server '127.0.0.1', @port - EM.connect '127.0.0.1', @port, test_module - end - - assert_equal 0, val - end - - def test_get_sock_opt - omit_if(windows?) - omit_if(!EM.respond_to?(:set_sock_opt)) - - val = nil - test_module = Module.new do - define_method :connection_completed do - val = get_sock_opt Socket::SOL_SOCKET, Socket::SO_ERROR - EM.stop - end - end - - EM.run do - EM.start_server '127.0.0.1', @port - EM.connect '127.0.0.1', @port, test_module - end - - assert_equal "\0\0\0\0", val - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_spawn.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_spawn.rb deleted file mode 100644 index ab0a92f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_spawn.rb +++ /dev/null @@ -1,293 +0,0 @@ - -require 'em_test_helper' - - - -class TestSpawn < Test::Unit::TestCase - - # Spawn a process that simply stops the reactor. - # Assert that the notification runs after the block that calls it. - # - def test_stop - x = nil - EM.run { - s = EM.spawn {EM.stop} - s.notify - x = true - } - assert x - end - - - # Pass a parameter to a spawned process. - # - def test_parms - val = 5 - EM.run { - s = EM.spawn {|v| val *= v; EM.stop} - s.notify 3 - } - assert_equal( 15, val ) - end - - # Pass multiple parameters to a spawned process. - # - def test_multiparms - val = 5 - EM.run { - s = EM.spawn {|v1,v2| val *= (v1 + v2); EM.stop} - s.notify 3,4 - } - assert_equal( 35, val ) - end - - - # This test demonstrates that a notification does not happen immediately, - # but rather is scheduled sometime after the current code path completes. - # - def test_race - x = 0 - EM.run { - s = EM.spawn {x *= 2; EM.stop} - s.notify - x = 2 - } - assert_equal( 4, x) - end - - - # Spawn a process and notify it 25 times to run fibonacci - # on a pair of global variables. - # - def test_fibonacci - x = 1 - y = 1 - EM.run { - s = EM.spawn {x,y = y,x+y} - 25.times {s.notify} - - t = EM.spawn {EM.stop} - t.notify - } - assert_equal( 121393, x) - assert_equal( 196418, y) - end - - # This one spawns 25 distinct processes, and notifies each one once, - # rather than notifying a single process 25 times. - # - def test_another_fibonacci - x = 1 - y = 1 - EM.run { - 25.times { - s = EM.spawn {x,y = y,x+y} - s.notify - } - - t = EM.spawn {EM.stop} - t.notify - } - assert_equal( 121393, x) - assert_equal( 196418, y) - end - - - # Make a chain of processes that notify each other in turn - # with intermediate fibonacci results. The final process in - # the chain stops the loop and returns the result. - # - def test_fibonacci_chain - a,b = nil - - EM.run { - nextpid = EM.spawn {|x,y| - a,b = x,y - EM.stop - } - - 25.times { - n = nextpid - nextpid = EM.spawn {|x,y| n.notify( y, x+y )} - } - - nextpid.notify( 1, 1 ) - } - - assert_equal( 121393, a) - assert_equal( 196418, b) - end - - - # EM#yield gives a spawed process to yield control to other processes - # (in other words, to stop running), and to specify a different code block - # that will run on its next notification. - # - def test_yield - a = 0 - EM.run { - n = EM.spawn { - a += 10 - EM.yield { - a += 20 - EM.yield { - a += 30 - EM.stop - } - } - } - n.notify - n.notify - n.notify - } - assert_equal( 60, a ) - end - - # EM#yield_and_notify behaves like EM#yield, except that it also notifies the - # yielding process. This may sound trivial, since the yield block will run very - # shortly after with no action by the program, but this actually can be very useful, - # because it causes the reactor core to execute once before the yielding process - # gets control back. So it can be used to allow heavily-used network connections - # to clear buffers, or allow other processes to process their notifications. - # - # Notice in this test code that only a simple notify is needed at the bottom - # of the initial block. Even so, all of the yielded blocks will execute. - # - def test_yield_and_notify - a = 0 - EM.run { - n = EM.spawn { - a += 10 - EM.yield_and_notify { - a += 20 - EM.yield_and_notify { - a += 30 - EM.stop - } - } - } - n.notify - } - assert_equal( 60, a ) - end - - # resume is an alias for notify. - # - def test_resume - EM.run { - n = EM.spawn {EM.stop} - n.resume - } - assert true - end - - # run is an idiomatic alias for notify. - # - def test_run - EM.run { - (EM.spawn {EM.stop}).run - } - assert true - end - - - # Clones the ping-pong example from the Erlang tutorial, in much less code. - # Illustrates that a spawned block executes in the context of a SpawnableObject. - # (Meaning, we can pass self as a parameter to another process that can then - # notify us.) - # - def test_ping_pong - n_pongs = 0 - EM.run { - pong = EM.spawn {|x, ping| - n_pongs += 1 - ping.notify( x-1 ) - } - ping = EM.spawn {|x| - if x > 0 - pong.notify x, self - else - EM.stop - end - } - ping.notify 3 - } - assert_equal( 3, n_pongs ) - end - - # Illustrates that you can call notify inside a notification, and it will cause - # the currently-executing process to be re-notified. Of course, the new notification - # won't run until sometime after the current one completes. - # - def test_self_notify - n = 0 - EM.run { - pid = EM.spawn {|x| - if x > 0 - n += x - notify( x-1 ) - else - EM.stop - end - } - pid.notify 3 - } - assert_equal( 6, n ) - end - - - # Illustrates that the block passed to #spawn executes in the context of a - # SpawnedProcess object, NOT in the local context. This can often be deceptive. - # - class BlockScopeTest - attr_reader :var - def run - # The following line correctly raises a NameError. - # The problem is that the programmer expected the spawned block to - # execute in the local context, but it doesn't. - # - # (EM.spawn { do_something }).notify ### NO! BAD! - - - - # The following line correctly passes self as a parameter to the - # notified process. - # - (EM.spawn {|obj| obj.do_something }).notify(self) - - - - # Here's another way to do it. This works because "myself" is bound - # in the local scope, unlike "self," so the spawned block sees it. - # - myself = self - (EM.spawn { myself.do_something }).notify - - - - # And we end the loop. - # This is a tangential point, but observe that #notify never blocks. - # It merely appends a message to the internal queue of a spawned process - # and returns. As it turns out, the reactor processes notifications for ALL - # spawned processes in the order that #notify is called. So there is a - # reasonable expectation that the process which stops the reactor will - # execute after the previous ones in this method. HOWEVER, this is NOT - # a documented behavior and is subject to change. - # - (EM.spawn {EM.stop}).notify - end - def do_something - @var ||= 0 - @var += 100 - end - end - - def test_block_scope - bs = BlockScopeTest.new - EM.run { - bs.run - } - assert_equal( 200, bs.var ) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_args.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_args.rb deleted file mode 100644 index d337628..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_args.rb +++ /dev/null @@ -1,78 +0,0 @@ -require "test/unit" -require 'tempfile' - -require 'em_test_helper' - -module EM - def self._set_mocks - class < priv_file) - end - assert_raises(EM::FileNotFoundException) do - conn.start_tls(:cert_chain_file => cert_file) - end - assert_raises(EM::FileNotFoundException) do - conn.start_tls(:private_key_file => priv_file, :cert_chain_file => cert_file) - end - end - - def test_tls_params_file_does_exist - priv_file = Tempfile.new('em_test') - cert_file = Tempfile.new('em_test') - priv_file_path = priv_file.path - cert_file_path = cert_file.path - conn = EM::Connection.new('foo') - params = {:private_key_file => priv_file_path, :cert_chain_file => cert_file_path} - begin - conn.start_tls params - rescue Object - assert(false, 'should not have raised an exception') - end - end -end if EM.ssl? diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_dhparam.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_dhparam.rb deleted file mode 100644 index 85f52d2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_dhparam.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'em_test_helper' - -class TestSslDhParam < Test::Unit::TestCase - def setup - $dir = File.dirname(File.expand_path(__FILE__)) + '/' - $dhparam_file = File.join($dir, 'dhparam.pem') - end - - module Client - def post_init - start_tls - end - - def ssl_handshake_completed - $client_handshake_completed = true - $client_cipher_name = get_cipher_name - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - module Server - def post_init - start_tls(:dhparam => $dhparam_file, :cipher_list => "DHE,EDH") - end - - def ssl_handshake_completed - $server_handshake_completed = true - $server_cipher_name = get_cipher_name - end - end - - module NoDhServer - def post_init - start_tls(:cipher_list => "DHE,EDH") - end - - def ssl_handshake_completed - $server_handshake_completed = true - $server_cipher_name = get_cipher_name - end - end - - def test_no_dhparam - omit_unless(EM.ssl?) - omit_if(EM.library_type == :pure_ruby) # DH will work with defaults - omit_if(rbx?) - - $client_handshake_completed, $server_handshake_completed = false, false - $server_cipher_name, $client_cipher_name = nil, nil - - EM.run { - EM.start_server("127.0.0.1", 16784, NoDhServer) - EM.connect("127.0.0.1", 16784, Client) - } - - assert(!$client_handshake_completed) - assert(!$server_handshake_completed) - end - - def test_dhparam - omit_unless(EM.ssl?) - omit_if(rbx?) - - $client_handshake_completed, $server_handshake_completed = false, false - $server_cipher_name, $client_cipher_name = nil, nil - - EM.run { - EM.start_server("127.0.0.1", 16784, Server) - EM.connect("127.0.0.1", 16784, Client) - } - - assert($client_handshake_completed) - assert($server_handshake_completed) - - assert($client_cipher_name.length > 0) - assert_equal($client_cipher_name, $server_cipher_name) - - assert_match(/^(DHE|EDH)/, $client_cipher_name) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_ecdh_curve.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_ecdh_curve.rb deleted file mode 100644 index 8dc167b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_ecdh_curve.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'em_test_helper' - -class TestSslEcdhCurve < Test::Unit::TestCase - module Client - def post_init - start_tls - end - - def ssl_handshake_completed - $client_handshake_completed = true - $client_cipher_name = get_cipher_name - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - module Server - def post_init - start_tls(:ecdh_curve => "prime256v1", :cipher_list => "ECDH") - end - - def ssl_handshake_completed - $server_handshake_completed = true - $server_cipher_name = get_cipher_name - end - end - - module NoCurveServer - def post_init - start_tls(:cipher_list => "ECDH") - end - - def ssl_handshake_completed - $server_handshake_completed = true - $server_cipher_name = get_cipher_name - end - end - - def test_no_ecdh_curve - omit_unless(EM.ssl?) - omit_if(rbx?) - - $client_handshake_completed, $server_handshake_completed = false, false - - EM.run { - EM.start_server("127.0.0.1", 16784, NoCurveServer) - EM.connect("127.0.0.1", 16784, Client) - } - - assert(!$client_handshake_completed) - assert(!$server_handshake_completed) - end - - def test_ecdh_curve - omit_unless(EM.ssl?) - omit_if(EM.library_type == :pure_ruby && RUBY_VERSION < "2.3.0") - omit_if(rbx?) - - $client_handshake_completed, $server_handshake_completed = false, false - $server_cipher_name, $client_cipher_name = nil, nil - - EM.run { - EM.start_server("127.0.0.1", 16784, Server) - EM.connect("127.0.0.1", 16784, Client) - } - - assert($client_handshake_completed) - assert($server_handshake_completed) - - assert($client_cipher_name.length > 0) - assert_equal($client_cipher_name, $server_cipher_name) - - assert_match(/^(AECDH|ECDHE)/, $client_cipher_name) - end - - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_extensions.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_extensions.rb deleted file mode 100644 index 0610ba8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_extensions.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'em_test_helper' - -require 'socket' -require 'openssl' - -if EM.ssl? - class TestSslExtensions < Test::Unit::TestCase - - module Client - def ssl_handshake_completed - $client_handshake_completed = true - close_connection - end - - def unbind - EM.stop_event_loop - end - - def post_init - start_tls(:ssl_version => :tlsv1, :sni_hostname => 'example.com') - end - end - - module Server - def ssl_handshake_completed - $server_handshake_completed = true - $server_sni_hostname = get_sni_hostname - end - - def post_init - start_tls(:ssl_version => :TLSv1) - end - end - - def test_tlsext_sni_hostname - $server_handshake_completed = false - - EM.run do - EM.start_server("127.0.0.1", 16784, Server) - EM.connect("127.0.0.1", 16784, Client) - end - - assert($server_handshake_completed) - assert_equal('example.com', $server_sni_hostname) - end - end -else - warn "EM built without SSL support, skipping tests in #{__FILE__}" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_methods.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_methods.rb deleted file mode 100644 index c2e5744..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_methods.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'em_test_helper' - -class TestSSLMethods < Test::Unit::TestCase - - module ServerHandler - def post_init - start_tls - end - - def ssl_handshake_completed - $server_called_back = true - $server_cert_value = get_peer_cert - $server_cipher_bits = get_cipher_bits - $server_cipher_name = get_cipher_name - $server_cipher_protocol = get_cipher_protocol - end - end - - module ClientHandler - def post_init - start_tls - end - - def ssl_handshake_completed - $client_called_back = true - $client_cert_value = get_peer_cert - $client_cipher_bits = get_cipher_bits - $client_cipher_name = get_cipher_name - $client_cipher_protocol = get_cipher_protocol - EM.stop_event_loop - end - end - - def test_ssl_methods - omit_unless(EM.ssl?) - omit_if(rbx?) - $server_called_back, $client_called_back = false, false - $server_cert_value, $client_cert_value = nil, nil - $server_cipher_bits, $client_cipher_bits = nil, nil - $server_cipher_name, $client_cipher_name = nil, nil - $server_cipher_protocol, $client_cipher_protocol = nil, nil - - EM.run { - EM.start_server("127.0.0.1", 9999, ServerHandler) - EM.connect("127.0.0.1", 9999, ClientHandler) - } - - assert($server_called_back) - assert($client_called_back) - - assert($server_cert_value.is_a?(NilClass)) - assert($client_cert_value.is_a?(String)) - - assert($client_cipher_bits > 0) - assert_equal($client_cipher_bits, $server_cipher_bits) - - assert($client_cipher_name.length > 0) - assert_match(/AES/, $client_cipher_name) - assert_equal($client_cipher_name, $server_cipher_name) - - assert_match(/TLS/, $client_cipher_protocol) - assert_equal($client_cipher_protocol, $server_cipher_protocol) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_protocols.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_protocols.rb deleted file mode 100644 index bcb6824..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_protocols.rb +++ /dev/null @@ -1,246 +0,0 @@ -require 'em_test_helper' - -require 'socket' -require 'openssl' - -if EM.ssl? - class TestSslProtocols < Test::Unit::TestCase - - module Client - def ssl_handshake_completed - $client_handshake_completed = true - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - module Server - def ssl_handshake_completed - $server_handshake_completed = true - end - end - - module ClientAny - include Client - def post_init - start_tls(:ssl_version => %w(sslv2 sslv3 tlsv1 tlsv1_1 tlsv1_2)) - end - end - - module ClientDefault - include Client - def post_init - start_tls - end - end - - module ClientSSLv3 - include Client - def post_init - start_tls(:ssl_version => %w(SSLv3)) - end - end - - module ServerSSLv3 - include Server - def post_init - start_tls(:ssl_version => %w(SSLv3)) - end - end - - module ServerTLSv1CaseInsensitive - include Server - def post_init - start_tls(:ssl_version => %w(tlsv1)) - end - end - - module ServerAny - include Server - def post_init - start_tls(:ssl_version => %w(sslv2 sslv3 tlsv1 tlsv1_1 tlsv1_2)) - end - end - - module ServerDefault - include Server - def post_init - start_tls - end - end - - module InvalidProtocol - include Client - def post_init - start_tls(:ssl_version => %w(tlsv1 badinput)) - end - end - - def test_invalid_ssl_version - assert_raises(RuntimeError, "Unrecognized SSL/TLS Version: badinput") do - EM.run do - EM.start_server("127.0.0.1", 16784, InvalidProtocol) - EM.connect("127.0.0.1", 16784, InvalidProtocol) - end - end - end - - def test_any_to_v3 - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerSSLv3) - EM.connect("127.0.0.1", 16784, ClientAny) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_case_insensitivity - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerTLSv1CaseInsensitive) - EM.connect("127.0.0.1", 16784, ClientAny) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_v3_to_any - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerAny) - EM.connect("127.0.0.1", 16784, ClientSSLv3) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_v3_to_v3 - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerSSLv3) - EM.connect("127.0.0.1", 16784, ClientSSLv3) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_any_to_any - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerAny) - EM.connect("127.0.0.1", 16784, ClientAny) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_default_to_default - $client_handshake_completed, $server_handshake_completed = false, false - EM.run do - EM.start_server("127.0.0.1", 16784, ServerDefault) - EM.connect("127.0.0.1", 16784, ClientDefault) - end - - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - module ServerV3StopAfterHandshake - def post_init - start_tls(:ssl_version => %w(SSLv3)) - end - - def ssl_handshake_completed - $server_handshake_completed = true - EM.stop_event_loop - end - end - - module ServerTLSv1StopAfterHandshake - def post_init - start_tls(:ssl_version => %w(TLSv1)) - end - - def ssl_handshake_completed - $server_handshake_completed = true - EM.stop_event_loop - end - end - - def test_v3_with_external_client - $server_handshake_completed = false - EM.run do - setup_timeout(2) - EM.start_server("127.0.0.1", 16784, ServerV3StopAfterHandshake) - EM.defer do - sock = TCPSocket.new("127.0.0.1", 16784) - ctx = OpenSSL::SSL::SSLContext.new - ctx.ssl_version = :SSLv3_client - ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) - ssl.connect - ssl.close rescue nil - sock.close rescue nil - end - end - - assert($server_handshake_completed) - end - - def test_tlsv1_with_external_client - $server_handshake_completed = false - EM.run do - setup_timeout(2) - EM.start_server("127.0.0.1", 16784, ServerTLSv1StopAfterHandshake) - EM.defer do - sock = TCPSocket.new("127.0.0.1", 16784) - ctx = OpenSSL::SSL::SSLContext.new - ctx.ssl_version = :TLSv1_client - ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) - ssl.connect - ssl.close rescue nil - sock.close rescue nil - end - end - - assert($server_handshake_completed) - end - - def test_tlsv1_required_with_external_client - $server_handshake_completed = false - - EM.run do - n = 0 - EM.add_periodic_timer(0.5) do - n += 1 - (EM.stop rescue nil) if n == 2 - end - EM.start_server("127.0.0.1", 16784, ServerTLSv1StopAfterHandshake) - EM.defer do - sock = TCPSocket.new("127.0.0.1", 16784) - ctx = OpenSSL::SSL::SSLContext.new - ctx.ssl_version = :SSLv3_client - ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) - assert_raise OpenSSL::SSL::SSLError do - ssl.connect - end - ssl.close rescue nil - sock.close rescue nil - EM.stop rescue nil - end - end - - assert(!$server_handshake_completed) - end - end -else - warn "EM built without SSL support, skipping tests in #{__FILE__}" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_verify.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_verify.rb deleted file mode 100644 index a6d8fca..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ssl_verify.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'em_test_helper' - -class TestSslVerify < Test::Unit::TestCase - def setup - $dir = File.dirname(File.expand_path(__FILE__)) + '/' - $cert_from_file = File.read($dir+'client.crt') - end - - module ClientNoCert - def connection_completed - start_tls() - end - - def ssl_handshake_completed - $client_handshake_completed = true - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - module Client - def connection_completed - start_tls(:private_key_file => $dir+'client.key', :cert_chain_file => $dir+'client.crt') - end - - def ssl_handshake_completed - $client_handshake_completed = true - close_connection - end - - def unbind - EM.stop_event_loop - end - end - - module AcceptServer - def post_init - start_tls(:verify_peer => true) - end - - def ssl_verify_peer(cert) - $cert_from_server = cert - true - end - - def ssl_handshake_completed - $server_handshake_completed = true - end - end - - module DenyServer - def post_init - start_tls(:verify_peer => true) - end - - def ssl_verify_peer(cert) - $cert_from_server = cert - # Do not accept the peer. This should now cause the connection to shut down without the SSL handshake being completed. - false - end - - def ssl_handshake_completed - $server_handshake_completed = true - end - end - - module FailServerNoPeerCert - def post_init - start_tls(:verify_peer => true, :fail_if_no_peer_cert => true) - end - - def ssl_verify_peer(cert) - raise "Verify peer should not get called for a client without a certificate" - end - - def ssl_handshake_completed - $server_handshake_completed = true - end - end - - def test_fail_no_peer_cert - omit_unless(EM.ssl?) - omit_if(rbx?) - - $client_handshake_completed, $server_handshake_completed = false, false - - EM.run { - EM.start_server("127.0.0.1", 16784, FailServerNoPeerCert) - EM.connect("127.0.0.1", 16784, ClientNoCert) - } - - assert(!$client_handshake_completed) - assert(!$server_handshake_completed) - end - - def test_accept_server - omit_unless(EM.ssl?) - omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain - omit_if(rbx?) - $client_handshake_completed, $server_handshake_completed = false, false - EM.run { - EM.start_server("127.0.0.1", 16784, AcceptServer) - EM.connect("127.0.0.1", 16784, Client).instance_variable_get("@signature") - } - - assert_equal($cert_from_file, $cert_from_server) - assert($client_handshake_completed) - assert($server_handshake_completed) - end - - def test_deny_server - omit_unless(EM.ssl?) - omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain - omit_if(rbx?) - $client_handshake_completed, $server_handshake_completed = false, false - EM.run { - EM.start_server("127.0.0.1", 16784, DenyServer) - EM.connect("127.0.0.1", 16784, Client) - } - - assert_equal($cert_from_file, $cert_from_server) - assert(!$client_handshake_completed) - assert(!$server_handshake_completed) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_stomp.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_stomp.rb deleted file mode 100644 index 53c0502..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_stomp.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'em_test_helper' - -class TestStomp < Test::Unit::TestCase - CONTENT_LENGTH_REGEX = /^content-length: (\d+)$/ - - def bytesize(str) - str = str.to_s - size = str.bytesize if str.respond_to?(:bytesize) # bytesize added in 1.9 - size || str.size - end - - class TStomp - include EM::P::Stomp - - def last_sent_content_length - @sent && Integer(@sent[CONTENT_LENGTH_REGEX, 1]) - end - - def send_data(string) - @sent = string - end - end - - def test_content_length_in_bytes - connection = TStomp.new - - queue = "queue" - failure_message = "header content-length is not the byte size of last sent body" - - body = "test" - connection.send queue, body - assert_equal bytesize(body), connection.last_sent_content_length, failure_message - - body = "test\u221A" - connection.send queue, body - assert_equal bytesize(body), connection.last_sent_content_length, failure_message - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_system.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_system.rb deleted file mode 100644 index fbbe2c9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_system.rb +++ /dev/null @@ -1,46 +0,0 @@ -# coding: utf-8 -require 'em_test_helper' - -class TestSystem < Test::Unit::TestCase - def setup - @filename = File.expand_path("../я манал dump.txt", __FILE__) - @test_data = 'a' * 100 - File.open(@filename, 'w'){|f| f.write(@test_data)} - end - - def test_system - omit_if(windows?) - - result = nil - status = nil - EM.run { - EM.system('cat', @filename){|out, state| - result = out - status = state.exitstatus - EM.stop - } - } - assert_equal(0, status) - assert_equal(@test_data, result) - end - - def test_system_with_string - omit_if(windows?) - - result = nil - status = nil - EM.run { - EM.system("cat '#@filename'"){|out, state| - result = out - status = state.exitstatus - EM.stop - } - } - assert_equal(0, status) - assert_equal(@test_data, result) - end - - def teardown - File.unlink(@filename) - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_threaded_resource.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_threaded_resource.rb deleted file mode 100644 index 9bb39c6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_threaded_resource.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'em_test_helper' - -class TestThreadedResource < Test::Unit::TestCase - def object - @object ||= {} - end - - def resource - @resource = EM::ThreadedResource.new do - object - end - end - - def teardown - resource.shutdown - end - - def test_dispatch_completion - EM.run do - EM.add_timer(3) do - EM.stop - fail 'Resource dispatch timed out' - end - completion = resource.dispatch do |o| - o[:foo] = :bar - :foo - end - completion.callback do |result| - assert_equal :foo, result - EM.stop - end - completion.errback do |error| - EM.stop - fail "Unexpected error: #{error.message}" - end - end - assert_equal :bar, object[:foo] - end - - def test_dispatch_failure - completion = resource.dispatch do |o| - raise 'boom' - end - completion.errback do |error| - assert_kind_of RuntimeError, error - assert_equal 'boom', error.message - end - end - - def test_dispatch_threading - main = Thread.current - resource.dispatch do |o| - o[:dispatch_thread] = Thread.current - end - assert_not_equal main, object[:dispatch_thread] - end - - def test_shutdown - # This test should get improved sometime. The method returning thread is - # NOT an api that will be maintained. - assert !resource.shutdown.alive? - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_tick_loop.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_tick_loop.rb deleted file mode 100644 index 39d86b5..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_tick_loop.rb +++ /dev/null @@ -1,59 +0,0 @@ -require "test/unit" -require 'em_test_helper' - -class TestEmTickLoop < Test::Unit::TestCase - def test_em_tick_loop - i = 0 - EM.tick_loop { i += 1; EM.stop if i == 10 } - EM.run { EM.add_timer(1) { EM.stop } } - assert_equal i, 10 - end - - def test_tick_loop_on_stop - t = nil - tick_loop = EM.tick_loop { :stop } - tick_loop.on_stop { t = true } - EM.run { EM.next_tick { EM.stop } } - assert t - end - - def test_start_twice - i = 0 - s = 0 - tick_loop = EM.tick_loop { i += 1; :stop } - tick_loop.on_stop { s += 1; EM.stop } - EM.run { EM.next_tick { EM.stop } } - assert_equal 1, i - assert_equal 1, s - tick_loop.start - EM.run { EM.next_tick { EM.stop } } - assert_equal 2, i - assert_equal 1, s # stop callbacks are only called once - end - - def test_stop - i, s = 0, 0 - tick_loop = EM.tick_loop { i += 1 } - tick_loop.on_stop { s += 1 } - EM.run { EM.next_tick { tick_loop.stop; EM.next_tick { EM.stop } } } - assert tick_loop.stopped? - assert_equal 1, i - assert_equal 1, s - end - - def test_immediate_stops - s = 0 - tick_loop = EM::TickLoop.new { } - tick_loop.on_stop { s += 1 } - tick_loop.on_stop { s += 1 } - assert_equal 2, s - end - - def test_stopped - tick_loop = EM::TickLoop.new { } - assert tick_loop.stopped? - tick_loop.start - assert !tick_loop.stopped? - end - -end \ No newline at end of file diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_timers.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_timers.rb deleted file mode 100644 index 88b3b78..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_timers.rb +++ /dev/null @@ -1,130 +0,0 @@ -require 'em_test_helper' - -class TestTimers < Test::Unit::TestCase - - def test_timer_with_block - x = false - EM.run { - EM::Timer.new(0) { - x = true - EM.stop - } - } - assert x - end - - def test_timer_with_proc - x = false - EM.run { - EM::Timer.new(0, proc { - x = true - EM.stop - }) - } - assert x - end - - def test_timer_cancel - assert_nothing_raised do - EM.run { - timer = EM::Timer.new(0.01) { flunk "Timer was not cancelled." } - timer.cancel - - EM.add_timer(0.02) { EM.stop } - } - end - end - - def test_periodic_timer - x = 0 - EM.run { - EM::PeriodicTimer.new(0.01) do - x += 1 - EM.stop if x == 4 - end - } - - assert_equal 4, x - end - - def test_add_periodic_timer - x = 0 - EM.run { - t = EM.add_periodic_timer(0.01) do - x += 1 - EM.stop if x == 4 - end - assert t.respond_to?(:cancel) - } - assert_equal 4, x - end - - def test_periodic_timer_cancel - x = 0 - EM.run { - pt = EM::PeriodicTimer.new(0.01) { x += 1 } - pt.cancel - EM::Timer.new(0.02) { EM.stop } - } - assert_equal 0, x - end - - def test_add_periodic_timer_cancel - x = 0 - EM.run { - pt = EM.add_periodic_timer(0.01) { x += 1 } - EM.cancel_timer(pt) - EM.add_timer(0.02) { EM.stop } - } - assert_equal 0, x - end - - def test_periodic_timer_self_cancel - x = 0 - EM.run { - pt = EM::PeriodicTimer.new(0) { - x += 1 - if x == 4 - pt.cancel - EM.stop - end - } - } - assert_equal 4, x - end - - def test_oneshot_timer_large_future_value - large_value = 11948602000 - EM.run { - EM.add_timer(large_value) { EM.stop } - EM.add_timer(0.02) { EM.stop } - } - end - - # This test is only applicable to compiled versions of the reactor. - # Pure ruby and java versions have no built-in limit on the number of outstanding timers. - unless [:pure_ruby, :java].include? EM.library_type - def test_timer_change_max_outstanding - defaults = EM.get_max_timers - EM.set_max_timers(100) - - one_hundred_one_timers = lambda do - 101.times { EM.add_timer(0.01) {} } - EM.stop - end - - assert_raises(RuntimeError) do - EM.run( &one_hundred_one_timers ) - end - - EM.set_max_timers( 101 ) - - assert_nothing_raised do - EM.run( &one_hundred_one_timers ) - end - ensure - EM.set_max_timers(defaults) - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ud.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ud.rb deleted file mode 100644 index 3559756..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_ud.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'em_test_helper' - -class TestUserDefinedEvents < Test::Unit::TestCase - - def test_a - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_unbind_reason.rb b/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_unbind_reason.rb deleted file mode 100644 index ff9193e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/eventmachine-1.2.7/tests/test_unbind_reason.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'em_test_helper' - -class TestUnbindReason < Test::Unit::TestCase - - class StubConnection < EM::Connection - attr_reader :error - def unbind(reason = nil) - @error = reason - EM.stop - end - end - - # RFC 5737 Address Blocks Reserved for Documentation - def test_connect_timeout - conn = nil - EM.run do - conn = EM.connect '192.0.2.0', 80, StubConnection - conn.pending_connect_timeout = 1 - end - assert_equal Errno::ETIMEDOUT, conn.error - end - - def test_connect_refused - pend('FIXME: this test is broken on Windows') if windows? - conn = nil - EM.run do - conn = EM.connect '127.0.0.1', 12388, StubConnection - end - assert_equal Errno::ECONNREFUSED, conn.error - end - - def test_optional_argument - pend('FIXME: this test is broken on Windows') if windows? - conn = nil - EM.run do - conn = EM.connect '127.0.0.1', 12388, StubConnection - end - assert_equal Errno::ECONNREFUSED, conn.error - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/.yardopts b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/.yardopts deleted file mode 100644 index 0a782de..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/.yardopts +++ /dev/null @@ -1 +0,0 @@ ---title 'Ruby Public Suffix API Documentation' diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/2.0-Upgrade.md b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/2.0-Upgrade.md deleted file mode 100644 index 1a10bfb..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/2.0-Upgrade.md +++ /dev/null @@ -1,52 +0,0 @@ -# Welcome to PublicSuffix 2.0! - -PublicSuffix 2.0 contains a rewritten internal representation and comparison logic, that drastically increases the lookup performance. The new version also changes several internal and external API. - -This document documents the most relevant changes to help you upgrading from PublicSuffix 1.0 to 2.0. - -## What's New - -- The library is now 100% compliants with the official PublicSuffix tests. The major breaking change you may experience, is that if a domain passed as input doesn't match any rule, the rule `*` is assumed. You can override this behavior by passing a custom default rule with the `default_rule` option. The old behavior can be restored by passing `default_rule: nil`. -- `PublicSuffix.domain` is a new method that parses the input and returns the domain (combination of second level domain + suffix). This is a convenient helper to parse a domain name, for example when you need to determine the cookie or SSL scope. -- Added the ability to disable the use of private domains either at runtime, in addition to the ability to not load the private domains section when reading the list (`private_domains: false`). This feature also superseded the `private_domains` class-level attribute, that is no longer available. - -## Upgrade - -When upgrading, here's the most relevant changes to keep an eye on: - -- Several futile utility helpers were removed, such as `Domain#rule`, `Domain#is_a_domain?`, `Domain#is_a_subdomain?`, `Domain#valid?`. You can easily obtain the same result by having a custom method that reconstructs the logic, and/or calling `PublicSuffix.{domain|parse}(domain.to_s)`. -- `PublicSuffix::List.private_domains` is no longer available. Instead, you now have two ways to enable/disable the private domains: - - 1. At runtime, by using the `ignore_private` option - - ```ruby - PublicSuffix.domain("something.blogspot.com", ignore_private: true) - ``` - - 1. Loading a filtered list: - - ```ruby - # Disable support for private TLDs - PublicSuffix::List.default = PublicSuffix::List.parse(File.read(PublicSuffix::List::DEFAULT_LIST_PATH), private_domains: false) - # => "blogspot.com" - PublicSuffix.domain("something.blogspot.com") - # => "blogspot.com" - ``` -- Now that the library is 100% compliant with the official PublicSuffix algorithm, if a domain passed as input doesn't match any rule, the wildcard rule `*` is assumed. This means that unlisted TLDs will be considered valid by default, when they would have been invalid in 1.x. However, you can override this behavior to emulate the 1.x behavior if needed: - - ```ruby - # 1.x: - - PublicSuffix.valid?("google.commm") - # => false - - # 2.x: - - PublicSuffix.valid?("google.commm") - # => true - - # Overriding 2.x behavior if needed: - - PublicSuffix.valid?("google.commm", default_rule: nil) - # => false - ```` diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/CHANGELOG.md b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/CHANGELOG.md deleted file mode 100644 index d03a01e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/CHANGELOG.md +++ /dev/null @@ -1,462 +0,0 @@ -# Changelog - -This project uses [Semantic Versioning 2.0.0](https://semver.org/). - -## 5.1.1 - -No significant changes. Releasing a mini version to address 5.1.0 release with major ruby requirement change (GH-315). - - -## 5.0.5 - -### Changed - -- Updated definitions. - -## 5.0.4 - -### Changed - -- Reduced .gem file size (GH-258). [Thanks @ybiquitous] -- Updated definitions. - -## 5.0.3 - -### Fixed - -- Fixed automated release workflow. - -## 5.0.2 - -### Changed - -- Updated definitions. - -## 5.0.1 - -### Changed - -- Updated definitions. - - -## 5.0.0 - -### Changed - -- Minimum Ruby version is 2.6 - -- Updated definitions. - - -## 4.0.7 - -### Fixes - -- Fixed YARD rake task (GH-179) - -### Changed - -- Updated definitions. - - -## 4.0.6 - -### Changed - -- Updated definitions. - - -## 4.0.5 - -### Changed - -- Updated definitions. - - -## 4.0.4 - -### Changed - -- Updated definitions. - - -## 4.0.3 - -### Fixed - -- Fixed 2.7 deprecations and warnings (GH-167). [Thanks @BrianHawley] - - -## 4.0.2 - -### Changed - -- Updated definitions. - - -## 4.0.1 - -### Changed - -- Updated definitions. - - -## 4.0.0 - -### Changed - -- Minimum Ruby version is 2.3 - - -## Release 3.1.1 - -- CHANGED: Updated definitions. -- CHANGED: Rolled back support for Ruby 2.3 (GH-161, GH-162) - -IMPORTANT: 3.x is the latest version compatible with Ruby 2.1 and Ruby 2.2. - - -## Release 3.1.0 - -- CHANGED: Updated definitions. -- CHANGED: Minimum Ruby version is 2.3 -- CHANGED: Upgraded to Bundler 2.x - - -## Release 3.0.3 - -- CHANGED: Updated definitions. - - -## Release 3.0.2 - -- CHANGED: Updated definitions. - - -## Release 3.0.1 - -- CHANGED: Updated definitions. -- CHANGED: Improve performance and avoid allocation (GH-146). [Thanks @robholland] - - -## Release 3.0.0 - -This new version includes a major redesign of the library internals, with the goal to drastically -improve the lookup time while reducing storage space. - -For this reason, several public methods that are no longer applicable have been deprecated -and/or removed. You can find more information at GH-133. - -- CHANGED: Updated definitions. -- CHANGED: Dropped support for Ruby < 2.1 -- CHANGED: `PublicSuffix::List#rules` is now protected. You should not rely on it as the internal rule representation is subject to change to optimize performances. -- CHANGED: Removed `PublicSuffix::List.clear`, it was an unnecessary accessor method. Use `PublicSuffix::List.default = nil` if you **really** need to reset the default list. You shouldn't. -- CHANGED: `PublicSuffix::List#select` is now private. You should not use it, instead use `PublicSuffix::List#find`. -- CHANGED: `PublicSuffix::List` no longer implements Enumerable. Instead, use `#each` to loop over, or get an Enumerator. -- CHANGED: Redesigned internal list storage and lookup algorithm to achieve O(1) lookup time (see GH-133). - - -## Release 2.0.5 - -- CHANGED: Updated definitions. -- CHANGED: Initialization performance improvements (GH-128). [Thanks @casperisfine] - - -## Release 2.0.4 - -- FIXED: Fix a bug that caused the GEM to be published with the wrong version number in the gemspec (GH-121). - -- CHANGED: Updated definitions. - - -## Release 2.0.3 - -- CHANGED: Updated definitions. - - -## Release 2.0.2 - -- CHANGED: Updated definitions. - - -## Release 2.0.1 - -- FIXED: Fix bug that prevented .valid? to reset the default rule - - -## Release 2.0.0 - -- NEW: Added PublicSuffix.domain # => sld.tld -- NEW: Added the ability to disable the use of private domains either at runtime, in addition to the ability to not load the private domains section when reading the list (`private_domains: false`). This feature also superseded the `private_domains` class-level attribute, that is no longer available. - -- CHANGED: Considerable performance improvements (GH-92) -- CHANGED: Updated definitions. -- CHANGED: Removed deprecated PublicSuffix::InvalidDomain exception -- CHANGED: If the suffix is now listed, then the prevaling rule is "*" as defined by the PSL algorithm (GH-91) -- CHANGED: Input validation is performed only if you call `PublicSuffix.parse` or `PublicSuffix.list` -- CHANGED: Input with leading dot is invalid per PSL acceptance tests -- CHANGED: Removed `private_domains` class-level attribute. It is replaced by the `private_domains: false` option in the list parse method. -- CHANGED: The default list now assumes you use UTF-8 for reading the input (GH-94), - -- REMOVED: Removed futile utility helpers such as `Domain#rule`, `Domain#is_a_domain?`, `Domain#is_a_subdomain?`, `Domain#valid?`. You can easily obtain the same result by having a custom method that reconstructs the logic, and/or calling `PublicSuffix.{domain|parse}(domain.to_s)`. - - -## Release 1.5.3 - -- FIXED: Don't duplicate rule indices when creating index (GH-77). [Thanks @ags] - -- CHANGED: Updated definitions. - - -## Release 1.5.2 - -- CHANGED: Updated definitions. - - -## Release 1.5.1 - -- FIXED: Ignore case for parsing and validating (GH-62) - -- CHANGED: Updated definitions. - - -## Release 1.5.0 - -- CHANGED: Dropped support for Ruby < 2.0 - -- CHANGED: Updated definitions. - - -## Release 1.4.6 - -- CHANGED: Updated definitions. - - -## Release 1.4.5 - -- CHANGED: Updated definitions. - - -## Release 1.4.4 - -- CHANGED: Updated definitions. - - -## Release 1.4.3 - -- CHANGED: Updated definitions. - - -## Release 1.4.2 - -- CHANGED: Updated definitions. - - -## Release 1.4.1 - -- CHANGED: Updated definitions. - - -## Release 1.4.0 - -- CHANGED: Moved the definitions in the lib folder. - -- CHANGED: Updated definitions. - - -## Release 1.3.3 - -- CHANGED: Updated definitions. - - -## Release 1.3.2 - -- CHANGED: Updated definitions. - - -## Release 1.3.1 - -- CHANGED: Updated definitions. - - -## Release 1.3.0 - -- NEW: Ability to skip Private Domains (GH-28). [Thanks @rb2k] - -- CHANGED: Updated definitions. - - -## Release 1.2.1 - -- CHANGED: Updated definitions. - - -## Release 1.2.0 - -- NEW: Allow a custom List on `PublicSuffix.parse` (GH-26). [Thanks @itspriddle] - -- FIXED: PublicSuffix.parse and PublicSuffix.valid? crashes when input is nil (GH-20). - -- CHANGED: Updated definitions. - - -## Release 1.1.3 - -- CHANGED: Updated definitions. - - -## Release 1.1.2 - -- CHANGED: Updated definitions. - - -## Release 1.1.1 - -- CHANGED: Updated definitions. - - -## Release 1.1.0 - -- FIXED: #valid? and #parse consider URIs as valid domains (GH-15) - -- CHANGED: Updated definitions. - -- CHANGED: Removed deprecatd PublicSuffixService::RuleList. - - -## Release 1.0.0 - -- CHANGED: Updated definitions. - - -## Release 1.0.0.rc1 - -The library is now known as PublicSuffix. - - -## Release 0.9.1 - -- CHANGED: Renamed PublicSuffixService::RuleList to PublicSuffixService::List. - -- CHANGED: Renamed PublicSuffixService::List#list to PublicSuffixService::List#rules. - -- CHANGED: Renamed PublicSuffixService to PublicSuffix. - -- CHANGED: Updated definitions. - - -## Release 0.9.0 - -- CHANGED: Minimum Ruby version increased to Ruby 1.8.7. - -- CHANGED: rake/gempackagetask is deprecated. Use rubygems/package_task instead. - - -## Release 0.8.4 - -- FIXED: Reverted bugfix for issue #12 for Ruby 1.8.6. - This is the latest version compatible with Ruby 1.8.6. - - -## Release 0.8.3 - -- FIXED: Fixed ArgumentError: invalid byte sequence in US-ASCII with Ruby 1.9.2 (#12). - -- CHANGED: Updated definitions (#11). - -- CHANGED: Renamed definitions.txt to definitions.dat. - - -## Release 0.8.2 - -- NEW: Added support for rubygems-test. - -- CHANGED: Integrated Bundler. - -- CHANGED: Updated definitions. - - -## Release 0.8.1 - -- FIXED: The files in the release 0.8.0 have wrong permission 600 and can't be loaded (#10). - - -## Release 0.8.0 - -- CHANGED: Update public suffix list to d1a5599b49fa 2010-10-25 15:10 +0100 (#9) - -- NEW: Add support for Fully Qualified Domain Names (#7) - - -## Release 0.7.0 - -- CHANGED: Using YARD to document the code instead of RDoc. - -- FIXED: RuleList cache is not recreated when a new rule is appended to the list (#6) - -- FIXED: PublicSuffixService.valid? should return false if the domain is not defined or not allowed (#4, #5) - - -## Release 0.6.0 - -- NEW: PublicSuffixService.parse raises DomainNotAllowed when trying to parse a domain name - which exists, but is not allowed by the current definition list (#3) - - PublicSuffixService.parse("nic.do") - # => PublicSuffixService::DomainNotAllowed - -- CHANGED: Renamed PublicSuffixService::InvalidDomain to PublicSuffixService::DomainInvalid - - -## Release 0.5.2 - -- CHANGED: Update public suffix list to 248ea690d671 2010-09-16 18:02 +0100 - - -## Release 0.5.1 - -- CHANGED: Update public suffix list to 14dc66dd53c1 2010-09-15 17:09 +0100 - - -## Release 0.5.0 - -- CHANGED: Improve documentation for Domain#domain and Domain#subdomain (#1). - -- CHANGED: Performance improvements (#2). - - -## Release 0.4.0 - -- CHANGED: Rename library from DomainName to PublicSuffixService to reduce the probability of name conflicts. - - -## Release 0.3.1 - -- Deprecated DomainName library. - - -## Release 0.3.0 - -- CHANGED: DomainName#domain and DomainName#subdomain are no longer alias of Domain#sld and Domain#tld. - -- CHANGED: Removed DomainName#labels and decoupled Rule from DomainName. - -- CHANGED: DomainName#valid? no longer instantiates new DomainName objects. This means less overhead. - -- CHANGED: Refactoring the entire DomainName API. Removed the internal on-the-fly parsing. Added a bunch of new methods to check and validate the DomainName. - - -## Release 0.2.0 - -- NEW: DomainName#valid? - -- NEW: DomainName#parse and DomainName#parse! - -- NEW: DomainName#valid_domain? and DomainName#valid_subdomain? - -- CHANGED: Make sure RuleList lookup is only performed once. - - -## Release 0.1.0 - -- Initial version diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/LICENSE.txt b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/LICENSE.txt deleted file mode 100644 index 32b1ac8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2024 Simone Carletti - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/README.md b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/README.md deleted file mode 100644 index 1b9537c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/README.md +++ /dev/null @@ -1,224 +0,0 @@ -# Public Suffix for Ruby - -PublicSuffix is a Ruby domain name parser based on the [Public Suffix List](https://publicsuffix.org/). - -[![Build Status](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml) -[![Tidelift dependencies](https://tidelift.com/badges/package/rubygems/public_suffix)](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=enterprise) - - -## Links - -- [Homepage](https://simonecarletti.com/code/publicsuffix-ruby) -- [Repository](https://github.com/weppos/publicsuffix-ruby) -- [API Documentation](https://rubydoc.info/gems/public_suffix) -- [Introducing the Public Suffix List library for Ruby](https://simonecarletti.com/blog/2010/06/public-suffix-list-library-for-ruby/) - - -## Requirements - -PublicSuffix requires **Ruby >= 2.6**. For an older versions of Ruby use a previous release. - - -## Installation - -You can install the gem manually: - -```shell -gem install public_suffix -``` - -Or use Bundler and define it as a dependency in your `Gemfile`: - -```ruby -gem 'public_suffix' -``` - -If you are upgrading to 2.0, see [2.0-Upgrade.md](2.0-Upgrade.md). - -## Usage - -Extract the domain out from a name: - -```ruby -PublicSuffix.domain("google.com") -# => "google.com" -PublicSuffix.domain("www.google.com") -# => "google.com" -PublicSuffix.domain("www.google.co.uk") -# => "google.co.uk" -``` - -Parse a domain without subdomains: - -```ruby -domain = PublicSuffix.parse("google.com") -# => # -domain.tld -# => "com" -domain.sld -# => "google" -domain.trd -# => nil -domain.domain -# => "google.com" -domain.subdomain -# => nil -``` - -Parse a domain with subdomains: - -```ruby -domain = PublicSuffix.parse("www.google.com") -# => # -domain.tld -# => "com" -domain.sld -# => "google" -domain.trd -# => "www" -domain.domain -# => "google.com" -domain.subdomain -# => "www.google.com" -``` - -Simple validation example: - -```ruby -PublicSuffix.valid?("google.com") -# => true - -PublicSuffix.valid?("www.google.com") -# => true - -# Explicitly forbidden, it is listed as a private domain -PublicSuffix.valid?("blogspot.com") -# => false - -# Unknown/not-listed TLD domains are valid by default -PublicSuffix.valid?("example.tldnotlisted") -# => true -``` - -Strict validation (without applying the default * rule): - -```ruby -PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) -# => false -``` - - -## Fully Qualified Domain Names - -This library automatically recognizes Fully Qualified Domain Names. A FQDN is a domain name that end with a trailing dot. - -```ruby -# Parse a standard domain name -PublicSuffix.domain("www.google.com") -# => "google.com" - -# Parse a fully qualified domain name -PublicSuffix.domain("www.google.com.") -# => "google.com" -``` - -## Private domains - -This library has support for switching off support for private (non-ICANN). - -```ruby -# Extract a domain including private domains (by default) -PublicSuffix.domain("something.blogspot.com") -# => "something.blogspot.com" - -# Extract a domain excluding private domains -PublicSuffix.domain("something.blogspot.com", ignore_private: true) -# => "blogspot.com" - -# It also works for #parse and #valid? -PublicSuffix.parse("something.blogspot.com", ignore_private: true) -PublicSuffix.valid?("something.blogspot.com", ignore_private: true) -``` - -If you don't care about private domains at all, it's more efficient to exclude them when the list is parsed: - -```ruby -# Disable support for private TLDs -PublicSuffix::List.default = PublicSuffix::List.parse(File.read(PublicSuffix::List::DEFAULT_LIST_PATH), private_domains: false) -# => "blogspot.com" -PublicSuffix.domain("something.blogspot.com") -# => "blogspot.com" -``` - -## Add domain to list - -If you want to manually add a domain to the list just run: - -```ruby -PublicSuffix::List.default << PublicSuffix::Rule.factory('onmicrosoft.com') -``` - -## What is the Public Suffix List? - -The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative to provide an accurate list of domain name suffixes. - -The Public Suffix List is an initiative of the Mozilla Project, but is maintained as a community resource. It is available for use in any software, but was originally created to meet the needs of browser manufacturers. - -A "public suffix" is one under which Internet users can directly register names. Some examples of public suffixes are ".com", ".co.uk" and "pvt.k12.wy.us". The Public Suffix List is a list of all known public suffixes. - - -## Why the Public Suffix List is better than any available Regular Expression parser? - -Previously, browsers used an algorithm which basically only denied setting wide-ranging cookies for top-level domains with no dots (e.g. com or org). However, this did not work for top-level domains where only third-level registrations are allowed (e.g. co.uk). In these cases, websites could set a cookie for co.uk which will be passed onto every website registered under co.uk. - -Clearly, this was a security risk as it allowed websites other than the one setting the cookie to read it, and therefore potentially extract sensitive information. - -Since there is no algorithmic method of finding the highest level at which a domain may be registered for a particular top-level domain (the policies differ with each registry), the only method is to create a list of all top-level domains and the level at which domains can be registered. This is the aim of the effective TLD list. - -As well as being used to prevent cookies from being set where they shouldn't be, the list can also potentially be used for other applications where the registry controlled and privately controlled parts of a domain name need to be known, for example when grouping by top-level domains. - -Source: https://wiki.mozilla.org/Public_Suffix_List - -Not convinced yet? Check out [this real world example](https://stackoverflow.com/q/288810/123527). - - -## Does PublicSuffix make requests to Public Suffix List website? - -No. PublicSuffix comes with a bundled list. It does not make any HTTP requests to parse or validate a domain. - - -## Support - -Library documentation is auto-generated from the [README](https://github.com/weppos/publicsuffix-ruby/blob/master/README.md) and the source code, and it's available at https://rubydoc.info/gems/public_suffix. - -- The PublicSuffix bug tracker is here: https://github.com/weppos/publicsuffix-ruby/issues -- The PublicSuffix code repository is here: https://github.com/weppos/publicsuffix-ruby. Contributions are welcome! Please include tests and/or feature coverage for every patch, and create a topic branch for every separate change you make. - -[Consider subscribing to Tidelift which provides Enterprise support for this project](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=readme) as part of the Tidelift Subscription. Tidelift subscriptions also help the maintainers by funding the project, which in turn allows us to ship releases, bugfixes, and security updates more often. - - -## Security and Vulnerability Reporting - -Full information and description of our security policy please visit [`SECURITY.md`](SECURITY.md) - - -## Changelog - -See the [CHANGELOG.md](CHANGELOG.md) file for details. - - -## License - -Copyright (c) 2009-2024 Simone Carletti. This is Free Software distributed under the MIT license. - -The [Public Suffix List source](https://publicsuffix.org/list/) is subject to the terms of the Mozilla Public License, v. 2.0. - -## Definitions - -tld = Top level domain, this is in reference to the last segment of a domain, sometimes the part that is directly after the "dot" symbol. For example, `mozilla.org`, the `.org` portion is the tld. - -sld = Second level domain, a domain that is directly below a top-level domain. For example, in `https://www.mozilla.org/en-US/`, `mozilla` is the second-level domain of the .org tld. - -trd = Transit routing domain, or known as a subdomain. This is the part of the domain that is before the sld or root domain. For example, in `https://www.mozilla.org/en-US/`, `www` is the trd. - -FQDN = Fully Qualified Domain Names, are domain names that are written with the hostname and the domain name, and include the top-level domain, the format looks like `[hostname].[domain].[tld].` for ex. `[www].[mozilla].[org]`. diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/SECURITY.md b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/SECURITY.md deleted file mode 100644 index 5cbbec7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/SECURITY.md +++ /dev/null @@ -1,25 +0,0 @@ -# Security Policy - -## Supported Versions - -Security updates are provided only for the current minor version. - -If you are using a previous minor version, we recommend to upgrade to the current minor version. -This project uses [semantic versioning](https://semver.org/), therefore you can upgrade to a more recent minor version without incurring into breaking changes. - -Exceptionally, we may support previous minor versions upon request if there are significant reasons preventing to immediately switch the latest minor version. - -Older major versions are no longer supported. - - -## Reporting a Vulnerability - -To make a report, please email weppos@weppos.net. - -> [!IMPORTANT] -> Please consider encrypting your report with GPG using the key [0x420da82a989398df](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x420da82a989398df). - - -## Tracking Security Updates - -Information about security vulnerabilities are published in the [Security Advisories](https://github.com/weppos/publicsuffix-ruby/security/advisories) page. diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/data/list.txt b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/data/list.txt deleted file mode 100644 index 291197f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/data/list.txt +++ /dev/null @@ -1,15697 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -// Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, -// rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. - -// Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. - -// ===BEGIN ICANN DOMAINS=== - -// ac : http://nic.ac/rules.htm -ac -com.ac -edu.ac -gov.ac -net.ac -mil.ac -org.ac - -// ad : https://en.wikipedia.org/wiki/.ad -ad -nom.ad - -// ae : https://tdra.gov.ae/en/aeda/ae-policies -ae -co.ae -net.ae -org.ae -sch.ae -ac.ae -gov.ae -mil.ae - -// aero : see https://www.information.aero/index.php?id=66 -aero -accident-investigation.aero -accident-prevention.aero -aerobatic.aero -aeroclub.aero -aerodrome.aero -agents.aero -aircraft.aero -airline.aero -airport.aero -air-surveillance.aero -airtraffic.aero -air-traffic-control.aero -ambulance.aero -amusement.aero -association.aero -author.aero -ballooning.aero -broker.aero -caa.aero -cargo.aero -catering.aero -certification.aero -championship.aero -charter.aero -civilaviation.aero -club.aero -conference.aero -consultant.aero -consulting.aero -control.aero -council.aero -crew.aero -design.aero -dgca.aero -educator.aero -emergency.aero -engine.aero -engineer.aero -entertainment.aero -equipment.aero -exchange.aero -express.aero -federation.aero -flight.aero -fuel.aero -gliding.aero -government.aero -groundhandling.aero -group.aero -hanggliding.aero -homebuilt.aero -insurance.aero -journal.aero -journalist.aero -leasing.aero -logistics.aero -magazine.aero -maintenance.aero -media.aero -microlight.aero -modelling.aero -navigation.aero -parachuting.aero -paragliding.aero -passenger-association.aero -pilot.aero -press.aero -production.aero -recreation.aero -repbody.aero -res.aero -research.aero -rotorcraft.aero -safety.aero -scientist.aero -services.aero -show.aero -skydiving.aero -software.aero -student.aero -trader.aero -trading.aero -trainer.aero -union.aero -workinggroup.aero -works.aero - -// af : http://www.nic.af/help.jsp -af -gov.af -com.af -org.af -net.af -edu.af - -// ag : http://www.nic.ag/prices.htm -ag -com.ag -org.ag -net.ag -co.ag -nom.ag - -// ai : http://nic.com.ai/ -ai -off.ai -com.ai -net.ai -org.ai - -// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 -al -com.al -edu.al -gov.al -mil.al -net.al -org.al - -// am : https://www.amnic.net/policy/en/Policy_EN.pdf -am -co.am -com.am -commune.am -net.am -org.am - -// ao : https://en.wikipedia.org/wiki/.ao -// http://www.dns.ao/REGISTR.DOC -ao -ed.ao -gv.ao -og.ao -co.ao -pb.ao -it.ao - -// aq : https://en.wikipedia.org/wiki/.aq -aq - -// ar : https://nic.ar/es/nic-argentina/normativa -ar -bet.ar -com.ar -coop.ar -edu.ar -gob.ar -gov.ar -int.ar -mil.ar -musica.ar -mutual.ar -net.ar -org.ar -senasa.ar -tur.ar - -// arpa : https://en.wikipedia.org/wiki/.arpa -// Confirmed by registry 2008-06-18 -arpa -e164.arpa -in-addr.arpa -ip6.arpa -iris.arpa -uri.arpa -urn.arpa - -// as : https://en.wikipedia.org/wiki/.as -as -gov.as - -// asia : https://en.wikipedia.org/wiki/.asia -asia - -// at : https://en.wikipedia.org/wiki/.at -// Confirmed by registry 2008-06-17 -at -ac.at -co.at -gv.at -or.at -sth.ac.at - -// au : https://en.wikipedia.org/wiki/.au -// http://www.auda.org.au/ -au -// 2LDs -com.au -net.au -org.au -edu.au -gov.au -asn.au -id.au -// Historic 2LDs (closed to new registration, but sites still exist) -info.au -conf.au -oz.au -// CGDNs - http://www.cgdn.org.au/ -act.au -nsw.au -nt.au -qld.au -sa.au -tas.au -vic.au -wa.au -// 3LDs -act.edu.au -catholic.edu.au -// eq.edu.au - Removed at the request of the Queensland Department of Education -nsw.edu.au -nt.edu.au -qld.edu.au -sa.edu.au -tas.edu.au -vic.edu.au -wa.edu.au -// act.gov.au Bug 984824 - Removed at request of Greg Tankard -// nsw.gov.au Bug 547985 - Removed at request of -// nt.gov.au Bug 940478 - Removed at request of Greg Connors -qld.gov.au -sa.gov.au -tas.gov.au -vic.gov.au -wa.gov.au -// 4LDs -// education.tas.edu.au - Removed at the request of the Department of Education Tasmania -schools.nsw.edu.au - -// aw : https://en.wikipedia.org/wiki/.aw -aw -com.aw - -// ax : https://en.wikipedia.org/wiki/.ax -ax - -// az : https://en.wikipedia.org/wiki/.az -az -com.az -net.az -int.az -gov.az -org.az -edu.az -info.az -pp.az -mil.az -name.az -pro.az -biz.az - -// ba : http://nic.ba/users_data/files/pravilnik_o_registraciji.pdf -ba -com.ba -edu.ba -gov.ba -mil.ba -net.ba -org.ba - -// bb : https://en.wikipedia.org/wiki/.bb -bb -biz.bb -co.bb -com.bb -edu.bb -gov.bb -info.bb -net.bb -org.bb -store.bb -tv.bb - -// bd : https://en.wikipedia.org/wiki/.bd -*.bd - -// be : https://en.wikipedia.org/wiki/.be -// Confirmed by registry 2008-06-08 -be -ac.be - -// bf : https://en.wikipedia.org/wiki/.bf -bf -gov.bf - -// bg : https://en.wikipedia.org/wiki/.bg -// https://www.register.bg/user/static/rules/en/index.html -bg -a.bg -b.bg -c.bg -d.bg -e.bg -f.bg -g.bg -h.bg -i.bg -j.bg -k.bg -l.bg -m.bg -n.bg -o.bg -p.bg -q.bg -r.bg -s.bg -t.bg -u.bg -v.bg -w.bg -x.bg -y.bg -z.bg -0.bg -1.bg -2.bg -3.bg -4.bg -5.bg -6.bg -7.bg -8.bg -9.bg - -// bh : https://en.wikipedia.org/wiki/.bh -bh -com.bh -edu.bh -net.bh -org.bh -gov.bh - -// bi : https://en.wikipedia.org/wiki/.bi -// http://whois.nic.bi/ -bi -co.bi -com.bi -edu.bi -or.bi -org.bi - -// biz : https://en.wikipedia.org/wiki/.biz -biz - -// bj : https://nic.bj/bj-suffixes.txt -// submitted by registry -bj -africa.bj -agro.bj -architectes.bj -assur.bj -avocats.bj -co.bj -com.bj -eco.bj -econo.bj -edu.bj -info.bj -loisirs.bj -money.bj -net.bj -org.bj -ote.bj -resto.bj -restaurant.bj -tourism.bj -univ.bj - -// bm : http://www.bermudanic.bm/dnr-text.txt -bm -com.bm -edu.bm -gov.bm -net.bm -org.bm - -// bn : http://www.bnnic.bn/faqs -bn -com.bn -edu.bn -gov.bn -net.bn -org.bn - -// bo : https://nic.bo/delegacion2015.php#h-1.10 -bo -com.bo -edu.bo -gob.bo -int.bo -org.bo -net.bo -mil.bo -tv.bo -web.bo -// Social Domains -academia.bo -agro.bo -arte.bo -blog.bo -bolivia.bo -ciencia.bo -cooperativa.bo -democracia.bo -deporte.bo -ecologia.bo -economia.bo -empresa.bo -indigena.bo -industria.bo -info.bo -medicina.bo -movimiento.bo -musica.bo -natural.bo -nombre.bo -noticias.bo -patria.bo -politica.bo -profesional.bo -plurinacional.bo -pueblo.bo -revista.bo -salud.bo -tecnologia.bo -tksat.bo -transporte.bo -wiki.bo - -// br : http://registro.br/dominio/categoria.html -// Submitted by registry -br -9guacu.br -abc.br -adm.br -adv.br -agr.br -aju.br -am.br -anani.br -aparecida.br -app.br -arq.br -art.br -ato.br -b.br -barueri.br -belem.br -bhz.br -bib.br -bio.br -blog.br -bmd.br -boavista.br -bsb.br -campinagrande.br -campinas.br -caxias.br -cim.br -cng.br -cnt.br -com.br -contagem.br -coop.br -coz.br -cri.br -cuiaba.br -curitiba.br -def.br -des.br -det.br -dev.br -ecn.br -eco.br -edu.br -emp.br -enf.br -eng.br -esp.br -etc.br -eti.br -far.br -feira.br -flog.br -floripa.br -fm.br -fnd.br -fortal.br -fot.br -foz.br -fst.br -g12.br -geo.br -ggf.br -goiania.br -gov.br -// gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil -ac.gov.br -al.gov.br -am.gov.br -ap.gov.br -ba.gov.br -ce.gov.br -df.gov.br -es.gov.br -go.gov.br -ma.gov.br -mg.gov.br -ms.gov.br -mt.gov.br -pa.gov.br -pb.gov.br -pe.gov.br -pi.gov.br -pr.gov.br -rj.gov.br -rn.gov.br -ro.gov.br -rr.gov.br -rs.gov.br -sc.gov.br -se.gov.br -sp.gov.br -to.gov.br -gru.br -imb.br -ind.br -inf.br -jab.br -jampa.br -jdf.br -joinville.br -jor.br -jus.br -leg.br -lel.br -log.br -londrina.br -macapa.br -maceio.br -manaus.br -maringa.br -mat.br -med.br -mil.br -morena.br -mp.br -mus.br -natal.br -net.br -niteroi.br -*.nom.br -not.br -ntr.br -odo.br -ong.br -org.br -osasco.br -palmas.br -poa.br -ppg.br -pro.br -psc.br -psi.br -pvh.br -qsl.br -radio.br -rec.br -recife.br -rep.br -ribeirao.br -rio.br -riobranco.br -riopreto.br -salvador.br -sampa.br -santamaria.br -santoandre.br -saobernardo.br -saogonca.br -seg.br -sjc.br -slg.br -slz.br -sorocaba.br -srv.br -taxi.br -tc.br -tec.br -teo.br -the.br -tmp.br -trd.br -tur.br -tv.br -udi.br -vet.br -vix.br -vlog.br -wiki.br -zlg.br - -// bs : http://www.nic.bs/rules.html -bs -com.bs -net.bs -org.bs -edu.bs -gov.bs - -// bt : https://en.wikipedia.org/wiki/.bt -bt -com.bt -edu.bt -gov.bt -net.bt -org.bt - -// bv : No registrations at this time. -// Submitted by registry -bv - -// bw : https://en.wikipedia.org/wiki/.bw -// http://www.gobin.info/domainname/bw.doc -// list of other 2nd level tlds ? -bw -co.bw -org.bw - -// by : https://en.wikipedia.org/wiki/.by -// http://tld.by/rules_2006_en.html -// list of other 2nd level tlds ? -by -gov.by -mil.by -// Official information does not indicate that com.by is a reserved -// second-level domain, but it's being used as one (see www.google.com.by and -// www.yahoo.com.by, for example), so we list it here for safety's sake. -com.by - -// http://hoster.by/ -of.by - -// bz : https://en.wikipedia.org/wiki/.bz -// http://www.belizenic.bz/ -bz -com.bz -net.bz -org.bz -edu.bz -gov.bz - -// ca : https://en.wikipedia.org/wiki/.ca -ca -// ca geographical names -ab.ca -bc.ca -mb.ca -nb.ca -nf.ca -nl.ca -ns.ca -nt.ca -nu.ca -on.ca -pe.ca -qc.ca -sk.ca -yk.ca -// gc.ca: https://en.wikipedia.org/wiki/.gc.ca -// see also: http://registry.gc.ca/en/SubdomainFAQ -gc.ca - -// cat : https://en.wikipedia.org/wiki/.cat -cat - -// cc : https://en.wikipedia.org/wiki/.cc -cc - -// cd : https://en.wikipedia.org/wiki/.cd -// see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1 -cd -gov.cd - -// cf : https://en.wikipedia.org/wiki/.cf -cf - -// cg : https://en.wikipedia.org/wiki/.cg -cg - -// ch : https://en.wikipedia.org/wiki/.ch -ch - -// ci : https://en.wikipedia.org/wiki/.ci -// http://www.nic.ci/index.php?page=charte -ci -org.ci -or.ci -com.ci -co.ci -edu.ci -ed.ci -ac.ci -net.ci -go.ci -asso.ci -aéroport.ci -int.ci -presse.ci -md.ci -gouv.ci - -// ck : https://en.wikipedia.org/wiki/.ck -*.ck -!www.ck - -// cl : https://www.nic.cl -// Confirmed by .CL registry -cl -co.cl -gob.cl -gov.cl -mil.cl - -// cm : https://en.wikipedia.org/wiki/.cm plus bug 981927 -cm -co.cm -com.cm -gov.cm -net.cm - -// cn : https://en.wikipedia.org/wiki/.cn -// Submitted by registry -cn -ac.cn -com.cn -edu.cn -gov.cn -net.cn -org.cn -mil.cn -公司.cn -网络.cn -網絡.cn -// cn geographic names -ah.cn -bj.cn -cq.cn -fj.cn -gd.cn -gs.cn -gz.cn -gx.cn -ha.cn -hb.cn -he.cn -hi.cn -hl.cn -hn.cn -jl.cn -js.cn -jx.cn -ln.cn -nm.cn -nx.cn -qh.cn -sc.cn -sd.cn -sh.cn -sn.cn -sx.cn -tj.cn -xj.cn -xz.cn -yn.cn -zj.cn -hk.cn -mo.cn -tw.cn - -// co : https://en.wikipedia.org/wiki/.co -// Submitted by registry -co -arts.co -com.co -edu.co -firm.co -gov.co -info.co -int.co -mil.co -net.co -nom.co -org.co -rec.co -web.co - -// com : https://en.wikipedia.org/wiki/.com -com - -// coop : https://en.wikipedia.org/wiki/.coop -coop - -// cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do -cr -ac.cr -co.cr -ed.cr -fi.cr -go.cr -or.cr -sa.cr - -// cu : https://en.wikipedia.org/wiki/.cu -cu -com.cu -edu.cu -org.cu -net.cu -gov.cu -inf.cu - -// cv : https://en.wikipedia.org/wiki/.cv -// cv : http://www.dns.cv/tldcv_portal/do?com=DS;5446457100;111;+PAGE(4000018)+K-CAT-CODIGO(RDOM)+RCNT(100); <- registration rules -cv -com.cv -edu.cv -int.cv -nome.cv -org.cv - -// cw : http://www.una.cw/cw_registry/ -// Confirmed by registry 2013-03-26 -cw -com.cw -edu.cw -net.cw -org.cw - -// cx : https://en.wikipedia.org/wiki/.cx -// list of other 2nd level tlds ? -cx -gov.cx - -// cy : http://www.nic.cy/ -// Submitted by registry Panayiotou Fotia -// namespace policies URL https://www.nic.cy/portal//sites/default/files/symfonia_gia_eggrafi.pdf -cy -ac.cy -biz.cy -com.cy -ekloges.cy -gov.cy -ltd.cy -mil.cy -net.cy -org.cy -press.cy -pro.cy -tm.cy - -// cz : https://en.wikipedia.org/wiki/.cz -cz - -// de : https://en.wikipedia.org/wiki/.de -// Confirmed by registry (with technical -// reservations) 2008-07-01 -de - -// dj : https://en.wikipedia.org/wiki/.dj -dj - -// dk : https://en.wikipedia.org/wiki/.dk -// Confirmed by registry 2008-06-17 -dk - -// dm : https://en.wikipedia.org/wiki/.dm -dm -com.dm -net.dm -org.dm -edu.dm -gov.dm - -// do : https://en.wikipedia.org/wiki/.do -do -art.do -com.do -edu.do -gob.do -gov.do -mil.do -net.do -org.do -sld.do -web.do - -// dz : http://www.nic.dz/images/pdf_nic/charte.pdf -dz -art.dz -asso.dz -com.dz -edu.dz -gov.dz -org.dz -net.dz -pol.dz -soc.dz -tm.dz - -// ec : http://www.nic.ec/reg/paso1.asp -// Submitted by registry -ec -com.ec -info.ec -net.ec -fin.ec -k12.ec -med.ec -pro.ec -org.ec -edu.ec -gov.ec -gob.ec -mil.ec - -// edu : https://en.wikipedia.org/wiki/.edu -edu - -// ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B -ee -edu.ee -gov.ee -riik.ee -lib.ee -med.ee -com.ee -pri.ee -aip.ee -org.ee -fie.ee - -// eg : https://en.wikipedia.org/wiki/.eg -eg -com.eg -edu.eg -eun.eg -gov.eg -mil.eg -name.eg -net.eg -org.eg -sci.eg - -// er : https://en.wikipedia.org/wiki/.er -*.er - -// es : https://www.nic.es/site_ingles/ingles/dominios/index.html -es -com.es -nom.es -org.es -gob.es -edu.es - -// et : https://en.wikipedia.org/wiki/.et -et -com.et -gov.et -org.et -edu.et -biz.et -name.et -info.et -net.et - -// eu : https://en.wikipedia.org/wiki/.eu -eu - -// fi : https://en.wikipedia.org/wiki/.fi -fi -// aland.fi : https://en.wikipedia.org/wiki/.ax -// This domain is being phased out in favor of .ax. As there are still many -// domains under aland.fi, we still keep it on the list until aland.fi is -// completely removed. -// TODO: Check for updates (expected to be phased out around Q1/2009) -aland.fi - -// fj : http://domains.fj/ -// Submitted by registry 2020-02-11 -fj -ac.fj -biz.fj -com.fj -gov.fj -info.fj -mil.fj -name.fj -net.fj -org.fj -pro.fj - -// fk : https://en.wikipedia.org/wiki/.fk -*.fk - -// fm : https://en.wikipedia.org/wiki/.fm -com.fm -edu.fm -net.fm -org.fm -fm - -// fo : https://en.wikipedia.org/wiki/.fo -fo - -// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -fr -asso.fr -com.fr -gouv.fr -nom.fr -prd.fr -tm.fr -// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes -avoues.fr -cci.fr -greta.fr -huissier-justice.fr - -// ga : https://en.wikipedia.org/wiki/.ga -ga - -// gb : This registry is effectively dormant -// Submitted by registry -gb - -// gd : https://en.wikipedia.org/wiki/.gd -edu.gd -gov.gd -gd - -// ge : http://www.nic.net.ge/policy_en.pdf -ge -com.ge -edu.ge -gov.ge -org.ge -mil.ge -net.ge -pvt.ge - -// gf : https://en.wikipedia.org/wiki/.gf -gf - -// gg : http://www.channelisles.net/register-domains/ -// Confirmed by registry 2013-11-28 -gg -co.gg -net.gg -org.gg - -// gh : https://en.wikipedia.org/wiki/.gh -// see also: http://www.nic.gh/reg_now.php -// Although domains directly at second level are not possible at the moment, -// they have been possible for some time and may come back. -gh -com.gh -edu.gh -gov.gh -org.gh -mil.gh - -// gi : http://www.nic.gi/rules.html -gi -com.gi -ltd.gi -gov.gi -mod.gi -edu.gi -org.gi - -// gl : https://en.wikipedia.org/wiki/.gl -// http://nic.gl -gl -co.gl -com.gl -edu.gl -net.gl -org.gl - -// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm -gm - -// gn : http://psg.com/dns/gn/gn.txt -// Submitted by registry -gn -ac.gn -com.gn -edu.gn -gov.gn -org.gn -net.gn - -// gov : https://en.wikipedia.org/wiki/.gov -gov - -// gp : http://www.nic.gp/index.php?lang=en -gp -com.gp -net.gp -mobi.gp -edu.gp -org.gp -asso.gp - -// gq : https://en.wikipedia.org/wiki/.gq -gq - -// gr : https://grweb.ics.forth.gr/english/1617-B-2005.html -// Submitted by registry -gr -com.gr -edu.gr -net.gr -org.gr -gov.gr - -// gs : https://en.wikipedia.org/wiki/.gs -gs - -// gt : https://www.gt/sitio/registration_policy.php?lang=en -gt -com.gt -edu.gt -gob.gt -ind.gt -mil.gt -net.gt -org.gt - -// gu : http://gadao.gov.gu/register.html -// University of Guam : https://www.uog.edu -// Submitted by uognoc@triton.uog.edu -gu -com.gu -edu.gu -gov.gu -guam.gu -info.gu -net.gu -org.gu -web.gu - -// gw : https://en.wikipedia.org/wiki/.gw -// gw : https://nic.gw/regras/ -gw - -// gy : https://en.wikipedia.org/wiki/.gy -// http://registry.gy/ -gy -co.gy -com.gy -edu.gy -gov.gy -net.gy -org.gy - -// hk : https://www.hkirc.hk -// Submitted by registry -hk -com.hk -edu.hk -gov.hk -idv.hk -net.hk -org.hk -公司.hk -教育.hk -敎育.hk -政府.hk -個人.hk -个人.hk -箇人.hk -網络.hk -网络.hk -组織.hk -網絡.hk -网絡.hk -组织.hk -組織.hk -組织.hk - -// hm : https://en.wikipedia.org/wiki/.hm -hm - -// hn : http://www.nic.hn/politicas/ps02,,05.html -hn -com.hn -edu.hn -org.hn -net.hn -mil.hn -gob.hn - -// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf -hr -iz.hr -from.hr -name.hr -com.hr - -// ht : http://www.nic.ht/info/charte.cfm -ht -com.ht -shop.ht -firm.ht -info.ht -adult.ht -net.ht -pro.ht -org.ht -med.ht -art.ht -coop.ht -pol.ht -asso.ht -edu.ht -rel.ht -gouv.ht -perso.ht - -// hu : http://www.domain.hu/domain/English/sld.html -// Confirmed by registry 2008-06-12 -hu -co.hu -info.hu -org.hu -priv.hu -sport.hu -tm.hu -2000.hu -agrar.hu -bolt.hu -casino.hu -city.hu -erotica.hu -erotika.hu -film.hu -forum.hu -games.hu -hotel.hu -ingatlan.hu -jogasz.hu -konyvelo.hu -lakas.hu -media.hu -news.hu -reklam.hu -sex.hu -shop.hu -suli.hu -szex.hu -tozsde.hu -utazas.hu -video.hu - -// id : https://pandi.id/en/domain/registration-requirements/ -id -ac.id -biz.id -co.id -desa.id -go.id -mil.id -my.id -net.id -or.id -ponpes.id -sch.id -web.id - -// ie : https://en.wikipedia.org/wiki/.ie -ie -gov.ie - -// il : http://www.isoc.org.il/domains/ -// see also: https://en.isoc.org.il/il-cctld/registration-rules -// ISOC-IL (operated by .il Registry) -il -ac.il -co.il -gov.il -idf.il -k12.il -muni.il -net.il -org.il -// xn--4dbrk0ce ("Israel", Hebrew) : IL -ישראל -// xn--4dbgdty6c.xn--4dbrk0ce. -אקדמיה.ישראל -// xn--5dbhl8d.xn--4dbrk0ce. -ישוב.ישראל -// xn--8dbq2a.xn--4dbrk0ce. -צהל.ישראל -// xn--hebda8b.xn--4dbrk0ce. -ממשל.ישראל - -// im : https://www.nic.im/ -// Submitted by registry -im -ac.im -co.im -com.im -ltd.co.im -net.im -org.im -plc.co.im -tt.im -tv.im - -// in : https://en.wikipedia.org/wiki/.in -// see also: https://registry.in/policies -// Please note, that nic.in is not an official eTLD, but used by most -// government institutions. -in -5g.in -6g.in -ac.in -ai.in -am.in -bihar.in -biz.in -business.in -ca.in -cn.in -co.in -com.in -coop.in -cs.in -delhi.in -dr.in -edu.in -er.in -firm.in -gen.in -gov.in -gujarat.in -ind.in -info.in -int.in -internet.in -io.in -me.in -mil.in -net.in -nic.in -org.in -pg.in -post.in -pro.in -res.in -travel.in -tv.in -uk.in -up.in -us.in - -// info : https://en.wikipedia.org/wiki/.info -info - -// int : https://en.wikipedia.org/wiki/.int -// Confirmed by registry 2008-06-18 -int -eu.int - -// io : http://www.nic.io/rules.htm -// list of other 2nd level tlds ? -io -com.io - -// iq : http://www.cmc.iq/english/iq/iqregister1.htm -iq -gov.iq -edu.iq -mil.iq -com.iq -org.iq -net.iq - -// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules -// Also see http://www.nic.ir/Internationalized_Domain_Names -// Two .ir entries added at request of , 2010-04-16 -ir -ac.ir -co.ir -gov.ir -id.ir -net.ir -org.ir -sch.ir -// xn--mgba3a4f16a.ir (.ir, Persian YEH) -ایران.ir -// xn--mgba3a4fra.ir (.ir, Arabic YEH) -ايران.ir - -// is : http://www.isnic.is/domain/rules.php -// Confirmed by registry 2008-12-06 -is -net.is -com.is -edu.is -gov.is -org.is -int.is - -// it : https://en.wikipedia.org/wiki/.it -it -gov.it -edu.it -// Reserved geo-names (regions and provinces): -// https://www.nic.it/sites/default/files/archivio/docs/Regulation_assignation_v7.1.pdf -// Regions -abr.it -abruzzo.it -aosta-valley.it -aostavalley.it -bas.it -basilicata.it -cal.it -calabria.it -cam.it -campania.it -emilia-romagna.it -emiliaromagna.it -emr.it -friuli-v-giulia.it -friuli-ve-giulia.it -friuli-vegiulia.it -friuli-venezia-giulia.it -friuli-veneziagiulia.it -friuli-vgiulia.it -friuliv-giulia.it -friulive-giulia.it -friulivegiulia.it -friulivenezia-giulia.it -friuliveneziagiulia.it -friulivgiulia.it -fvg.it -laz.it -lazio.it -lig.it -liguria.it -lom.it -lombardia.it -lombardy.it -lucania.it -mar.it -marche.it -mol.it -molise.it -piedmont.it -piemonte.it -pmn.it -pug.it -puglia.it -sar.it -sardegna.it -sardinia.it -sic.it -sicilia.it -sicily.it -taa.it -tos.it -toscana.it -trentin-sud-tirol.it -trentin-süd-tirol.it -trentin-sudtirol.it -trentin-südtirol.it -trentin-sued-tirol.it -trentin-suedtirol.it -trentino-a-adige.it -trentino-aadige.it -trentino-alto-adige.it -trentino-altoadige.it -trentino-s-tirol.it -trentino-stirol.it -trentino-sud-tirol.it -trentino-süd-tirol.it -trentino-sudtirol.it -trentino-südtirol.it -trentino-sued-tirol.it -trentino-suedtirol.it -trentino.it -trentinoa-adige.it -trentinoaadige.it -trentinoalto-adige.it -trentinoaltoadige.it -trentinos-tirol.it -trentinostirol.it -trentinosud-tirol.it -trentinosüd-tirol.it -trentinosudtirol.it -trentinosüdtirol.it -trentinosued-tirol.it -trentinosuedtirol.it -trentinsud-tirol.it -trentinsüd-tirol.it -trentinsudtirol.it -trentinsüdtirol.it -trentinsued-tirol.it -trentinsuedtirol.it -tuscany.it -umb.it -umbria.it -val-d-aosta.it -val-daosta.it -vald-aosta.it -valdaosta.it -valle-aosta.it -valle-d-aosta.it -valle-daosta.it -valleaosta.it -valled-aosta.it -valledaosta.it -vallee-aoste.it -vallée-aoste.it -vallee-d-aoste.it -vallée-d-aoste.it -valleeaoste.it -valléeaoste.it -valleedaoste.it -valléedaoste.it -vao.it -vda.it -ven.it -veneto.it -// Provinces -ag.it -agrigento.it -al.it -alessandria.it -alto-adige.it -altoadige.it -an.it -ancona.it -andria-barletta-trani.it -andria-trani-barletta.it -andriabarlettatrani.it -andriatranibarletta.it -ao.it -aosta.it -aoste.it -ap.it -aq.it -aquila.it -ar.it -arezzo.it -ascoli-piceno.it -ascolipiceno.it -asti.it -at.it -av.it -avellino.it -ba.it -balsan-sudtirol.it -balsan-südtirol.it -balsan-suedtirol.it -balsan.it -bari.it -barletta-trani-andria.it -barlettatraniandria.it -belluno.it -benevento.it -bergamo.it -bg.it -bi.it -biella.it -bl.it -bn.it -bo.it -bologna.it -bolzano-altoadige.it -bolzano.it -bozen-sudtirol.it -bozen-südtirol.it -bozen-suedtirol.it -bozen.it -br.it -brescia.it -brindisi.it -bs.it -bt.it -bulsan-sudtirol.it -bulsan-südtirol.it -bulsan-suedtirol.it -bulsan.it -bz.it -ca.it -cagliari.it -caltanissetta.it -campidano-medio.it -campidanomedio.it -campobasso.it -carbonia-iglesias.it -carboniaiglesias.it -carrara-massa.it -carraramassa.it -caserta.it -catania.it -catanzaro.it -cb.it -ce.it -cesena-forli.it -cesena-forlì.it -cesenaforli.it -cesenaforlì.it -ch.it -chieti.it -ci.it -cl.it -cn.it -co.it -como.it -cosenza.it -cr.it -cremona.it -crotone.it -cs.it -ct.it -cuneo.it -cz.it -dell-ogliastra.it -dellogliastra.it -en.it -enna.it -fc.it -fe.it -fermo.it -ferrara.it -fg.it -fi.it -firenze.it -florence.it -fm.it -foggia.it -forli-cesena.it -forlì-cesena.it -forlicesena.it -forlìcesena.it -fr.it -frosinone.it -ge.it -genoa.it -genova.it -go.it -gorizia.it -gr.it -grosseto.it -iglesias-carbonia.it -iglesiascarbonia.it -im.it -imperia.it -is.it -isernia.it -kr.it -la-spezia.it -laquila.it -laspezia.it -latina.it -lc.it -le.it -lecce.it -lecco.it -li.it -livorno.it -lo.it -lodi.it -lt.it -lu.it -lucca.it -macerata.it -mantova.it -massa-carrara.it -massacarrara.it -matera.it -mb.it -mc.it -me.it -medio-campidano.it -mediocampidano.it -messina.it -mi.it -milan.it -milano.it -mn.it -mo.it -modena.it -monza-brianza.it -monza-e-della-brianza.it -monza.it -monzabrianza.it -monzaebrianza.it -monzaedellabrianza.it -ms.it -mt.it -na.it -naples.it -napoli.it -no.it -novara.it -nu.it -nuoro.it -og.it -ogliastra.it -olbia-tempio.it -olbiatempio.it -or.it -oristano.it -ot.it -pa.it -padova.it -padua.it -palermo.it -parma.it -pavia.it -pc.it -pd.it -pe.it -perugia.it -pesaro-urbino.it -pesarourbino.it -pescara.it -pg.it -pi.it -piacenza.it -pisa.it -pistoia.it -pn.it -po.it -pordenone.it -potenza.it -pr.it -prato.it -pt.it -pu.it -pv.it -pz.it -ra.it -ragusa.it -ravenna.it -rc.it -re.it -reggio-calabria.it -reggio-emilia.it -reggiocalabria.it -reggioemilia.it -rg.it -ri.it -rieti.it -rimini.it -rm.it -rn.it -ro.it -roma.it -rome.it -rovigo.it -sa.it -salerno.it -sassari.it -savona.it -si.it -siena.it -siracusa.it -so.it -sondrio.it -sp.it -sr.it -ss.it -suedtirol.it -südtirol.it -sv.it -ta.it -taranto.it -te.it -tempio-olbia.it -tempioolbia.it -teramo.it -terni.it -tn.it -to.it -torino.it -tp.it -tr.it -trani-andria-barletta.it -trani-barletta-andria.it -traniandriabarletta.it -tranibarlettaandria.it -trapani.it -trento.it -treviso.it -trieste.it -ts.it -turin.it -tv.it -ud.it -udine.it -urbino-pesaro.it -urbinopesaro.it -va.it -varese.it -vb.it -vc.it -ve.it -venezia.it -venice.it -verbania.it -vercelli.it -verona.it -vi.it -vibo-valentia.it -vibovalentia.it -vicenza.it -viterbo.it -vr.it -vs.it -vt.it -vv.it - -// je : http://www.channelisles.net/register-domains/ -// Confirmed by registry 2013-11-28 -je -co.je -net.je -org.je - -// jm : http://www.com.jm/register.html -*.jm - -// jo : http://www.dns.jo/Registration_policy.aspx -jo -com.jo -org.jo -net.jo -edu.jo -sch.jo -gov.jo -mil.jo -name.jo - -// jobs : https://en.wikipedia.org/wiki/.jobs -jobs - -// jp : https://en.wikipedia.org/wiki/.jp -// http://jprs.co.jp/en/jpdomain.html -// Submitted by registry -jp -// jp organizational type names -ac.jp -ad.jp -co.jp -ed.jp -go.jp -gr.jp -lg.jp -ne.jp -or.jp -// jp prefecture type names -aichi.jp -akita.jp -aomori.jp -chiba.jp -ehime.jp -fukui.jp -fukuoka.jp -fukushima.jp -gifu.jp -gunma.jp -hiroshima.jp -hokkaido.jp -hyogo.jp -ibaraki.jp -ishikawa.jp -iwate.jp -kagawa.jp -kagoshima.jp -kanagawa.jp -kochi.jp -kumamoto.jp -kyoto.jp -mie.jp -miyagi.jp -miyazaki.jp -nagano.jp -nagasaki.jp -nara.jp -niigata.jp -oita.jp -okayama.jp -okinawa.jp -osaka.jp -saga.jp -saitama.jp -shiga.jp -shimane.jp -shizuoka.jp -tochigi.jp -tokushima.jp -tokyo.jp -tottori.jp -toyama.jp -wakayama.jp -yamagata.jp -yamaguchi.jp -yamanashi.jp -栃木.jp -愛知.jp -愛媛.jp -兵庫.jp -熊本.jp -茨城.jp -北海道.jp -千葉.jp -和歌山.jp -長崎.jp -長野.jp -新潟.jp -青森.jp -静岡.jp -東京.jp -石川.jp -埼玉.jp -三重.jp -京都.jp -佐賀.jp -大分.jp -大阪.jp -奈良.jp -宮城.jp -宮崎.jp -富山.jp -山口.jp -山形.jp -山梨.jp -岩手.jp -岐阜.jp -岡山.jp -島根.jp -広島.jp -徳島.jp -沖縄.jp -滋賀.jp -神奈川.jp -福井.jp -福岡.jp -福島.jp -秋田.jp -群馬.jp -香川.jp -高知.jp -鳥取.jp -鹿児島.jp -// jp geographic type names -// http://jprs.jp/doc/rule/saisoku-1.html -*.kawasaki.jp -*.kitakyushu.jp -*.kobe.jp -*.nagoya.jp -*.sapporo.jp -*.sendai.jp -*.yokohama.jp -!city.kawasaki.jp -!city.kitakyushu.jp -!city.kobe.jp -!city.nagoya.jp -!city.sapporo.jp -!city.sendai.jp -!city.yokohama.jp -// 4th level registration -aisai.aichi.jp -ama.aichi.jp -anjo.aichi.jp -asuke.aichi.jp -chiryu.aichi.jp -chita.aichi.jp -fuso.aichi.jp -gamagori.aichi.jp -handa.aichi.jp -hazu.aichi.jp -hekinan.aichi.jp -higashiura.aichi.jp -ichinomiya.aichi.jp -inazawa.aichi.jp -inuyama.aichi.jp -isshiki.aichi.jp -iwakura.aichi.jp -kanie.aichi.jp -kariya.aichi.jp -kasugai.aichi.jp -kira.aichi.jp -kiyosu.aichi.jp -komaki.aichi.jp -konan.aichi.jp -kota.aichi.jp -mihama.aichi.jp -miyoshi.aichi.jp -nishio.aichi.jp -nisshin.aichi.jp -obu.aichi.jp -oguchi.aichi.jp -oharu.aichi.jp -okazaki.aichi.jp -owariasahi.aichi.jp -seto.aichi.jp -shikatsu.aichi.jp -shinshiro.aichi.jp -shitara.aichi.jp -tahara.aichi.jp -takahama.aichi.jp -tobishima.aichi.jp -toei.aichi.jp -togo.aichi.jp -tokai.aichi.jp -tokoname.aichi.jp -toyoake.aichi.jp -toyohashi.aichi.jp -toyokawa.aichi.jp -toyone.aichi.jp -toyota.aichi.jp -tsushima.aichi.jp -yatomi.aichi.jp -akita.akita.jp -daisen.akita.jp -fujisato.akita.jp -gojome.akita.jp -hachirogata.akita.jp -happou.akita.jp -higashinaruse.akita.jp -honjo.akita.jp -honjyo.akita.jp -ikawa.akita.jp -kamikoani.akita.jp -kamioka.akita.jp -katagami.akita.jp -kazuno.akita.jp -kitaakita.akita.jp -kosaka.akita.jp -kyowa.akita.jp -misato.akita.jp -mitane.akita.jp -moriyoshi.akita.jp -nikaho.akita.jp -noshiro.akita.jp -odate.akita.jp -oga.akita.jp -ogata.akita.jp -semboku.akita.jp -yokote.akita.jp -yurihonjo.akita.jp -aomori.aomori.jp -gonohe.aomori.jp -hachinohe.aomori.jp -hashikami.aomori.jp -hiranai.aomori.jp -hirosaki.aomori.jp -itayanagi.aomori.jp -kuroishi.aomori.jp -misawa.aomori.jp -mutsu.aomori.jp -nakadomari.aomori.jp -noheji.aomori.jp -oirase.aomori.jp -owani.aomori.jp -rokunohe.aomori.jp -sannohe.aomori.jp -shichinohe.aomori.jp -shingo.aomori.jp -takko.aomori.jp -towada.aomori.jp -tsugaru.aomori.jp -tsuruta.aomori.jp -abiko.chiba.jp -asahi.chiba.jp -chonan.chiba.jp -chosei.chiba.jp -choshi.chiba.jp -chuo.chiba.jp -funabashi.chiba.jp -futtsu.chiba.jp -hanamigawa.chiba.jp -ichihara.chiba.jp -ichikawa.chiba.jp -ichinomiya.chiba.jp -inzai.chiba.jp -isumi.chiba.jp -kamagaya.chiba.jp -kamogawa.chiba.jp -kashiwa.chiba.jp -katori.chiba.jp -katsuura.chiba.jp -kimitsu.chiba.jp -kisarazu.chiba.jp -kozaki.chiba.jp -kujukuri.chiba.jp -kyonan.chiba.jp -matsudo.chiba.jp -midori.chiba.jp -mihama.chiba.jp -minamiboso.chiba.jp -mobara.chiba.jp -mutsuzawa.chiba.jp -nagara.chiba.jp -nagareyama.chiba.jp -narashino.chiba.jp -narita.chiba.jp -noda.chiba.jp -oamishirasato.chiba.jp -omigawa.chiba.jp -onjuku.chiba.jp -otaki.chiba.jp -sakae.chiba.jp -sakura.chiba.jp -shimofusa.chiba.jp -shirako.chiba.jp -shiroi.chiba.jp -shisui.chiba.jp -sodegaura.chiba.jp -sosa.chiba.jp -tako.chiba.jp -tateyama.chiba.jp -togane.chiba.jp -tohnosho.chiba.jp -tomisato.chiba.jp -urayasu.chiba.jp -yachimata.chiba.jp -yachiyo.chiba.jp -yokaichiba.chiba.jp -yokoshibahikari.chiba.jp -yotsukaido.chiba.jp -ainan.ehime.jp -honai.ehime.jp -ikata.ehime.jp -imabari.ehime.jp -iyo.ehime.jp -kamijima.ehime.jp -kihoku.ehime.jp -kumakogen.ehime.jp -masaki.ehime.jp -matsuno.ehime.jp -matsuyama.ehime.jp -namikata.ehime.jp -niihama.ehime.jp -ozu.ehime.jp -saijo.ehime.jp -seiyo.ehime.jp -shikokuchuo.ehime.jp -tobe.ehime.jp -toon.ehime.jp -uchiko.ehime.jp -uwajima.ehime.jp -yawatahama.ehime.jp -echizen.fukui.jp -eiheiji.fukui.jp -fukui.fukui.jp -ikeda.fukui.jp -katsuyama.fukui.jp -mihama.fukui.jp -minamiechizen.fukui.jp -obama.fukui.jp -ohi.fukui.jp -ono.fukui.jp -sabae.fukui.jp -sakai.fukui.jp -takahama.fukui.jp -tsuruga.fukui.jp -wakasa.fukui.jp -ashiya.fukuoka.jp -buzen.fukuoka.jp -chikugo.fukuoka.jp -chikuho.fukuoka.jp -chikujo.fukuoka.jp -chikushino.fukuoka.jp -chikuzen.fukuoka.jp -chuo.fukuoka.jp -dazaifu.fukuoka.jp -fukuchi.fukuoka.jp -hakata.fukuoka.jp -higashi.fukuoka.jp -hirokawa.fukuoka.jp -hisayama.fukuoka.jp -iizuka.fukuoka.jp -inatsuki.fukuoka.jp -kaho.fukuoka.jp -kasuga.fukuoka.jp -kasuya.fukuoka.jp -kawara.fukuoka.jp -keisen.fukuoka.jp -koga.fukuoka.jp -kurate.fukuoka.jp -kurogi.fukuoka.jp -kurume.fukuoka.jp -minami.fukuoka.jp -miyako.fukuoka.jp -miyama.fukuoka.jp -miyawaka.fukuoka.jp -mizumaki.fukuoka.jp -munakata.fukuoka.jp -nakagawa.fukuoka.jp -nakama.fukuoka.jp -nishi.fukuoka.jp -nogata.fukuoka.jp -ogori.fukuoka.jp -okagaki.fukuoka.jp -okawa.fukuoka.jp -oki.fukuoka.jp -omuta.fukuoka.jp -onga.fukuoka.jp -onojo.fukuoka.jp -oto.fukuoka.jp -saigawa.fukuoka.jp -sasaguri.fukuoka.jp -shingu.fukuoka.jp -shinyoshitomi.fukuoka.jp -shonai.fukuoka.jp -soeda.fukuoka.jp -sue.fukuoka.jp -tachiarai.fukuoka.jp -tagawa.fukuoka.jp -takata.fukuoka.jp -toho.fukuoka.jp -toyotsu.fukuoka.jp -tsuiki.fukuoka.jp -ukiha.fukuoka.jp -umi.fukuoka.jp -usui.fukuoka.jp -yamada.fukuoka.jp -yame.fukuoka.jp -yanagawa.fukuoka.jp -yukuhashi.fukuoka.jp -aizubange.fukushima.jp -aizumisato.fukushima.jp -aizuwakamatsu.fukushima.jp -asakawa.fukushima.jp -bandai.fukushima.jp -date.fukushima.jp -fukushima.fukushima.jp -furudono.fukushima.jp -futaba.fukushima.jp -hanawa.fukushima.jp -higashi.fukushima.jp -hirata.fukushima.jp -hirono.fukushima.jp -iitate.fukushima.jp -inawashiro.fukushima.jp -ishikawa.fukushima.jp -iwaki.fukushima.jp -izumizaki.fukushima.jp -kagamiishi.fukushima.jp -kaneyama.fukushima.jp -kawamata.fukushima.jp -kitakata.fukushima.jp -kitashiobara.fukushima.jp -koori.fukushima.jp -koriyama.fukushima.jp -kunimi.fukushima.jp -miharu.fukushima.jp -mishima.fukushima.jp -namie.fukushima.jp -nango.fukushima.jp -nishiaizu.fukushima.jp -nishigo.fukushima.jp -okuma.fukushima.jp -omotego.fukushima.jp -ono.fukushima.jp -otama.fukushima.jp -samegawa.fukushima.jp -shimogo.fukushima.jp -shirakawa.fukushima.jp -showa.fukushima.jp -soma.fukushima.jp -sukagawa.fukushima.jp -taishin.fukushima.jp -tamakawa.fukushima.jp -tanagura.fukushima.jp -tenei.fukushima.jp -yabuki.fukushima.jp -yamato.fukushima.jp -yamatsuri.fukushima.jp -yanaizu.fukushima.jp -yugawa.fukushima.jp -anpachi.gifu.jp -ena.gifu.jp -gifu.gifu.jp -ginan.gifu.jp -godo.gifu.jp -gujo.gifu.jp -hashima.gifu.jp -hichiso.gifu.jp -hida.gifu.jp -higashishirakawa.gifu.jp -ibigawa.gifu.jp -ikeda.gifu.jp -kakamigahara.gifu.jp -kani.gifu.jp -kasahara.gifu.jp -kasamatsu.gifu.jp -kawaue.gifu.jp -kitagata.gifu.jp -mino.gifu.jp -minokamo.gifu.jp -mitake.gifu.jp -mizunami.gifu.jp -motosu.gifu.jp -nakatsugawa.gifu.jp -ogaki.gifu.jp -sakahogi.gifu.jp -seki.gifu.jp -sekigahara.gifu.jp -shirakawa.gifu.jp -tajimi.gifu.jp -takayama.gifu.jp -tarui.gifu.jp -toki.gifu.jp -tomika.gifu.jp -wanouchi.gifu.jp -yamagata.gifu.jp -yaotsu.gifu.jp -yoro.gifu.jp -annaka.gunma.jp -chiyoda.gunma.jp -fujioka.gunma.jp -higashiagatsuma.gunma.jp -isesaki.gunma.jp -itakura.gunma.jp -kanna.gunma.jp -kanra.gunma.jp -katashina.gunma.jp -kawaba.gunma.jp -kiryu.gunma.jp -kusatsu.gunma.jp -maebashi.gunma.jp -meiwa.gunma.jp -midori.gunma.jp -minakami.gunma.jp -naganohara.gunma.jp -nakanojo.gunma.jp -nanmoku.gunma.jp -numata.gunma.jp -oizumi.gunma.jp -ora.gunma.jp -ota.gunma.jp -shibukawa.gunma.jp -shimonita.gunma.jp -shinto.gunma.jp -showa.gunma.jp -takasaki.gunma.jp -takayama.gunma.jp -tamamura.gunma.jp -tatebayashi.gunma.jp -tomioka.gunma.jp -tsukiyono.gunma.jp -tsumagoi.gunma.jp -ueno.gunma.jp -yoshioka.gunma.jp -asaminami.hiroshima.jp -daiwa.hiroshima.jp -etajima.hiroshima.jp -fuchu.hiroshima.jp -fukuyama.hiroshima.jp -hatsukaichi.hiroshima.jp -higashihiroshima.hiroshima.jp -hongo.hiroshima.jp -jinsekikogen.hiroshima.jp -kaita.hiroshima.jp -kui.hiroshima.jp -kumano.hiroshima.jp -kure.hiroshima.jp -mihara.hiroshima.jp -miyoshi.hiroshima.jp -naka.hiroshima.jp -onomichi.hiroshima.jp -osakikamijima.hiroshima.jp -otake.hiroshima.jp -saka.hiroshima.jp -sera.hiroshima.jp -seranishi.hiroshima.jp -shinichi.hiroshima.jp -shobara.hiroshima.jp -takehara.hiroshima.jp -abashiri.hokkaido.jp -abira.hokkaido.jp -aibetsu.hokkaido.jp -akabira.hokkaido.jp -akkeshi.hokkaido.jp -asahikawa.hokkaido.jp -ashibetsu.hokkaido.jp -ashoro.hokkaido.jp -assabu.hokkaido.jp -atsuma.hokkaido.jp -bibai.hokkaido.jp -biei.hokkaido.jp -bifuka.hokkaido.jp -bihoro.hokkaido.jp -biratori.hokkaido.jp -chippubetsu.hokkaido.jp -chitose.hokkaido.jp -date.hokkaido.jp -ebetsu.hokkaido.jp -embetsu.hokkaido.jp -eniwa.hokkaido.jp -erimo.hokkaido.jp -esan.hokkaido.jp -esashi.hokkaido.jp -fukagawa.hokkaido.jp -fukushima.hokkaido.jp -furano.hokkaido.jp -furubira.hokkaido.jp -haboro.hokkaido.jp -hakodate.hokkaido.jp -hamatonbetsu.hokkaido.jp -hidaka.hokkaido.jp -higashikagura.hokkaido.jp -higashikawa.hokkaido.jp -hiroo.hokkaido.jp -hokuryu.hokkaido.jp -hokuto.hokkaido.jp -honbetsu.hokkaido.jp -horokanai.hokkaido.jp -horonobe.hokkaido.jp -ikeda.hokkaido.jp -imakane.hokkaido.jp -ishikari.hokkaido.jp -iwamizawa.hokkaido.jp -iwanai.hokkaido.jp -kamifurano.hokkaido.jp -kamikawa.hokkaido.jp -kamishihoro.hokkaido.jp -kamisunagawa.hokkaido.jp -kamoenai.hokkaido.jp -kayabe.hokkaido.jp -kembuchi.hokkaido.jp -kikonai.hokkaido.jp -kimobetsu.hokkaido.jp -kitahiroshima.hokkaido.jp -kitami.hokkaido.jp -kiyosato.hokkaido.jp -koshimizu.hokkaido.jp -kunneppu.hokkaido.jp -kuriyama.hokkaido.jp -kuromatsunai.hokkaido.jp -kushiro.hokkaido.jp -kutchan.hokkaido.jp -kyowa.hokkaido.jp -mashike.hokkaido.jp -matsumae.hokkaido.jp -mikasa.hokkaido.jp -minamifurano.hokkaido.jp -mombetsu.hokkaido.jp -moseushi.hokkaido.jp -mukawa.hokkaido.jp -muroran.hokkaido.jp -naie.hokkaido.jp -nakagawa.hokkaido.jp -nakasatsunai.hokkaido.jp -nakatombetsu.hokkaido.jp -nanae.hokkaido.jp -nanporo.hokkaido.jp -nayoro.hokkaido.jp -nemuro.hokkaido.jp -niikappu.hokkaido.jp -niki.hokkaido.jp -nishiokoppe.hokkaido.jp -noboribetsu.hokkaido.jp -numata.hokkaido.jp -obihiro.hokkaido.jp -obira.hokkaido.jp -oketo.hokkaido.jp -okoppe.hokkaido.jp -otaru.hokkaido.jp -otobe.hokkaido.jp -otofuke.hokkaido.jp -otoineppu.hokkaido.jp -oumu.hokkaido.jp -ozora.hokkaido.jp -pippu.hokkaido.jp -rankoshi.hokkaido.jp -rebun.hokkaido.jp -rikubetsu.hokkaido.jp -rishiri.hokkaido.jp -rishirifuji.hokkaido.jp -saroma.hokkaido.jp -sarufutsu.hokkaido.jp -shakotan.hokkaido.jp -shari.hokkaido.jp -shibecha.hokkaido.jp -shibetsu.hokkaido.jp -shikabe.hokkaido.jp -shikaoi.hokkaido.jp -shimamaki.hokkaido.jp -shimizu.hokkaido.jp -shimokawa.hokkaido.jp -shinshinotsu.hokkaido.jp -shintoku.hokkaido.jp -shiranuka.hokkaido.jp -shiraoi.hokkaido.jp -shiriuchi.hokkaido.jp -sobetsu.hokkaido.jp -sunagawa.hokkaido.jp -taiki.hokkaido.jp -takasu.hokkaido.jp -takikawa.hokkaido.jp -takinoue.hokkaido.jp -teshikaga.hokkaido.jp -tobetsu.hokkaido.jp -tohma.hokkaido.jp -tomakomai.hokkaido.jp -tomari.hokkaido.jp -toya.hokkaido.jp -toyako.hokkaido.jp -toyotomi.hokkaido.jp -toyoura.hokkaido.jp -tsubetsu.hokkaido.jp -tsukigata.hokkaido.jp -urakawa.hokkaido.jp -urausu.hokkaido.jp -uryu.hokkaido.jp -utashinai.hokkaido.jp -wakkanai.hokkaido.jp -wassamu.hokkaido.jp -yakumo.hokkaido.jp -yoichi.hokkaido.jp -aioi.hyogo.jp -akashi.hyogo.jp -ako.hyogo.jp -amagasaki.hyogo.jp -aogaki.hyogo.jp -asago.hyogo.jp -ashiya.hyogo.jp -awaji.hyogo.jp -fukusaki.hyogo.jp -goshiki.hyogo.jp -harima.hyogo.jp -himeji.hyogo.jp -ichikawa.hyogo.jp -inagawa.hyogo.jp -itami.hyogo.jp -kakogawa.hyogo.jp -kamigori.hyogo.jp -kamikawa.hyogo.jp -kasai.hyogo.jp -kasuga.hyogo.jp -kawanishi.hyogo.jp -miki.hyogo.jp -minamiawaji.hyogo.jp -nishinomiya.hyogo.jp -nishiwaki.hyogo.jp -ono.hyogo.jp -sanda.hyogo.jp -sannan.hyogo.jp -sasayama.hyogo.jp -sayo.hyogo.jp -shingu.hyogo.jp -shinonsen.hyogo.jp -shiso.hyogo.jp -sumoto.hyogo.jp -taishi.hyogo.jp -taka.hyogo.jp -takarazuka.hyogo.jp -takasago.hyogo.jp -takino.hyogo.jp -tamba.hyogo.jp -tatsuno.hyogo.jp -toyooka.hyogo.jp -yabu.hyogo.jp -yashiro.hyogo.jp -yoka.hyogo.jp -yokawa.hyogo.jp -ami.ibaraki.jp -asahi.ibaraki.jp -bando.ibaraki.jp -chikusei.ibaraki.jp -daigo.ibaraki.jp -fujishiro.ibaraki.jp -hitachi.ibaraki.jp -hitachinaka.ibaraki.jp -hitachiomiya.ibaraki.jp -hitachiota.ibaraki.jp -ibaraki.ibaraki.jp -ina.ibaraki.jp -inashiki.ibaraki.jp -itako.ibaraki.jp -iwama.ibaraki.jp -joso.ibaraki.jp -kamisu.ibaraki.jp -kasama.ibaraki.jp -kashima.ibaraki.jp -kasumigaura.ibaraki.jp -koga.ibaraki.jp -miho.ibaraki.jp -mito.ibaraki.jp -moriya.ibaraki.jp -naka.ibaraki.jp -namegata.ibaraki.jp -oarai.ibaraki.jp -ogawa.ibaraki.jp -omitama.ibaraki.jp -ryugasaki.ibaraki.jp -sakai.ibaraki.jp -sakuragawa.ibaraki.jp -shimodate.ibaraki.jp -shimotsuma.ibaraki.jp -shirosato.ibaraki.jp -sowa.ibaraki.jp -suifu.ibaraki.jp -takahagi.ibaraki.jp -tamatsukuri.ibaraki.jp -tokai.ibaraki.jp -tomobe.ibaraki.jp -tone.ibaraki.jp -toride.ibaraki.jp -tsuchiura.ibaraki.jp -tsukuba.ibaraki.jp -uchihara.ibaraki.jp -ushiku.ibaraki.jp -yachiyo.ibaraki.jp -yamagata.ibaraki.jp -yawara.ibaraki.jp -yuki.ibaraki.jp -anamizu.ishikawa.jp -hakui.ishikawa.jp -hakusan.ishikawa.jp -kaga.ishikawa.jp -kahoku.ishikawa.jp -kanazawa.ishikawa.jp -kawakita.ishikawa.jp -komatsu.ishikawa.jp -nakanoto.ishikawa.jp -nanao.ishikawa.jp -nomi.ishikawa.jp -nonoichi.ishikawa.jp -noto.ishikawa.jp -shika.ishikawa.jp -suzu.ishikawa.jp -tsubata.ishikawa.jp -tsurugi.ishikawa.jp -uchinada.ishikawa.jp -wajima.ishikawa.jp -fudai.iwate.jp -fujisawa.iwate.jp -hanamaki.iwate.jp -hiraizumi.iwate.jp -hirono.iwate.jp -ichinohe.iwate.jp -ichinoseki.iwate.jp -iwaizumi.iwate.jp -iwate.iwate.jp -joboji.iwate.jp -kamaishi.iwate.jp -kanegasaki.iwate.jp -karumai.iwate.jp -kawai.iwate.jp -kitakami.iwate.jp -kuji.iwate.jp -kunohe.iwate.jp -kuzumaki.iwate.jp -miyako.iwate.jp -mizusawa.iwate.jp -morioka.iwate.jp -ninohe.iwate.jp -noda.iwate.jp -ofunato.iwate.jp -oshu.iwate.jp -otsuchi.iwate.jp -rikuzentakata.iwate.jp -shiwa.iwate.jp -shizukuishi.iwate.jp -sumita.iwate.jp -tanohata.iwate.jp -tono.iwate.jp -yahaba.iwate.jp -yamada.iwate.jp -ayagawa.kagawa.jp -higashikagawa.kagawa.jp -kanonji.kagawa.jp -kotohira.kagawa.jp -manno.kagawa.jp -marugame.kagawa.jp -mitoyo.kagawa.jp -naoshima.kagawa.jp -sanuki.kagawa.jp -tadotsu.kagawa.jp -takamatsu.kagawa.jp -tonosho.kagawa.jp -uchinomi.kagawa.jp -utazu.kagawa.jp -zentsuji.kagawa.jp -akune.kagoshima.jp -amami.kagoshima.jp -hioki.kagoshima.jp -isa.kagoshima.jp -isen.kagoshima.jp -izumi.kagoshima.jp -kagoshima.kagoshima.jp -kanoya.kagoshima.jp -kawanabe.kagoshima.jp -kinko.kagoshima.jp -kouyama.kagoshima.jp -makurazaki.kagoshima.jp -matsumoto.kagoshima.jp -minamitane.kagoshima.jp -nakatane.kagoshima.jp -nishinoomote.kagoshima.jp -satsumasendai.kagoshima.jp -soo.kagoshima.jp -tarumizu.kagoshima.jp -yusui.kagoshima.jp -aikawa.kanagawa.jp -atsugi.kanagawa.jp -ayase.kanagawa.jp -chigasaki.kanagawa.jp -ebina.kanagawa.jp -fujisawa.kanagawa.jp -hadano.kanagawa.jp -hakone.kanagawa.jp -hiratsuka.kanagawa.jp -isehara.kanagawa.jp -kaisei.kanagawa.jp -kamakura.kanagawa.jp -kiyokawa.kanagawa.jp -matsuda.kanagawa.jp -minamiashigara.kanagawa.jp -miura.kanagawa.jp -nakai.kanagawa.jp -ninomiya.kanagawa.jp -odawara.kanagawa.jp -oi.kanagawa.jp -oiso.kanagawa.jp -sagamihara.kanagawa.jp -samukawa.kanagawa.jp -tsukui.kanagawa.jp -yamakita.kanagawa.jp -yamato.kanagawa.jp -yokosuka.kanagawa.jp -yugawara.kanagawa.jp -zama.kanagawa.jp -zushi.kanagawa.jp -aki.kochi.jp -geisei.kochi.jp -hidaka.kochi.jp -higashitsuno.kochi.jp -ino.kochi.jp -kagami.kochi.jp -kami.kochi.jp -kitagawa.kochi.jp -kochi.kochi.jp -mihara.kochi.jp -motoyama.kochi.jp -muroto.kochi.jp -nahari.kochi.jp -nakamura.kochi.jp -nankoku.kochi.jp -nishitosa.kochi.jp -niyodogawa.kochi.jp -ochi.kochi.jp -okawa.kochi.jp -otoyo.kochi.jp -otsuki.kochi.jp -sakawa.kochi.jp -sukumo.kochi.jp -susaki.kochi.jp -tosa.kochi.jp -tosashimizu.kochi.jp -toyo.kochi.jp -tsuno.kochi.jp -umaji.kochi.jp -yasuda.kochi.jp -yusuhara.kochi.jp -amakusa.kumamoto.jp -arao.kumamoto.jp -aso.kumamoto.jp -choyo.kumamoto.jp -gyokuto.kumamoto.jp -kamiamakusa.kumamoto.jp -kikuchi.kumamoto.jp -kumamoto.kumamoto.jp -mashiki.kumamoto.jp -mifune.kumamoto.jp -minamata.kumamoto.jp -minamioguni.kumamoto.jp -nagasu.kumamoto.jp -nishihara.kumamoto.jp -oguni.kumamoto.jp -ozu.kumamoto.jp -sumoto.kumamoto.jp -takamori.kumamoto.jp -uki.kumamoto.jp -uto.kumamoto.jp -yamaga.kumamoto.jp -yamato.kumamoto.jp -yatsushiro.kumamoto.jp -ayabe.kyoto.jp -fukuchiyama.kyoto.jp -higashiyama.kyoto.jp -ide.kyoto.jp -ine.kyoto.jp -joyo.kyoto.jp -kameoka.kyoto.jp -kamo.kyoto.jp -kita.kyoto.jp -kizu.kyoto.jp -kumiyama.kyoto.jp -kyotamba.kyoto.jp -kyotanabe.kyoto.jp -kyotango.kyoto.jp -maizuru.kyoto.jp -minami.kyoto.jp -minamiyamashiro.kyoto.jp -miyazu.kyoto.jp -muko.kyoto.jp -nagaokakyo.kyoto.jp -nakagyo.kyoto.jp -nantan.kyoto.jp -oyamazaki.kyoto.jp -sakyo.kyoto.jp -seika.kyoto.jp -tanabe.kyoto.jp -uji.kyoto.jp -ujitawara.kyoto.jp -wazuka.kyoto.jp -yamashina.kyoto.jp -yawata.kyoto.jp -asahi.mie.jp -inabe.mie.jp -ise.mie.jp -kameyama.mie.jp -kawagoe.mie.jp -kiho.mie.jp -kisosaki.mie.jp -kiwa.mie.jp -komono.mie.jp -kumano.mie.jp -kuwana.mie.jp -matsusaka.mie.jp -meiwa.mie.jp -mihama.mie.jp -minamiise.mie.jp -misugi.mie.jp -miyama.mie.jp -nabari.mie.jp -shima.mie.jp -suzuka.mie.jp -tado.mie.jp -taiki.mie.jp -taki.mie.jp -tamaki.mie.jp -toba.mie.jp -tsu.mie.jp -udono.mie.jp -ureshino.mie.jp -watarai.mie.jp -yokkaichi.mie.jp -furukawa.miyagi.jp -higashimatsushima.miyagi.jp -ishinomaki.miyagi.jp -iwanuma.miyagi.jp -kakuda.miyagi.jp -kami.miyagi.jp -kawasaki.miyagi.jp -marumori.miyagi.jp -matsushima.miyagi.jp -minamisanriku.miyagi.jp -misato.miyagi.jp -murata.miyagi.jp -natori.miyagi.jp -ogawara.miyagi.jp -ohira.miyagi.jp -onagawa.miyagi.jp -osaki.miyagi.jp -rifu.miyagi.jp -semine.miyagi.jp -shibata.miyagi.jp -shichikashuku.miyagi.jp -shikama.miyagi.jp -shiogama.miyagi.jp -shiroishi.miyagi.jp -tagajo.miyagi.jp -taiwa.miyagi.jp -tome.miyagi.jp -tomiya.miyagi.jp -wakuya.miyagi.jp -watari.miyagi.jp -yamamoto.miyagi.jp -zao.miyagi.jp -aya.miyazaki.jp -ebino.miyazaki.jp -gokase.miyazaki.jp -hyuga.miyazaki.jp -kadogawa.miyazaki.jp -kawaminami.miyazaki.jp -kijo.miyazaki.jp -kitagawa.miyazaki.jp -kitakata.miyazaki.jp -kitaura.miyazaki.jp -kobayashi.miyazaki.jp -kunitomi.miyazaki.jp -kushima.miyazaki.jp -mimata.miyazaki.jp -miyakonojo.miyazaki.jp -miyazaki.miyazaki.jp -morotsuka.miyazaki.jp -nichinan.miyazaki.jp -nishimera.miyazaki.jp -nobeoka.miyazaki.jp -saito.miyazaki.jp -shiiba.miyazaki.jp -shintomi.miyazaki.jp -takaharu.miyazaki.jp -takanabe.miyazaki.jp -takazaki.miyazaki.jp -tsuno.miyazaki.jp -achi.nagano.jp -agematsu.nagano.jp -anan.nagano.jp -aoki.nagano.jp -asahi.nagano.jp -azumino.nagano.jp -chikuhoku.nagano.jp -chikuma.nagano.jp -chino.nagano.jp -fujimi.nagano.jp -hakuba.nagano.jp -hara.nagano.jp -hiraya.nagano.jp -iida.nagano.jp -iijima.nagano.jp -iiyama.nagano.jp -iizuna.nagano.jp -ikeda.nagano.jp -ikusaka.nagano.jp -ina.nagano.jp -karuizawa.nagano.jp -kawakami.nagano.jp -kiso.nagano.jp -kisofukushima.nagano.jp -kitaaiki.nagano.jp -komagane.nagano.jp -komoro.nagano.jp -matsukawa.nagano.jp -matsumoto.nagano.jp -miasa.nagano.jp -minamiaiki.nagano.jp -minamimaki.nagano.jp -minamiminowa.nagano.jp -minowa.nagano.jp -miyada.nagano.jp -miyota.nagano.jp -mochizuki.nagano.jp -nagano.nagano.jp -nagawa.nagano.jp -nagiso.nagano.jp -nakagawa.nagano.jp -nakano.nagano.jp -nozawaonsen.nagano.jp -obuse.nagano.jp -ogawa.nagano.jp -okaya.nagano.jp -omachi.nagano.jp -omi.nagano.jp -ookuwa.nagano.jp -ooshika.nagano.jp -otaki.nagano.jp -otari.nagano.jp -sakae.nagano.jp -sakaki.nagano.jp -saku.nagano.jp -sakuho.nagano.jp -shimosuwa.nagano.jp -shinanomachi.nagano.jp -shiojiri.nagano.jp -suwa.nagano.jp -suzaka.nagano.jp -takagi.nagano.jp -takamori.nagano.jp -takayama.nagano.jp -tateshina.nagano.jp -tatsuno.nagano.jp -togakushi.nagano.jp -togura.nagano.jp -tomi.nagano.jp -ueda.nagano.jp -wada.nagano.jp -yamagata.nagano.jp -yamanouchi.nagano.jp -yasaka.nagano.jp -yasuoka.nagano.jp -chijiwa.nagasaki.jp -futsu.nagasaki.jp -goto.nagasaki.jp -hasami.nagasaki.jp -hirado.nagasaki.jp -iki.nagasaki.jp -isahaya.nagasaki.jp -kawatana.nagasaki.jp -kuchinotsu.nagasaki.jp -matsuura.nagasaki.jp -nagasaki.nagasaki.jp -obama.nagasaki.jp -omura.nagasaki.jp -oseto.nagasaki.jp -saikai.nagasaki.jp -sasebo.nagasaki.jp -seihi.nagasaki.jp -shimabara.nagasaki.jp -shinkamigoto.nagasaki.jp -togitsu.nagasaki.jp -tsushima.nagasaki.jp -unzen.nagasaki.jp -ando.nara.jp -gose.nara.jp -heguri.nara.jp -higashiyoshino.nara.jp -ikaruga.nara.jp -ikoma.nara.jp -kamikitayama.nara.jp -kanmaki.nara.jp -kashiba.nara.jp -kashihara.nara.jp -katsuragi.nara.jp -kawai.nara.jp -kawakami.nara.jp -kawanishi.nara.jp -koryo.nara.jp -kurotaki.nara.jp -mitsue.nara.jp -miyake.nara.jp -nara.nara.jp -nosegawa.nara.jp -oji.nara.jp -ouda.nara.jp -oyodo.nara.jp -sakurai.nara.jp -sango.nara.jp -shimoichi.nara.jp -shimokitayama.nara.jp -shinjo.nara.jp -soni.nara.jp -takatori.nara.jp -tawaramoto.nara.jp -tenkawa.nara.jp -tenri.nara.jp -uda.nara.jp -yamatokoriyama.nara.jp -yamatotakada.nara.jp -yamazoe.nara.jp -yoshino.nara.jp -aga.niigata.jp -agano.niigata.jp -gosen.niigata.jp -itoigawa.niigata.jp -izumozaki.niigata.jp -joetsu.niigata.jp -kamo.niigata.jp -kariwa.niigata.jp -kashiwazaki.niigata.jp -minamiuonuma.niigata.jp -mitsuke.niigata.jp -muika.niigata.jp -murakami.niigata.jp -myoko.niigata.jp -nagaoka.niigata.jp -niigata.niigata.jp -ojiya.niigata.jp -omi.niigata.jp -sado.niigata.jp -sanjo.niigata.jp -seiro.niigata.jp -seirou.niigata.jp -sekikawa.niigata.jp -shibata.niigata.jp -tagami.niigata.jp -tainai.niigata.jp -tochio.niigata.jp -tokamachi.niigata.jp -tsubame.niigata.jp -tsunan.niigata.jp -uonuma.niigata.jp -yahiko.niigata.jp -yoita.niigata.jp -yuzawa.niigata.jp -beppu.oita.jp -bungoono.oita.jp -bungotakada.oita.jp -hasama.oita.jp -hiji.oita.jp -himeshima.oita.jp -hita.oita.jp -kamitsue.oita.jp -kokonoe.oita.jp -kuju.oita.jp -kunisaki.oita.jp -kusu.oita.jp -oita.oita.jp -saiki.oita.jp -taketa.oita.jp -tsukumi.oita.jp -usa.oita.jp -usuki.oita.jp -yufu.oita.jp -akaiwa.okayama.jp -asakuchi.okayama.jp -bizen.okayama.jp -hayashima.okayama.jp -ibara.okayama.jp -kagamino.okayama.jp -kasaoka.okayama.jp -kibichuo.okayama.jp -kumenan.okayama.jp -kurashiki.okayama.jp -maniwa.okayama.jp -misaki.okayama.jp -nagi.okayama.jp -niimi.okayama.jp -nishiawakura.okayama.jp -okayama.okayama.jp -satosho.okayama.jp -setouchi.okayama.jp -shinjo.okayama.jp -shoo.okayama.jp -soja.okayama.jp -takahashi.okayama.jp -tamano.okayama.jp -tsuyama.okayama.jp -wake.okayama.jp -yakage.okayama.jp -aguni.okinawa.jp -ginowan.okinawa.jp -ginoza.okinawa.jp -gushikami.okinawa.jp -haebaru.okinawa.jp -higashi.okinawa.jp -hirara.okinawa.jp -iheya.okinawa.jp -ishigaki.okinawa.jp -ishikawa.okinawa.jp -itoman.okinawa.jp -izena.okinawa.jp -kadena.okinawa.jp -kin.okinawa.jp -kitadaito.okinawa.jp -kitanakagusuku.okinawa.jp -kumejima.okinawa.jp -kunigami.okinawa.jp -minamidaito.okinawa.jp -motobu.okinawa.jp -nago.okinawa.jp -naha.okinawa.jp -nakagusuku.okinawa.jp -nakijin.okinawa.jp -nanjo.okinawa.jp -nishihara.okinawa.jp -ogimi.okinawa.jp -okinawa.okinawa.jp -onna.okinawa.jp -shimoji.okinawa.jp -taketomi.okinawa.jp -tarama.okinawa.jp -tokashiki.okinawa.jp -tomigusuku.okinawa.jp -tonaki.okinawa.jp -urasoe.okinawa.jp -uruma.okinawa.jp -yaese.okinawa.jp -yomitan.okinawa.jp -yonabaru.okinawa.jp -yonaguni.okinawa.jp -zamami.okinawa.jp -abeno.osaka.jp -chihayaakasaka.osaka.jp -chuo.osaka.jp -daito.osaka.jp -fujiidera.osaka.jp -habikino.osaka.jp -hannan.osaka.jp -higashiosaka.osaka.jp -higashisumiyoshi.osaka.jp -higashiyodogawa.osaka.jp -hirakata.osaka.jp -ibaraki.osaka.jp -ikeda.osaka.jp -izumi.osaka.jp -izumiotsu.osaka.jp -izumisano.osaka.jp -kadoma.osaka.jp -kaizuka.osaka.jp -kanan.osaka.jp -kashiwara.osaka.jp -katano.osaka.jp -kawachinagano.osaka.jp -kishiwada.osaka.jp -kita.osaka.jp -kumatori.osaka.jp -matsubara.osaka.jp -minato.osaka.jp -minoh.osaka.jp -misaki.osaka.jp -moriguchi.osaka.jp -neyagawa.osaka.jp -nishi.osaka.jp -nose.osaka.jp -osakasayama.osaka.jp -sakai.osaka.jp -sayama.osaka.jp -sennan.osaka.jp -settsu.osaka.jp -shijonawate.osaka.jp -shimamoto.osaka.jp -suita.osaka.jp -tadaoka.osaka.jp -taishi.osaka.jp -tajiri.osaka.jp -takaishi.osaka.jp -takatsuki.osaka.jp -tondabayashi.osaka.jp -toyonaka.osaka.jp -toyono.osaka.jp -yao.osaka.jp -ariake.saga.jp -arita.saga.jp -fukudomi.saga.jp -genkai.saga.jp -hamatama.saga.jp -hizen.saga.jp -imari.saga.jp -kamimine.saga.jp -kanzaki.saga.jp -karatsu.saga.jp -kashima.saga.jp -kitagata.saga.jp -kitahata.saga.jp -kiyama.saga.jp -kouhoku.saga.jp -kyuragi.saga.jp -nishiarita.saga.jp -ogi.saga.jp -omachi.saga.jp -ouchi.saga.jp -saga.saga.jp -shiroishi.saga.jp -taku.saga.jp -tara.saga.jp -tosu.saga.jp -yoshinogari.saga.jp -arakawa.saitama.jp -asaka.saitama.jp -chichibu.saitama.jp -fujimi.saitama.jp -fujimino.saitama.jp -fukaya.saitama.jp -hanno.saitama.jp -hanyu.saitama.jp -hasuda.saitama.jp -hatogaya.saitama.jp -hatoyama.saitama.jp -hidaka.saitama.jp -higashichichibu.saitama.jp -higashimatsuyama.saitama.jp -honjo.saitama.jp -ina.saitama.jp -iruma.saitama.jp -iwatsuki.saitama.jp -kamiizumi.saitama.jp -kamikawa.saitama.jp -kamisato.saitama.jp -kasukabe.saitama.jp -kawagoe.saitama.jp -kawaguchi.saitama.jp -kawajima.saitama.jp -kazo.saitama.jp -kitamoto.saitama.jp -koshigaya.saitama.jp -kounosu.saitama.jp -kuki.saitama.jp -kumagaya.saitama.jp -matsubushi.saitama.jp -minano.saitama.jp -misato.saitama.jp -miyashiro.saitama.jp -miyoshi.saitama.jp -moroyama.saitama.jp -nagatoro.saitama.jp -namegawa.saitama.jp -niiza.saitama.jp -ogano.saitama.jp -ogawa.saitama.jp -ogose.saitama.jp -okegawa.saitama.jp -omiya.saitama.jp -otaki.saitama.jp -ranzan.saitama.jp -ryokami.saitama.jp -saitama.saitama.jp -sakado.saitama.jp -satte.saitama.jp -sayama.saitama.jp -shiki.saitama.jp -shiraoka.saitama.jp -soka.saitama.jp -sugito.saitama.jp -toda.saitama.jp -tokigawa.saitama.jp -tokorozawa.saitama.jp -tsurugashima.saitama.jp -urawa.saitama.jp -warabi.saitama.jp -yashio.saitama.jp -yokoze.saitama.jp -yono.saitama.jp -yorii.saitama.jp -yoshida.saitama.jp -yoshikawa.saitama.jp -yoshimi.saitama.jp -aisho.shiga.jp -gamo.shiga.jp -higashiomi.shiga.jp -hikone.shiga.jp -koka.shiga.jp -konan.shiga.jp -kosei.shiga.jp -koto.shiga.jp -kusatsu.shiga.jp -maibara.shiga.jp -moriyama.shiga.jp -nagahama.shiga.jp -nishiazai.shiga.jp -notogawa.shiga.jp -omihachiman.shiga.jp -otsu.shiga.jp -ritto.shiga.jp -ryuoh.shiga.jp -takashima.shiga.jp -takatsuki.shiga.jp -torahime.shiga.jp -toyosato.shiga.jp -yasu.shiga.jp -akagi.shimane.jp -ama.shimane.jp -gotsu.shimane.jp -hamada.shimane.jp -higashiizumo.shimane.jp -hikawa.shimane.jp -hikimi.shimane.jp -izumo.shimane.jp -kakinoki.shimane.jp -masuda.shimane.jp -matsue.shimane.jp -misato.shimane.jp -nishinoshima.shimane.jp -ohda.shimane.jp -okinoshima.shimane.jp -okuizumo.shimane.jp -shimane.shimane.jp -tamayu.shimane.jp -tsuwano.shimane.jp -unnan.shimane.jp -yakumo.shimane.jp -yasugi.shimane.jp -yatsuka.shimane.jp -arai.shizuoka.jp -atami.shizuoka.jp -fuji.shizuoka.jp -fujieda.shizuoka.jp -fujikawa.shizuoka.jp -fujinomiya.shizuoka.jp -fukuroi.shizuoka.jp -gotemba.shizuoka.jp -haibara.shizuoka.jp -hamamatsu.shizuoka.jp -higashiizu.shizuoka.jp -ito.shizuoka.jp -iwata.shizuoka.jp -izu.shizuoka.jp -izunokuni.shizuoka.jp -kakegawa.shizuoka.jp -kannami.shizuoka.jp -kawanehon.shizuoka.jp -kawazu.shizuoka.jp -kikugawa.shizuoka.jp -kosai.shizuoka.jp -makinohara.shizuoka.jp -matsuzaki.shizuoka.jp -minamiizu.shizuoka.jp -mishima.shizuoka.jp -morimachi.shizuoka.jp -nishiizu.shizuoka.jp -numazu.shizuoka.jp -omaezaki.shizuoka.jp -shimada.shizuoka.jp -shimizu.shizuoka.jp -shimoda.shizuoka.jp -shizuoka.shizuoka.jp -susono.shizuoka.jp -yaizu.shizuoka.jp -yoshida.shizuoka.jp -ashikaga.tochigi.jp -bato.tochigi.jp -haga.tochigi.jp -ichikai.tochigi.jp -iwafune.tochigi.jp -kaminokawa.tochigi.jp -kanuma.tochigi.jp -karasuyama.tochigi.jp -kuroiso.tochigi.jp -mashiko.tochigi.jp -mibu.tochigi.jp -moka.tochigi.jp -motegi.tochigi.jp -nasu.tochigi.jp -nasushiobara.tochigi.jp -nikko.tochigi.jp -nishikata.tochigi.jp -nogi.tochigi.jp -ohira.tochigi.jp -ohtawara.tochigi.jp -oyama.tochigi.jp -sakura.tochigi.jp -sano.tochigi.jp -shimotsuke.tochigi.jp -shioya.tochigi.jp -takanezawa.tochigi.jp -tochigi.tochigi.jp -tsuga.tochigi.jp -ujiie.tochigi.jp -utsunomiya.tochigi.jp -yaita.tochigi.jp -aizumi.tokushima.jp -anan.tokushima.jp -ichiba.tokushima.jp -itano.tokushima.jp -kainan.tokushima.jp -komatsushima.tokushima.jp -matsushige.tokushima.jp -mima.tokushima.jp -minami.tokushima.jp -miyoshi.tokushima.jp -mugi.tokushima.jp -nakagawa.tokushima.jp -naruto.tokushima.jp -sanagochi.tokushima.jp -shishikui.tokushima.jp -tokushima.tokushima.jp -wajiki.tokushima.jp -adachi.tokyo.jp -akiruno.tokyo.jp -akishima.tokyo.jp -aogashima.tokyo.jp -arakawa.tokyo.jp -bunkyo.tokyo.jp -chiyoda.tokyo.jp -chofu.tokyo.jp -chuo.tokyo.jp -edogawa.tokyo.jp -fuchu.tokyo.jp -fussa.tokyo.jp -hachijo.tokyo.jp -hachioji.tokyo.jp -hamura.tokyo.jp -higashikurume.tokyo.jp -higashimurayama.tokyo.jp -higashiyamato.tokyo.jp -hino.tokyo.jp -hinode.tokyo.jp -hinohara.tokyo.jp -inagi.tokyo.jp -itabashi.tokyo.jp -katsushika.tokyo.jp -kita.tokyo.jp -kiyose.tokyo.jp -kodaira.tokyo.jp -koganei.tokyo.jp -kokubunji.tokyo.jp -komae.tokyo.jp -koto.tokyo.jp -kouzushima.tokyo.jp -kunitachi.tokyo.jp -machida.tokyo.jp -meguro.tokyo.jp -minato.tokyo.jp -mitaka.tokyo.jp -mizuho.tokyo.jp -musashimurayama.tokyo.jp -musashino.tokyo.jp -nakano.tokyo.jp -nerima.tokyo.jp -ogasawara.tokyo.jp -okutama.tokyo.jp -ome.tokyo.jp -oshima.tokyo.jp -ota.tokyo.jp -setagaya.tokyo.jp -shibuya.tokyo.jp -shinagawa.tokyo.jp -shinjuku.tokyo.jp -suginami.tokyo.jp -sumida.tokyo.jp -tachikawa.tokyo.jp -taito.tokyo.jp -tama.tokyo.jp -toshima.tokyo.jp -chizu.tottori.jp -hino.tottori.jp -kawahara.tottori.jp -koge.tottori.jp -kotoura.tottori.jp -misasa.tottori.jp -nanbu.tottori.jp -nichinan.tottori.jp -sakaiminato.tottori.jp -tottori.tottori.jp -wakasa.tottori.jp -yazu.tottori.jp -yonago.tottori.jp -asahi.toyama.jp -fuchu.toyama.jp -fukumitsu.toyama.jp -funahashi.toyama.jp -himi.toyama.jp -imizu.toyama.jp -inami.toyama.jp -johana.toyama.jp -kamiichi.toyama.jp -kurobe.toyama.jp -nakaniikawa.toyama.jp -namerikawa.toyama.jp -nanto.toyama.jp -nyuzen.toyama.jp -oyabe.toyama.jp -taira.toyama.jp -takaoka.toyama.jp -tateyama.toyama.jp -toga.toyama.jp -tonami.toyama.jp -toyama.toyama.jp -unazuki.toyama.jp -uozu.toyama.jp -yamada.toyama.jp -arida.wakayama.jp -aridagawa.wakayama.jp -gobo.wakayama.jp -hashimoto.wakayama.jp -hidaka.wakayama.jp -hirogawa.wakayama.jp -inami.wakayama.jp -iwade.wakayama.jp -kainan.wakayama.jp -kamitonda.wakayama.jp -katsuragi.wakayama.jp -kimino.wakayama.jp -kinokawa.wakayama.jp -kitayama.wakayama.jp -koya.wakayama.jp -koza.wakayama.jp -kozagawa.wakayama.jp -kudoyama.wakayama.jp -kushimoto.wakayama.jp -mihama.wakayama.jp -misato.wakayama.jp -nachikatsuura.wakayama.jp -shingu.wakayama.jp -shirahama.wakayama.jp -taiji.wakayama.jp -tanabe.wakayama.jp -wakayama.wakayama.jp -yuasa.wakayama.jp -yura.wakayama.jp -asahi.yamagata.jp -funagata.yamagata.jp -higashine.yamagata.jp -iide.yamagata.jp -kahoku.yamagata.jp -kaminoyama.yamagata.jp -kaneyama.yamagata.jp -kawanishi.yamagata.jp -mamurogawa.yamagata.jp -mikawa.yamagata.jp -murayama.yamagata.jp -nagai.yamagata.jp -nakayama.yamagata.jp -nanyo.yamagata.jp -nishikawa.yamagata.jp -obanazawa.yamagata.jp -oe.yamagata.jp -oguni.yamagata.jp -ohkura.yamagata.jp -oishida.yamagata.jp -sagae.yamagata.jp -sakata.yamagata.jp -sakegawa.yamagata.jp -shinjo.yamagata.jp -shirataka.yamagata.jp -shonai.yamagata.jp -takahata.yamagata.jp -tendo.yamagata.jp -tozawa.yamagata.jp -tsuruoka.yamagata.jp -yamagata.yamagata.jp -yamanobe.yamagata.jp -yonezawa.yamagata.jp -yuza.yamagata.jp -abu.yamaguchi.jp -hagi.yamaguchi.jp -hikari.yamaguchi.jp -hofu.yamaguchi.jp -iwakuni.yamaguchi.jp -kudamatsu.yamaguchi.jp -mitou.yamaguchi.jp -nagato.yamaguchi.jp -oshima.yamaguchi.jp -shimonoseki.yamaguchi.jp -shunan.yamaguchi.jp -tabuse.yamaguchi.jp -tokuyama.yamaguchi.jp -toyota.yamaguchi.jp -ube.yamaguchi.jp -yuu.yamaguchi.jp -chuo.yamanashi.jp -doshi.yamanashi.jp -fuefuki.yamanashi.jp -fujikawa.yamanashi.jp -fujikawaguchiko.yamanashi.jp -fujiyoshida.yamanashi.jp -hayakawa.yamanashi.jp -hokuto.yamanashi.jp -ichikawamisato.yamanashi.jp -kai.yamanashi.jp -kofu.yamanashi.jp -koshu.yamanashi.jp -kosuge.yamanashi.jp -minami-alps.yamanashi.jp -minobu.yamanashi.jp -nakamichi.yamanashi.jp -nanbu.yamanashi.jp -narusawa.yamanashi.jp -nirasaki.yamanashi.jp -nishikatsura.yamanashi.jp -oshino.yamanashi.jp -otsuki.yamanashi.jp -showa.yamanashi.jp -tabayama.yamanashi.jp -tsuru.yamanashi.jp -uenohara.yamanashi.jp -yamanakako.yamanashi.jp -yamanashi.yamanashi.jp - -// ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains -ke -ac.ke -co.ke -go.ke -info.ke -me.ke -mobi.ke -ne.ke -or.ke -sc.ke - -// kg : http://www.domain.kg/dmn_n.html -kg -org.kg -net.kg -com.kg -edu.kg -gov.kg -mil.kg - -// kh : http://www.mptc.gov.kh/dns_registration.htm -*.kh - -// ki : http://www.ki/dns/index.html -ki -edu.ki -biz.ki -net.ki -org.ki -gov.ki -info.ki -com.ki - -// km : https://en.wikipedia.org/wiki/.km -// http://www.domaine.km/documents/charte.doc -km -org.km -nom.km -gov.km -prd.km -tm.km -edu.km -mil.km -ass.km -com.km -// These are only mentioned as proposed suggestions at domaine.km, but -// https://en.wikipedia.org/wiki/.km says they're available for registration: -coop.km -asso.km -presse.km -medecin.km -notaires.km -pharmaciens.km -veterinaire.km -gouv.km - -// kn : https://en.wikipedia.org/wiki/.kn -// http://www.dot.kn/domainRules.html -kn -net.kn -org.kn -edu.kn -gov.kn - -// kp : http://www.kcce.kp/en_index.php -kp -com.kp -edu.kp -gov.kp -org.kp -rep.kp -tra.kp - -// kr : https://en.wikipedia.org/wiki/.kr -// see also: http://domain.nida.or.kr/eng/registration.jsp -kr -ac.kr -co.kr -es.kr -go.kr -hs.kr -kg.kr -mil.kr -ms.kr -ne.kr -or.kr -pe.kr -re.kr -sc.kr -// kr geographical names -busan.kr -chungbuk.kr -chungnam.kr -daegu.kr -daejeon.kr -gangwon.kr -gwangju.kr -gyeongbuk.kr -gyeonggi.kr -gyeongnam.kr -incheon.kr -jeju.kr -jeonbuk.kr -jeonnam.kr -seoul.kr -ulsan.kr - -// kw : https://www.nic.kw/policies/ -// Confirmed by registry -kw -com.kw -edu.kw -emb.kw -gov.kw -ind.kw -net.kw -org.kw - -// ky : http://www.icta.ky/da_ky_reg_dom.php -// Confirmed by registry 2008-06-17 -ky -com.ky -edu.ky -net.ky -org.ky - -// kz : https://en.wikipedia.org/wiki/.kz -// see also: http://www.nic.kz/rules/index.jsp -kz -org.kz -edu.kz -net.kz -gov.kz -mil.kz -com.kz - -// la : https://en.wikipedia.org/wiki/.la -// Submitted by registry -la -int.la -net.la -info.la -edu.la -gov.la -per.la -com.la -org.la - -// lb : https://en.wikipedia.org/wiki/.lb -// Submitted by registry -lb -com.lb -edu.lb -gov.lb -net.lb -org.lb - -// lc : https://en.wikipedia.org/wiki/.lc -// see also: http://www.nic.lc/rules.htm -lc -com.lc -net.lc -co.lc -org.lc -edu.lc -gov.lc - -// li : https://en.wikipedia.org/wiki/.li -li - -// lk : https://www.nic.lk/index.php/domain-registration/lk-domain-naming-structure -lk -gov.lk -sch.lk -net.lk -int.lk -com.lk -org.lk -edu.lk -ngo.lk -soc.lk -web.lk -ltd.lk -assn.lk -grp.lk -hotel.lk -ac.lk - -// lr : http://psg.com/dns/lr/lr.txt -// Submitted by registry -lr -com.lr -edu.lr -gov.lr -org.lr -net.lr - -// ls : http://www.nic.ls/ -// Confirmed by registry -ls -ac.ls -biz.ls -co.ls -edu.ls -gov.ls -info.ls -net.ls -org.ls -sc.ls - -// lt : https://en.wikipedia.org/wiki/.lt -lt -// gov.lt : http://www.gov.lt/index_en.php -gov.lt - -// lu : http://www.dns.lu/en/ -lu - -// lv : http://www.nic.lv/DNS/En/generic.php -lv -com.lv -edu.lv -gov.lv -org.lv -mil.lv -id.lv -net.lv -asn.lv -conf.lv - -// ly : http://www.nic.ly/regulations.php -ly -com.ly -net.ly -gov.ly -plc.ly -edu.ly -sch.ly -med.ly -org.ly -id.ly - -// ma : https://en.wikipedia.org/wiki/.ma -// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf -ma -co.ma -net.ma -gov.ma -org.ma -ac.ma -press.ma - -// mc : http://www.nic.mc/ -mc -tm.mc -asso.mc - -// md : https://en.wikipedia.org/wiki/.md -md - -// me : https://en.wikipedia.org/wiki/.me -me -co.me -net.me -org.me -edu.me -ac.me -gov.me -its.me -priv.me - -// mg : http://nic.mg/nicmg/?page_id=39 -mg -org.mg -nom.mg -gov.mg -prd.mg -tm.mg -edu.mg -mil.mg -com.mg -co.mg - -// mh : https://en.wikipedia.org/wiki/.mh -mh - -// mil : https://en.wikipedia.org/wiki/.mil -mil - -// mk : https://en.wikipedia.org/wiki/.mk -// see also: http://dns.marnet.net.mk/postapka.php -mk -com.mk -org.mk -net.mk -edu.mk -gov.mk -inf.mk -name.mk - -// ml : http://www.gobin.info/domainname/ml-template.doc -// see also: https://en.wikipedia.org/wiki/.ml -ml -com.ml -edu.ml -gouv.ml -gov.ml -net.ml -org.ml -presse.ml - -// mm : https://en.wikipedia.org/wiki/.mm -*.mm - -// mn : https://en.wikipedia.org/wiki/.mn -mn -gov.mn -edu.mn -org.mn - -// mo : http://www.monic.net.mo/ -mo -com.mo -net.mo -org.mo -edu.mo -gov.mo - -// mobi : https://en.wikipedia.org/wiki/.mobi -mobi - -// mp : http://www.dot.mp/ -// Confirmed by registry 2008-06-17 -mp - -// mq : https://en.wikipedia.org/wiki/.mq -mq - -// mr : https://en.wikipedia.org/wiki/.mr -mr -gov.mr - -// ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf -ms -com.ms -edu.ms -gov.ms -net.ms -org.ms - -// mt : https://www.nic.org.mt/go/policy -// Submitted by registry -mt -com.mt -edu.mt -net.mt -org.mt - -// mu : https://en.wikipedia.org/wiki/.mu -mu -com.mu -net.mu -org.mu -gov.mu -ac.mu -co.mu -or.mu - -// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ -museum - -// mv : https://en.wikipedia.org/wiki/.mv -// "mv" included because, contra Wikipedia, google.mv exists. -mv -aero.mv -biz.mv -com.mv -coop.mv -edu.mv -gov.mv -info.mv -int.mv -mil.mv -museum.mv -name.mv -net.mv -org.mv -pro.mv - -// mw : http://www.registrar.mw/ -mw -ac.mw -biz.mw -co.mw -com.mw -coop.mw -edu.mw -gov.mw -int.mw -museum.mw -net.mw -org.mw - -// mx : http://www.nic.mx/ -// Submitted by registry -mx -com.mx -org.mx -gob.mx -edu.mx -net.mx - -// my : http://www.mynic.my/ -// Available strings: https://mynic.my/resources/domains/buying-a-domain/ -my -biz.my -com.my -edu.my -gov.my -mil.my -name.my -net.my -org.my - -// mz : http://www.uem.mz/ -// Submitted by registry -mz -ac.mz -adv.mz -co.mz -edu.mz -gov.mz -mil.mz -net.mz -org.mz - -// na : http://www.na-nic.com.na/ -// http://www.info.na/domain/ -na -info.na -pro.na -name.na -school.na -or.na -dr.na -us.na -mx.na -ca.na -in.na -cc.na -tv.na -ws.na -mobi.na -co.na -com.na -org.na - -// name : has 2nd-level tlds, but there's no list of them -name - -// nc : http://www.cctld.nc/ -nc -asso.nc -nom.nc - -// ne : https://en.wikipedia.org/wiki/.ne -ne - -// net : https://en.wikipedia.org/wiki/.net -net - -// nf : https://en.wikipedia.org/wiki/.nf -nf -com.nf -net.nf -per.nf -rec.nf -web.nf -arts.nf -firm.nf -info.nf -other.nf -store.nf - -// ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds -ng -com.ng -edu.ng -gov.ng -i.ng -mil.ng -mobi.ng -name.ng -net.ng -org.ng -sch.ng - -// ni : http://www.nic.ni/ -ni -ac.ni -biz.ni -co.ni -com.ni -edu.ni -gob.ni -in.ni -info.ni -int.ni -mil.ni -net.ni -nom.ni -org.ni -web.ni - -// nl : https://en.wikipedia.org/wiki/.nl -// https://www.sidn.nl/ -// ccTLD for the Netherlands -nl - -// no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ -// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ -// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ -// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ -// RSS feed: https://teknisk.norid.no/en/feed/ -no -// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ -fhs.no -vgs.no -fylkesbibl.no -folkebibl.no -museum.no -idrett.no -priv.no -// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ -mil.no -stat.no -dep.no -kommune.no -herad.no -// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ -// counties -aa.no -ah.no -bu.no -fm.no -hl.no -hm.no -jan-mayen.no -mr.no -nl.no -nt.no -of.no -ol.no -oslo.no -rl.no -sf.no -st.no -svalbard.no -tm.no -tr.no -va.no -vf.no -// primary and lower secondary schools per county -gs.aa.no -gs.ah.no -gs.bu.no -gs.fm.no -gs.hl.no -gs.hm.no -gs.jan-mayen.no -gs.mr.no -gs.nl.no -gs.nt.no -gs.of.no -gs.ol.no -gs.oslo.no -gs.rl.no -gs.sf.no -gs.st.no -gs.svalbard.no -gs.tm.no -gs.tr.no -gs.va.no -gs.vf.no -// cities -akrehamn.no -åkrehamn.no -algard.no -ålgård.no -arna.no -brumunddal.no -bryne.no -bronnoysund.no -brønnøysund.no -drobak.no -drøbak.no -egersund.no -fetsund.no -floro.no -florø.no -fredrikstad.no -hokksund.no -honefoss.no -hønefoss.no -jessheim.no -jorpeland.no -jørpeland.no -kirkenes.no -kopervik.no -krokstadelva.no -langevag.no -langevåg.no -leirvik.no -mjondalen.no -mjøndalen.no -mo-i-rana.no -mosjoen.no -mosjøen.no -nesoddtangen.no -orkanger.no -osoyro.no -osøyro.no -raholt.no -råholt.no -sandnessjoen.no -sandnessjøen.no -skedsmokorset.no -slattum.no -spjelkavik.no -stathelle.no -stavern.no -stjordalshalsen.no -stjørdalshalsen.no -tananger.no -tranby.no -vossevangen.no -// communities -afjord.no -åfjord.no -agdenes.no -al.no -ål.no -alesund.no -ålesund.no -alstahaug.no -alta.no -áltá.no -alaheadju.no -álaheadju.no -alvdal.no -amli.no -åmli.no -amot.no -åmot.no -andebu.no -andoy.no -andøy.no -andasuolo.no -ardal.no -årdal.no -aremark.no -arendal.no -ås.no -aseral.no -åseral.no -asker.no -askim.no -askvoll.no -askoy.no -askøy.no -asnes.no -åsnes.no -audnedaln.no -aukra.no -aure.no -aurland.no -aurskog-holand.no -aurskog-høland.no -austevoll.no -austrheim.no -averoy.no -averøy.no -balestrand.no -ballangen.no -balat.no -bálát.no -balsfjord.no -bahccavuotna.no -báhccavuotna.no -bamble.no -bardu.no -beardu.no -beiarn.no -bajddar.no -bájddar.no -baidar.no -báidár.no -berg.no -bergen.no -berlevag.no -berlevåg.no -bearalvahki.no -bearalváhki.no -bindal.no -birkenes.no -bjarkoy.no -bjarkøy.no -bjerkreim.no -bjugn.no -bodo.no -bodø.no -badaddja.no -bådåddjå.no -budejju.no -bokn.no -bremanger.no -bronnoy.no -brønnøy.no -bygland.no -bykle.no -barum.no -bærum.no -bo.telemark.no -bø.telemark.no -bo.nordland.no -bø.nordland.no -bievat.no -bievát.no -bomlo.no -bømlo.no -batsfjord.no -båtsfjord.no -bahcavuotna.no -báhcavuotna.no -dovre.no -drammen.no -drangedal.no -dyroy.no -dyrøy.no -donna.no -dønna.no -eid.no -eidfjord.no -eidsberg.no -eidskog.no -eidsvoll.no -eigersund.no -elverum.no -enebakk.no -engerdal.no -etne.no -etnedal.no -evenes.no -evenassi.no -evenášši.no -evje-og-hornnes.no -farsund.no -fauske.no -fuossko.no -fuoisku.no -fedje.no -fet.no -finnoy.no -finnøy.no -fitjar.no -fjaler.no -fjell.no -flakstad.no -flatanger.no -flekkefjord.no -flesberg.no -flora.no -fla.no -flå.no -folldal.no -forsand.no -fosnes.no -frei.no -frogn.no -froland.no -frosta.no -frana.no -fræna.no -froya.no -frøya.no -fusa.no -fyresdal.no -forde.no -førde.no -gamvik.no -gangaviika.no -gáŋgaviika.no -gaular.no -gausdal.no -gildeskal.no -gildeskål.no -giske.no -gjemnes.no -gjerdrum.no -gjerstad.no -gjesdal.no -gjovik.no -gjøvik.no -gloppen.no -gol.no -gran.no -grane.no -granvin.no -gratangen.no -grimstad.no -grong.no -kraanghke.no -kråanghke.no -grue.no -gulen.no -hadsel.no -halden.no -halsa.no -hamar.no -hamaroy.no -habmer.no -hábmer.no -hapmir.no -hápmir.no -hammerfest.no -hammarfeasta.no -hámmárfeasta.no -haram.no -hareid.no -harstad.no -hasvik.no -aknoluokta.no -ákŋoluokta.no -hattfjelldal.no -aarborte.no -haugesund.no -hemne.no -hemnes.no -hemsedal.no -heroy.more-og-romsdal.no -herøy.møre-og-romsdal.no -heroy.nordland.no -herøy.nordland.no -hitra.no -hjartdal.no -hjelmeland.no -hobol.no -hobøl.no -hof.no -hol.no -hole.no -holmestrand.no -holtalen.no -holtålen.no -hornindal.no -horten.no -hurdal.no -hurum.no -hvaler.no -hyllestad.no -hagebostad.no -hægebostad.no -hoyanger.no -høyanger.no -hoylandet.no -høylandet.no -ha.no -hå.no -ibestad.no -inderoy.no -inderøy.no -iveland.no -jevnaker.no -jondal.no -jolster.no -jølster.no -karasjok.no -karasjohka.no -kárášjohka.no -karlsoy.no -galsa.no -gálsá.no -karmoy.no -karmøy.no -kautokeino.no -guovdageaidnu.no -klepp.no -klabu.no -klæbu.no -kongsberg.no -kongsvinger.no -kragero.no -kragerø.no -kristiansand.no -kristiansund.no -krodsherad.no -krødsherad.no -kvalsund.no -rahkkeravju.no -ráhkkerávju.no -kvam.no -kvinesdal.no -kvinnherad.no -kviteseid.no -kvitsoy.no -kvitsøy.no -kvafjord.no -kvæfjord.no -giehtavuoatna.no -kvanangen.no -kvænangen.no -navuotna.no -návuotna.no -kafjord.no -kåfjord.no -gaivuotna.no -gáivuotna.no -larvik.no -lavangen.no -lavagis.no -loabat.no -loabát.no -lebesby.no -davvesiida.no -leikanger.no -leirfjord.no -leka.no -leksvik.no -lenvik.no -leangaviika.no -leaŋgaviika.no -lesja.no -levanger.no -lier.no -lierne.no -lillehammer.no -lillesand.no -lindesnes.no -lindas.no -lindås.no -lom.no -loppa.no -lahppi.no -láhppi.no -lund.no -lunner.no -luroy.no -lurøy.no -luster.no -lyngdal.no -lyngen.no -ivgu.no -lardal.no -lerdal.no -lærdal.no -lodingen.no -lødingen.no -lorenskog.no -lørenskog.no -loten.no -løten.no -malvik.no -masoy.no -måsøy.no -muosat.no -muosát.no -mandal.no -marker.no -marnardal.no -masfjorden.no -meland.no -meldal.no -melhus.no -meloy.no -meløy.no -meraker.no -meråker.no -moareke.no -moåreke.no -midsund.no -midtre-gauldal.no -modalen.no -modum.no -molde.no -moskenes.no -moss.no -mosvik.no -malselv.no -målselv.no -malatvuopmi.no -málatvuopmi.no -namdalseid.no -aejrie.no -namsos.no -namsskogan.no -naamesjevuemie.no -nååmesjevuemie.no -laakesvuemie.no -nannestad.no -narvik.no -narviika.no -naustdal.no -nedre-eiker.no -nes.akershus.no -nes.buskerud.no -nesna.no -nesodden.no -nesseby.no -unjarga.no -unjárga.no -nesset.no -nissedal.no -nittedal.no -nord-aurdal.no -nord-fron.no -nord-odal.no -norddal.no -nordkapp.no -davvenjarga.no -davvenjárga.no -nordre-land.no -nordreisa.no -raisa.no -ráisa.no -nore-og-uvdal.no -notodden.no -naroy.no -nærøy.no -notteroy.no -nøtterøy.no -odda.no -oksnes.no -øksnes.no -oppdal.no -oppegard.no -oppegård.no -orkdal.no -orland.no -ørland.no -orskog.no -ørskog.no -orsta.no -ørsta.no -os.hedmark.no -os.hordaland.no -osen.no -osteroy.no -osterøy.no -ostre-toten.no -østre-toten.no -overhalla.no -ovre-eiker.no -øvre-eiker.no -oyer.no -øyer.no -oygarden.no -øygarden.no -oystre-slidre.no -øystre-slidre.no -porsanger.no -porsangu.no -porsáŋgu.no -porsgrunn.no -radoy.no -radøy.no -rakkestad.no -rana.no -ruovat.no -randaberg.no -rauma.no -rendalen.no -rennebu.no -rennesoy.no -rennesøy.no -rindal.no -ringebu.no -ringerike.no -ringsaker.no -rissa.no -risor.no -risør.no -roan.no -rollag.no -rygge.no -ralingen.no -rælingen.no -rodoy.no -rødøy.no -romskog.no -rømskog.no -roros.no -røros.no -rost.no -røst.no -royken.no -røyken.no -royrvik.no -røyrvik.no -rade.no -råde.no -salangen.no -siellak.no -saltdal.no -salat.no -sálát.no -sálat.no -samnanger.no -sande.more-og-romsdal.no -sande.møre-og-romsdal.no -sande.vestfold.no -sandefjord.no -sandnes.no -sandoy.no -sandøy.no -sarpsborg.no -sauda.no -sauherad.no -sel.no -selbu.no -selje.no -seljord.no -sigdal.no -siljan.no -sirdal.no -skaun.no -skedsmo.no -ski.no -skien.no -skiptvet.no -skjervoy.no -skjervøy.no -skierva.no -skiervá.no -skjak.no -skjåk.no -skodje.no -skanland.no -skånland.no -skanit.no -skánit.no -smola.no -smøla.no -snillfjord.no -snasa.no -snåsa.no -snoasa.no -snaase.no -snåase.no -sogndal.no -sokndal.no -sola.no -solund.no -songdalen.no -sortland.no -spydeberg.no -stange.no -stavanger.no -steigen.no -steinkjer.no -stjordal.no -stjørdal.no -stokke.no -stor-elvdal.no -stord.no -stordal.no -storfjord.no -omasvuotna.no -strand.no -stranda.no -stryn.no -sula.no -suldal.no -sund.no -sunndal.no -surnadal.no -sveio.no -svelvik.no -sykkylven.no -sogne.no -søgne.no -somna.no -sømna.no -sondre-land.no -søndre-land.no -sor-aurdal.no -sør-aurdal.no -sor-fron.no -sør-fron.no -sor-odal.no -sør-odal.no -sor-varanger.no -sør-varanger.no -matta-varjjat.no -mátta-várjjat.no -sorfold.no -sørfold.no -sorreisa.no -sørreisa.no -sorum.no -sørum.no -tana.no -deatnu.no -time.no -tingvoll.no -tinn.no -tjeldsund.no -dielddanuorri.no -tjome.no -tjøme.no -tokke.no -tolga.no -torsken.no -tranoy.no -tranøy.no -tromso.no -tromsø.no -tromsa.no -romsa.no -trondheim.no -troandin.no -trysil.no -trana.no -træna.no -trogstad.no -trøgstad.no -tvedestrand.no -tydal.no -tynset.no -tysfjord.no -divtasvuodna.no -divttasvuotna.no -tysnes.no -tysvar.no -tysvær.no -tonsberg.no -tønsberg.no -ullensaker.no -ullensvang.no -ulvik.no -utsira.no -vadso.no -vadsø.no -cahcesuolo.no -čáhcesuolo.no -vaksdal.no -valle.no -vang.no -vanylven.no -vardo.no -vardø.no -varggat.no -várggát.no -vefsn.no -vaapste.no -vega.no -vegarshei.no -vegårshei.no -vennesla.no -verdal.no -verran.no -vestby.no -vestnes.no -vestre-slidre.no -vestre-toten.no -vestvagoy.no -vestvågøy.no -vevelstad.no -vik.no -vikna.no -vindafjord.no -volda.no -voss.no -varoy.no -værøy.no -vagan.no -vågan.no -voagat.no -vagsoy.no -vågsøy.no -vaga.no -vågå.no -valer.ostfold.no -våler.østfold.no -valer.hedmark.no -våler.hedmark.no - -// np : http://www.mos.com.np/register.html -*.np - -// nr : http://cenpac.net.nr/dns/index.html -// Submitted by registry -nr -biz.nr -info.nr -gov.nr -edu.nr -org.nr -net.nr -com.nr - -// nu : https://en.wikipedia.org/wiki/.nu -nu - -// nz : https://en.wikipedia.org/wiki/.nz -// Submitted by registry -nz -ac.nz -co.nz -cri.nz -geek.nz -gen.nz -govt.nz -health.nz -iwi.nz -kiwi.nz -maori.nz -mil.nz -māori.nz -net.nz -org.nz -parliament.nz -school.nz - -// om : https://en.wikipedia.org/wiki/.om -om -co.om -com.om -edu.om -gov.om -med.om -museum.om -net.om -org.om -pro.om - -// onion : https://tools.ietf.org/html/rfc7686 -onion - -// org : https://en.wikipedia.org/wiki/.org -org - -// pa : http://www.nic.pa/ -// Some additional second level "domains" resolve directly as hostnames, such as -// pannet.pa, so we add a rule for "pa". -pa -ac.pa -gob.pa -com.pa -org.pa -sld.pa -edu.pa -net.pa -ing.pa -abo.pa -med.pa -nom.pa - -// pe : https://www.nic.pe/InformeFinalComision.pdf -pe -edu.pe -gob.pe -nom.pe -mil.pe -org.pe -com.pe -net.pe - -// pf : http://www.gobin.info/domainname/formulaire-pf.pdf -pf -com.pf -org.pf -edu.pf - -// pg : https://en.wikipedia.org/wiki/.pg -*.pg - -// ph : http://www.domains.ph/FAQ2.asp -// Submitted by registry -ph -com.ph -net.ph -org.ph -gov.ph -edu.ph -ngo.ph -mil.ph -i.ph - -// pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK -pk -com.pk -net.pk -edu.pk -org.pk -fam.pk -biz.pk -web.pk -gov.pk -gob.pk -gok.pk -gon.pk -gop.pk -gos.pk -info.pk - -// pl http://www.dns.pl/english/index.html -// Submitted by registry -pl -com.pl -net.pl -org.pl -// pl functional domains (http://www.dns.pl/english/index.html) -aid.pl -agro.pl -atm.pl -auto.pl -biz.pl -edu.pl -gmina.pl -gsm.pl -info.pl -mail.pl -miasta.pl -media.pl -mil.pl -nieruchomosci.pl -nom.pl -pc.pl -powiat.pl -priv.pl -realestate.pl -rel.pl -sex.pl -shop.pl -sklep.pl -sos.pl -szkola.pl -targi.pl -tm.pl -tourism.pl -travel.pl -turystyka.pl -// Government domains -gov.pl -ap.gov.pl -griw.gov.pl -ic.gov.pl -is.gov.pl -kmpsp.gov.pl -konsulat.gov.pl -kppsp.gov.pl -kwp.gov.pl -kwpsp.gov.pl -mup.gov.pl -mw.gov.pl -oia.gov.pl -oirm.gov.pl -oke.gov.pl -oow.gov.pl -oschr.gov.pl -oum.gov.pl -pa.gov.pl -pinb.gov.pl -piw.gov.pl -po.gov.pl -pr.gov.pl -psp.gov.pl -psse.gov.pl -pup.gov.pl -rzgw.gov.pl -sa.gov.pl -sdn.gov.pl -sko.gov.pl -so.gov.pl -sr.gov.pl -starostwo.gov.pl -ug.gov.pl -ugim.gov.pl -um.gov.pl -umig.gov.pl -upow.gov.pl -uppo.gov.pl -us.gov.pl -uw.gov.pl -uzs.gov.pl -wif.gov.pl -wiih.gov.pl -winb.gov.pl -wios.gov.pl -witd.gov.pl -wiw.gov.pl -wkz.gov.pl -wsa.gov.pl -wskr.gov.pl -wsse.gov.pl -wuoz.gov.pl -wzmiuw.gov.pl -zp.gov.pl -zpisdn.gov.pl -// pl regional domains (http://www.dns.pl/english/index.html) -augustow.pl -babia-gora.pl -bedzin.pl -beskidy.pl -bialowieza.pl -bialystok.pl -bielawa.pl -bieszczady.pl -boleslawiec.pl -bydgoszcz.pl -bytom.pl -cieszyn.pl -czeladz.pl -czest.pl -dlugoleka.pl -elblag.pl -elk.pl -glogow.pl -gniezno.pl -gorlice.pl -grajewo.pl -ilawa.pl -jaworzno.pl -jelenia-gora.pl -jgora.pl -kalisz.pl -kazimierz-dolny.pl -karpacz.pl -kartuzy.pl -kaszuby.pl -katowice.pl -kepno.pl -ketrzyn.pl -klodzko.pl -kobierzyce.pl -kolobrzeg.pl -konin.pl -konskowola.pl -kutno.pl -lapy.pl -lebork.pl -legnica.pl -lezajsk.pl -limanowa.pl -lomza.pl -lowicz.pl -lubin.pl -lukow.pl -malbork.pl -malopolska.pl -mazowsze.pl -mazury.pl -mielec.pl -mielno.pl -mragowo.pl -naklo.pl -nowaruda.pl -nysa.pl -olawa.pl -olecko.pl -olkusz.pl -olsztyn.pl -opoczno.pl -opole.pl -ostroda.pl -ostroleka.pl -ostrowiec.pl -ostrowwlkp.pl -pila.pl -pisz.pl -podhale.pl -podlasie.pl -polkowice.pl -pomorze.pl -pomorskie.pl -prochowice.pl -pruszkow.pl -przeworsk.pl -pulawy.pl -radom.pl -rawa-maz.pl -rybnik.pl -rzeszow.pl -sanok.pl -sejny.pl -slask.pl -slupsk.pl -sosnowiec.pl -stalowa-wola.pl -skoczow.pl -starachowice.pl -stargard.pl -suwalki.pl -swidnica.pl -swiebodzin.pl -swinoujscie.pl -szczecin.pl -szczytno.pl -tarnobrzeg.pl -tgory.pl -turek.pl -tychy.pl -ustka.pl -walbrzych.pl -warmia.pl -warszawa.pl -waw.pl -wegrow.pl -wielun.pl -wlocl.pl -wloclawek.pl -wodzislaw.pl -wolomin.pl -wroclaw.pl -zachpomor.pl -zagan.pl -zarow.pl -zgora.pl -zgorzelec.pl - -// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -pm - -// pn : http://www.government.pn/PnRegistry/policies.htm -pn -gov.pn -co.pn -org.pn -edu.pn -net.pn - -// post : https://en.wikipedia.org/wiki/.post -post - -// pr : http://www.nic.pr/index.asp?f=1 -pr -com.pr -net.pr -org.pr -gov.pr -edu.pr -isla.pr -pro.pr -biz.pr -info.pr -name.pr -// these aren't mentioned on nic.pr, but on https://en.wikipedia.org/wiki/.pr -est.pr -prof.pr -ac.pr - -// pro : http://registry.pro/get-pro -pro -aaa.pro -aca.pro -acct.pro -avocat.pro -bar.pro -cpa.pro -eng.pro -jur.pro -law.pro -med.pro -recht.pro - -// ps : https://en.wikipedia.org/wiki/.ps -// http://www.nic.ps/registration/policy.html#reg -ps -edu.ps -gov.ps -sec.ps -plo.ps -com.ps -org.ps -net.ps - -// pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ -pt -net.pt -gov.pt -org.pt -edu.pt -int.pt -publ.pt -com.pt -nome.pt - -// pw : https://en.wikipedia.org/wiki/.pw -pw -co.pw -ne.pw -or.pw -ed.pw -go.pw -belau.pw - -// py : http://www.nic.py/pautas.html#seccion_9 -// Submitted by registry -py -com.py -coop.py -edu.py -gov.py -mil.py -net.py -org.py - -// qa : http://domains.qa/en/ -qa -com.qa -edu.qa -gov.qa -mil.qa -name.qa -net.qa -org.qa -sch.qa - -// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -re -asso.re -com.re -nom.re - -// ro : http://www.rotld.ro/ -ro -arts.ro -com.ro -firm.ro -info.ro -nom.ro -nt.ro -org.ro -rec.ro -store.ro -tm.ro -www.ro - -// rs : https://www.rnids.rs/en/domains/national-domains -rs -ac.rs -co.rs -edu.rs -gov.rs -in.rs -org.rs - -// ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf -// Submitted by George Georgievsky -ru - -// rw : https://www.ricta.org.rw/sites/default/files/resources/registry_registrar_contract_0.pdf -rw -ac.rw -co.rw -coop.rw -gov.rw -mil.rw -net.rw -org.rw - -// sa : http://www.nic.net.sa/ -sa -com.sa -net.sa -org.sa -gov.sa -med.sa -pub.sa -edu.sa -sch.sa - -// sb : http://www.sbnic.net.sb/ -// Submitted by registry -sb -com.sb -edu.sb -gov.sb -net.sb -org.sb - -// sc : http://www.nic.sc/ -sc -com.sc -gov.sc -net.sc -org.sc -edu.sc - -// sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm -// Submitted by registry -sd -com.sd -net.sd -org.sd -edu.sd -med.sd -tv.sd -gov.sd -info.sd - -// se : https://en.wikipedia.org/wiki/.se -// Submitted by registry -se -a.se -ac.se -b.se -bd.se -brand.se -c.se -d.se -e.se -f.se -fh.se -fhsk.se -fhv.se -g.se -h.se -i.se -k.se -komforb.se -kommunalforbund.se -komvux.se -l.se -lanbib.se -m.se -n.se -naturbruksgymn.se -o.se -org.se -p.se -parti.se -pp.se -press.se -r.se -s.se -t.se -tm.se -u.se -w.se -x.se -y.se -z.se - -// sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines -sg -com.sg -net.sg -org.sg -gov.sg -edu.sg -per.sg - -// sh : http://nic.sh/rules.htm -sh -com.sh -net.sh -gov.sh -org.sh -mil.sh - -// si : https://en.wikipedia.org/wiki/.si -si - -// sj : No registrations at this time. -// Submitted by registry -sj - -// sk : https://en.wikipedia.org/wiki/.sk -// list of 2nd level domains ? -sk - -// sl : http://www.nic.sl -// Submitted by registry -sl -com.sl -net.sl -edu.sl -gov.sl -org.sl - -// sm : https://en.wikipedia.org/wiki/.sm -sm - -// sn : https://en.wikipedia.org/wiki/.sn -sn -art.sn -com.sn -edu.sn -gouv.sn -org.sn -perso.sn -univ.sn - -// so : http://sonic.so/policies/ -so -com.so -edu.so -gov.so -me.so -net.so -org.so - -// sr : https://en.wikipedia.org/wiki/.sr -sr - -// ss : https://registry.nic.ss/ -// Submitted by registry -ss -biz.ss -com.ss -edu.ss -gov.ss -me.ss -net.ss -org.ss -sch.ss - -// st : http://www.nic.st/html/policyrules/ -st -co.st -com.st -consulado.st -edu.st -embaixada.st -mil.st -net.st -org.st -principe.st -saotome.st -store.st - -// su : https://en.wikipedia.org/wiki/.su -su - -// sv : http://www.svnet.org.sv/niveldos.pdf -sv -com.sv -edu.sv -gob.sv -org.sv -red.sv - -// sx : https://en.wikipedia.org/wiki/.sx -// Submitted by registry -sx -gov.sx - -// sy : https://en.wikipedia.org/wiki/.sy -// see also: http://www.gobin.info/domainname/sy.doc -sy -edu.sy -gov.sy -net.sy -mil.sy -com.sy -org.sy - -// sz : https://en.wikipedia.org/wiki/.sz -// http://www.sispa.org.sz/ -sz -co.sz -ac.sz -org.sz - -// tc : https://en.wikipedia.org/wiki/.tc -tc - -// td : https://en.wikipedia.org/wiki/.td -td - -// tel: https://en.wikipedia.org/wiki/.tel -// http://www.telnic.org/ -tel - -// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -tf - -// tg : https://en.wikipedia.org/wiki/.tg -// http://www.nic.tg/ -tg - -// th : https://en.wikipedia.org/wiki/.th -// Submitted by registry -th -ac.th -co.th -go.th -in.th -mi.th -net.th -or.th - -// tj : http://www.nic.tj/policy.html -tj -ac.tj -biz.tj -co.tj -com.tj -edu.tj -go.tj -gov.tj -int.tj -mil.tj -name.tj -net.tj -nic.tj -org.tj -test.tj -web.tj - -// tk : https://en.wikipedia.org/wiki/.tk -tk - -// tl : https://en.wikipedia.org/wiki/.tl -tl -gov.tl - -// tm : http://www.nic.tm/local.html -tm -com.tm -co.tm -org.tm -net.tm -nom.tm -gov.tm -mil.tm -edu.tm - -// tn : http://www.registre.tn/fr/ -// https://whois.ati.tn/ -tn -com.tn -ens.tn -fin.tn -gov.tn -ind.tn -info.tn -intl.tn -mincom.tn -nat.tn -net.tn -org.tn -perso.tn -tourism.tn - -// to : https://en.wikipedia.org/wiki/.to -// Submitted by registry -to -com.to -gov.to -net.to -org.to -edu.to -mil.to - -// tr : https://nic.tr/ -// https://nic.tr/forms/eng/policies.pdf -// https://nic.tr/index.php?USRACTN=PRICELST -tr -av.tr -bbs.tr -bel.tr -biz.tr -com.tr -dr.tr -edu.tr -gen.tr -gov.tr -info.tr -mil.tr -k12.tr -kep.tr -name.tr -net.tr -org.tr -pol.tr -tel.tr -tsk.tr -tv.tr -web.tr -// Used by Northern Cyprus -nc.tr -// Used by government agencies of Northern Cyprus -gov.nc.tr - -// tt : http://www.nic.tt/ -tt -co.tt -com.tt -org.tt -net.tt -biz.tt -info.tt -pro.tt -int.tt -coop.tt -jobs.tt -mobi.tt -travel.tt -museum.tt -aero.tt -name.tt -gov.tt -edu.tt - -// tv : https://en.wikipedia.org/wiki/.tv -// Not listing any 2LDs as reserved since none seem to exist in practice, -// Wikipedia notwithstanding. -tv - -// tw : https://en.wikipedia.org/wiki/.tw -tw -edu.tw -gov.tw -mil.tw -com.tw -net.tw -org.tw -idv.tw -game.tw -ebiz.tw -club.tw -網路.tw -組織.tw -商業.tw - -// tz : http://www.tznic.or.tz/index.php/domains -// Submitted by registry -tz -ac.tz -co.tz -go.tz -hotel.tz -info.tz -me.tz -mil.tz -mobi.tz -ne.tz -or.tz -sc.tz -tv.tz - -// ua : https://hostmaster.ua/policy/?ua -// Submitted by registry -ua -// ua 2LD -com.ua -edu.ua -gov.ua -in.ua -net.ua -org.ua -// ua geographic names -// https://hostmaster.ua/2ld/ -cherkassy.ua -cherkasy.ua -chernigov.ua -chernihiv.ua -chernivtsi.ua -chernovtsy.ua -ck.ua -cn.ua -cr.ua -crimea.ua -cv.ua -dn.ua -dnepropetrovsk.ua -dnipropetrovsk.ua -donetsk.ua -dp.ua -if.ua -ivano-frankivsk.ua -kh.ua -kharkiv.ua -kharkov.ua -kherson.ua -khmelnitskiy.ua -khmelnytskyi.ua -kiev.ua -kirovograd.ua -km.ua -kr.ua -kropyvnytskyi.ua -krym.ua -ks.ua -kv.ua -kyiv.ua -lg.ua -lt.ua -lugansk.ua -luhansk.ua -lutsk.ua -lv.ua -lviv.ua -mk.ua -mykolaiv.ua -nikolaev.ua -od.ua -odesa.ua -odessa.ua -pl.ua -poltava.ua -rivne.ua -rovno.ua -rv.ua -sb.ua -sebastopol.ua -sevastopol.ua -sm.ua -sumy.ua -te.ua -ternopil.ua -uz.ua -uzhgorod.ua -uzhhorod.ua -vinnica.ua -vinnytsia.ua -vn.ua -volyn.ua -yalta.ua -zakarpattia.ua -zaporizhzhe.ua -zaporizhzhia.ua -zhitomir.ua -zhytomyr.ua -zp.ua -zt.ua - -// ug : https://www.registry.co.ug/ -ug -co.ug -or.ug -ac.ug -sc.ug -go.ug -ne.ug -com.ug -org.ug - -// uk : https://en.wikipedia.org/wiki/.uk -// Submitted by registry -uk -ac.uk -co.uk -gov.uk -ltd.uk -me.uk -net.uk -nhs.uk -org.uk -plc.uk -police.uk -*.sch.uk - -// us : https://en.wikipedia.org/wiki/.us -us -dni.us -fed.us -isa.us -kids.us -nsn.us -// us geographic names -ak.us -al.us -ar.us -as.us -az.us -ca.us -co.us -ct.us -dc.us -de.us -fl.us -ga.us -gu.us -hi.us -ia.us -id.us -il.us -in.us -ks.us -ky.us -la.us -ma.us -md.us -me.us -mi.us -mn.us -mo.us -ms.us -mt.us -nc.us -nd.us -ne.us -nh.us -nj.us -nm.us -nv.us -ny.us -oh.us -ok.us -or.us -pa.us -pr.us -ri.us -sc.us -sd.us -tn.us -tx.us -ut.us -vi.us -vt.us -va.us -wa.us -wi.us -wv.us -wy.us -// The registrar notes several more specific domains available in each state, -// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat -// haphazard; in some states these domains resolve as addresses, while in others -// only subdomains are available, or even nothing at all. We include the -// most common ones where it's clear that different sites are different -// entities. -k12.ak.us -k12.al.us -k12.ar.us -k12.as.us -k12.az.us -k12.ca.us -k12.co.us -k12.ct.us -k12.dc.us -k12.fl.us -k12.ga.us -k12.gu.us -// k12.hi.us Bug 614565 - Hawaii has a state-wide DOE login -k12.ia.us -k12.id.us -k12.il.us -k12.in.us -k12.ks.us -k12.ky.us -k12.la.us -k12.ma.us -k12.md.us -k12.me.us -k12.mi.us -k12.mn.us -k12.mo.us -k12.ms.us -k12.mt.us -k12.nc.us -// k12.nd.us Bug 1028347 - Removed at request of Travis Rosso -k12.ne.us -k12.nh.us -k12.nj.us -k12.nm.us -k12.nv.us -k12.ny.us -k12.oh.us -k12.ok.us -k12.or.us -k12.pa.us -k12.pr.us -// k12.ri.us Removed at request of Kim Cournoyer -k12.sc.us -// k12.sd.us Bug 934131 - Removed at request of James Booze -k12.tn.us -k12.tx.us -k12.ut.us -k12.vi.us -k12.vt.us -k12.va.us -k12.wa.us -k12.wi.us -// k12.wv.us Bug 947705 - Removed at request of Verne Britton -k12.wy.us -cc.ak.us -cc.al.us -cc.ar.us -cc.as.us -cc.az.us -cc.ca.us -cc.co.us -cc.ct.us -cc.dc.us -cc.de.us -cc.fl.us -cc.ga.us -cc.gu.us -cc.hi.us -cc.ia.us -cc.id.us -cc.il.us -cc.in.us -cc.ks.us -cc.ky.us -cc.la.us -cc.ma.us -cc.md.us -cc.me.us -cc.mi.us -cc.mn.us -cc.mo.us -cc.ms.us -cc.mt.us -cc.nc.us -cc.nd.us -cc.ne.us -cc.nh.us -cc.nj.us -cc.nm.us -cc.nv.us -cc.ny.us -cc.oh.us -cc.ok.us -cc.or.us -cc.pa.us -cc.pr.us -cc.ri.us -cc.sc.us -cc.sd.us -cc.tn.us -cc.tx.us -cc.ut.us -cc.vi.us -cc.vt.us -cc.va.us -cc.wa.us -cc.wi.us -cc.wv.us -cc.wy.us -lib.ak.us -lib.al.us -lib.ar.us -lib.as.us -lib.az.us -lib.ca.us -lib.co.us -lib.ct.us -lib.dc.us -// lib.de.us Issue #243 - Moved to Private section at request of Ed Moore -lib.fl.us -lib.ga.us -lib.gu.us -lib.hi.us -lib.ia.us -lib.id.us -lib.il.us -lib.in.us -lib.ks.us -lib.ky.us -lib.la.us -lib.ma.us -lib.md.us -lib.me.us -lib.mi.us -lib.mn.us -lib.mo.us -lib.ms.us -lib.mt.us -lib.nc.us -lib.nd.us -lib.ne.us -lib.nh.us -lib.nj.us -lib.nm.us -lib.nv.us -lib.ny.us -lib.oh.us -lib.ok.us -lib.or.us -lib.pa.us -lib.pr.us -lib.ri.us -lib.sc.us -lib.sd.us -lib.tn.us -lib.tx.us -lib.ut.us -lib.vi.us -lib.vt.us -lib.va.us -lib.wa.us -lib.wi.us -// lib.wv.us Bug 941670 - Removed at request of Larry W Arnold -lib.wy.us -// k12.ma.us contains school districts in Massachusetts. The 4LDs are -// managed independently except for private (PVT), charter (CHTR) and -// parochial (PAROCH) schools. Those are delegated directly to the -// 5LD operators. -pvt.k12.ma.us -chtr.k12.ma.us -paroch.k12.ma.us -// Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following -// see also: http://domreg.merit.edu -// see also: whois -h whois.domreg.merit.edu help -ann-arbor.mi.us -cog.mi.us -dst.mi.us -eaton.mi.us -gen.mi.us -mus.mi.us -tec.mi.us -washtenaw.mi.us - -// uy : http://www.nic.org.uy/ -uy -com.uy -edu.uy -gub.uy -mil.uy -net.uy -org.uy - -// uz : http://www.reg.uz/ -uz -co.uz -com.uz -net.uz -org.uz - -// va : https://en.wikipedia.org/wiki/.va -va - -// vc : https://en.wikipedia.org/wiki/.vc -// Submitted by registry -vc -com.vc -net.vc -org.vc -gov.vc -mil.vc -edu.vc - -// ve : https://registro.nic.ve/ -// Submitted by registry nic@nic.ve and nicve@conatel.gob.ve -ve -arts.ve -bib.ve -co.ve -com.ve -e12.ve -edu.ve -firm.ve -gob.ve -gov.ve -info.ve -int.ve -mil.ve -net.ve -nom.ve -org.ve -rar.ve -rec.ve -store.ve -tec.ve -web.ve - -// vg : https://en.wikipedia.org/wiki/.vg -vg - -// vi : http://www.nic.vi/newdomainform.htm -// http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other -// TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they -// are available for registration (which they do not seem to be). -vi -co.vi -com.vi -k12.vi -net.vi -org.vi - -// vn : https://www.vnnic.vn/en/domain/cctld-vn -// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt -vn -ac.vn -ai.vn -biz.vn -com.vn -edu.vn -gov.vn -health.vn -id.vn -info.vn -int.vn -io.vn -name.vn -net.vn -org.vn -pro.vn - -// vn geographical names -angiang.vn -bacgiang.vn -backan.vn -baclieu.vn -bacninh.vn -baria-vungtau.vn -bentre.vn -binhdinh.vn -binhduong.vn -binhphuoc.vn -binhthuan.vn -camau.vn -cantho.vn -caobang.vn -daklak.vn -daknong.vn -danang.vn -dienbien.vn -dongnai.vn -dongthap.vn -gialai.vn -hagiang.vn -haiduong.vn -haiphong.vn -hanam.vn -hanoi.vn -hatinh.vn -haugiang.vn -hoabinh.vn -hungyen.vn -khanhhoa.vn -kiengiang.vn -kontum.vn -laichau.vn -lamdong.vn -langson.vn -laocai.vn -longan.vn -namdinh.vn -nghean.vn -ninhbinh.vn -ninhthuan.vn -phutho.vn -phuyen.vn -quangbinh.vn -quangnam.vn -quangngai.vn -quangninh.vn -quangtri.vn -soctrang.vn -sonla.vn -tayninh.vn -thaibinh.vn -thainguyen.vn -thanhhoa.vn -thanhphohochiminh.vn -thuathienhue.vn -tiengiang.vn -travinh.vn -tuyenquang.vn -vinhlong.vn -vinhphuc.vn -yenbai.vn - -// vu : https://en.wikipedia.org/wiki/.vu -// http://www.vunic.vu/ -vu -com.vu -edu.vu -net.vu -org.vu - -// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -wf - -// ws : https://en.wikipedia.org/wiki/.ws -// http://samoanic.ws/index.dhtml -ws -com.ws -net.ws -org.ws -gov.ws -edu.ws - -// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf -yt - -// IDN ccTLDs -// When submitting patches, please maintain a sort by ISO 3166 ccTLD, then -// U-label, and follow this format: -// // A-Label ("", [, variant info]) : -// // [sponsoring org] -// U-Label - -// xn--mgbaam7a8h ("Emerat", Arabic) : AE -// http://nic.ae/english/arabicdomain/rules.jsp -امارات - -// xn--y9a3aq ("hye", Armenian) : AM -// ISOC AM (operated by .am Registry) -հայ - -// xn--54b7fta0cc ("Bangla", Bangla) : BD -বাংলা - -// xn--90ae ("bg", Bulgarian) : BG -бг - -// xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH -البحرين - -// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY -// Operated by .by registry -бел - -// xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN -// CNNIC -// http://cnnic.cn/html/Dir/2005/10/11/3218.htm -中国 - -// xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN -// CNNIC -// http://cnnic.cn/html/Dir/2005/10/11/3218.htm -中國 - -// xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ -الجزائر - -// xn--wgbh1c ("Egypt/Masr", Arabic) : EG -// http://www.dotmasr.eg/ -مصر - -// xn--e1a4c ("eu", Cyrillic) : EU -// https://eurid.eu -ею - -// xn--qxa6a ("eu", Greek) : EU -// https://eurid.eu -ευ - -// xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR -موريتانيا - -// xn--node ("ge", Georgian Mkhedruli) : GE -გე - -// xn--qxam ("el", Greek) : GR -// Hellenic Ministry of Infrastructure, Transport, and Networks -ελ - -// xn--j6w193g ("Hong Kong", Chinese) : HK -// https://www.hkirc.hk -// Submitted by registry -// https://www.hkirc.hk/content.jsp?id=30#!/34 -香港 -公司.香港 -教育.香港 -政府.香港 -個人.香港 -網絡.香港 -組織.香港 - -// xn--2scrj9c ("Bharat", Kannada) : IN -// India -ಭಾರತ - -// xn--3hcrj9c ("Bharat", Oriya) : IN -// India -ଭାରତ - -// xn--45br5cyl ("Bharatam", Assamese) : IN -// India -ভাৰত - -// xn--h2breg3eve ("Bharatam", Sanskrit) : IN -// India -भारतम् - -// xn--h2brj9c8c ("Bharot", Santali) : IN -// India -भारोत - -// xn--mgbgu82a ("Bharat", Sindhi) : IN -// India -ڀارت - -// xn--rvc1e0am3e ("Bharatam", Malayalam) : IN -// India -ഭാരതം - -// xn--h2brj9c ("Bharat", Devanagari) : IN -// India -भारत - -// xn--mgbbh1a ("Bharat", Kashmiri) : IN -// India -بارت - -// xn--mgbbh1a71e ("Bharat", Arabic) : IN -// India -بھارت - -// xn--fpcrj9c3d ("Bharat", Telugu) : IN -// India -భారత్ - -// xn--gecrj9c ("Bharat", Gujarati) : IN -// India -ભારત - -// xn--s9brj9c ("Bharat", Gurmukhi) : IN -// India -ਭਾਰਤ - -// xn--45brj9c ("Bharat", Bengali) : IN -// India -ভারত - -// xn--xkc2dl3a5ee0h ("India", Tamil) : IN -// India -இந்தியா - -// xn--mgba3a4f16a ("Iran", Persian) : IR -ایران - -// xn--mgba3a4fra ("Iran", Arabic) : IR -ايران - -// xn--mgbtx2b ("Iraq", Arabic) : IQ -// Communications and Media Commission -عراق - -// xn--mgbayh7gpa ("al-Ordon", Arabic) : JO -// National Information Technology Center (NITC) -// Royal Scientific Society, Al-Jubeiha -الاردن - -// xn--3e0b707e ("Republic of Korea", Hangul) : KR -한국 - -// xn--80ao21a ("Kaz", Kazakh) : KZ -қаз - -// xn--q7ce6a ("Lao", Lao) : LA -ລາວ - -// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK -// https://nic.lk -ලංකා - -// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK -// https://nic.lk -இலங்கை - -// xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA -المغرب - -// xn--d1alf ("mkd", Macedonian) : MK -// MARnet -мкд - -// xn--l1acc ("mon", Mongolian) : MN -мон - -// xn--mix891f ("Macao", Chinese, Traditional) : MO -// MONIC / HNET Asia (Registry Operator for .mo) -澳門 - -// xn--mix082f ("Macao", Chinese, Simplified) : MO -澳门 - -// xn--mgbx4cd0ab ("Malaysia", Malay) : MY -مليسيا - -// xn--mgb9awbf ("Oman", Arabic) : OM -عمان - -// xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK -پاکستان - -// xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK -پاكستان - -// xn--ygbi2ammx ("Falasteen", Arabic) : PS -// The Palestinian National Internet Naming Authority (PNINA) -// http://www.pnina.ps -فلسطين - -// xn--90a3ac ("srb", Cyrillic) : RS -// https://www.rnids.rs/en/domains/national-domains -срб -пр.срб -орг.срб -обр.срб -од.срб -упр.срб -ак.срб - -// xn--p1ai ("rf", Russian-Cyrillic) : RU -// https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf -// Submitted by George Georgievsky -рф - -// xn--wgbl6a ("Qatar", Arabic) : QA -// http://www.ict.gov.qa/ -قطر - -// xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA -// http://www.nic.net.sa/ -السعودية - -// xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant) : SA -السعودیة - -// xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA -السعودیۃ - -// xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA -السعوديه - -// xn--mgbpl2fh ("sudan", Arabic) : SD -// Operated by .sd registry -سودان - -// xn--yfro4i67o Singapore ("Singapore", Chinese) : SG -新加坡 - -// xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG -சிங்கப்பூர் - -// xn--ogbpf8fl ("Syria", Arabic) : SY -سورية - -// xn--mgbtf8fl ("Syria", Arabic, variant) : SY -سوريا - -// xn--o3cw4h ("Thai", Thai) : TH -// http://www.thnic.co.th -ไทย -ศึกษา.ไทย -ธุรกิจ.ไทย -รัฐบาล.ไทย -ทหาร.ไทย -เน็ต.ไทย -องค์กร.ไทย - -// xn--pgbs0dh ("Tunisia", Arabic) : TN -// http://nic.tn -تونس - -// xn--kpry57d ("Taiwan", Chinese, Traditional) : TW -// http://www.twnic.net/english/dn/dn_07a.htm -台灣 - -// xn--kprw13d ("Taiwan", Chinese, Simplified) : TW -// http://www.twnic.net/english/dn/dn_07a.htm -台湾 - -// xn--nnx388a ("Taiwan", Chinese, variant) : TW -臺灣 - -// xn--j1amh ("ukr", Cyrillic) : UA -укр - -// xn--mgb2ddes ("AlYemen", Arabic) : YE -اليمن - -// xxx : http://icmregistry.com -xxx - -// ye : http://www.y.net.ye/services/domain_name.htm -ye -com.ye -edu.ye -gov.ye -net.ye -mil.ye -org.ye - -// za : https://www.zadna.org.za/content/page/domain-information/ -ac.za -agric.za -alt.za -co.za -edu.za -gov.za -grondar.za -law.za -mil.za -net.za -ngo.za -nic.za -nis.za -nom.za -org.za -school.za -tm.za -web.za - -// zm : https://zicta.zm/ -// Submitted by registry -zm -ac.zm -biz.zm -co.zm -com.zm -edu.zm -gov.zm -info.zm -mil.zm -net.zm -org.zm -sch.zm - -// zw : https://www.potraz.gov.zw/ -// Confirmed by registry 2017-01-25 -zw -ac.zw -co.zw -gov.zw -mil.zw -org.zw - - -// newGTLDs - -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-28T15:13:37Z -// This list is auto-generated, don't edit it manually. -// aaa : American Automobile Association, Inc. -// https://www.iana.org/domains/root/db/aaa.html -aaa - -// aarp : AARP -// https://www.iana.org/domains/root/db/aarp.html -aarp - -// abb : ABB Ltd -// https://www.iana.org/domains/root/db/abb.html -abb - -// abbott : Abbott Laboratories, Inc. -// https://www.iana.org/domains/root/db/abbott.html -abbott - -// abbvie : AbbVie Inc. -// https://www.iana.org/domains/root/db/abbvie.html -abbvie - -// abc : Disney Enterprises, Inc. -// https://www.iana.org/domains/root/db/abc.html -abc - -// able : Able Inc. -// https://www.iana.org/domains/root/db/able.html -able - -// abogado : Registry Services, LLC -// https://www.iana.org/domains/root/db/abogado.html -abogado - -// abudhabi : Abu Dhabi Systems and Information Centre -// https://www.iana.org/domains/root/db/abudhabi.html -abudhabi - -// academy : Binky Moon, LLC -// https://www.iana.org/domains/root/db/academy.html -academy - -// accenture : Accenture plc -// https://www.iana.org/domains/root/db/accenture.html -accenture - -// accountant : dot Accountant Limited -// https://www.iana.org/domains/root/db/accountant.html -accountant - -// accountants : Binky Moon, LLC -// https://www.iana.org/domains/root/db/accountants.html -accountants - -// aco : ACO Severin Ahlmann GmbH & Co. KG -// https://www.iana.org/domains/root/db/aco.html -aco - -// actor : Dog Beach, LLC -// https://www.iana.org/domains/root/db/actor.html -actor - -// ads : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/ads.html -ads - -// adult : ICM Registry AD LLC -// https://www.iana.org/domains/root/db/adult.html -adult - -// aeg : Aktiebolaget Electrolux -// https://www.iana.org/domains/root/db/aeg.html -aeg - -// aetna : Aetna Life Insurance Company -// https://www.iana.org/domains/root/db/aetna.html -aetna - -// afl : Australian Football League -// https://www.iana.org/domains/root/db/afl.html -afl - -// africa : ZA Central Registry NPC trading as Registry.Africa -// https://www.iana.org/domains/root/db/africa.html -africa - -// agakhan : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/agakhan.html -agakhan - -// agency : Binky Moon, LLC -// https://www.iana.org/domains/root/db/agency.html -agency - -// aig : American International Group, Inc. -// https://www.iana.org/domains/root/db/aig.html -aig - -// airbus : Airbus S.A.S. -// https://www.iana.org/domains/root/db/airbus.html -airbus - -// airforce : Dog Beach, LLC -// https://www.iana.org/domains/root/db/airforce.html -airforce - -// airtel : Bharti Airtel Limited -// https://www.iana.org/domains/root/db/airtel.html -airtel - -// akdn : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/akdn.html -akdn - -// alibaba : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/alibaba.html -alibaba - -// alipay : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/alipay.html -alipay - -// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft -// https://www.iana.org/domains/root/db/allfinanz.html -allfinanz - -// allstate : Allstate Fire and Casualty Insurance Company -// https://www.iana.org/domains/root/db/allstate.html -allstate - -// ally : Ally Financial Inc. -// https://www.iana.org/domains/root/db/ally.html -ally - -// alsace : Region Grand Est -// https://www.iana.org/domains/root/db/alsace.html -alsace - -// alstom : ALSTOM -// https://www.iana.org/domains/root/db/alstom.html -alstom - -// amazon : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/amazon.html -amazon - -// americanexpress : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/americanexpress.html -americanexpress - -// americanfamily : AmFam, Inc. -// https://www.iana.org/domains/root/db/americanfamily.html -americanfamily - -// amex : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/amex.html -amex - -// amfam : AmFam, Inc. -// https://www.iana.org/domains/root/db/amfam.html -amfam - -// amica : Amica Mutual Insurance Company -// https://www.iana.org/domains/root/db/amica.html -amica - -// amsterdam : Gemeente Amsterdam -// https://www.iana.org/domains/root/db/amsterdam.html -amsterdam - -// analytics : Campus IP LLC -// https://www.iana.org/domains/root/db/analytics.html -analytics - -// android : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/android.html -android - -// anquan : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/anquan.html -anquan - -// anz : Australia and New Zealand Banking Group Limited -// https://www.iana.org/domains/root/db/anz.html -anz - -// aol : Oath Inc. -// https://www.iana.org/domains/root/db/aol.html -aol - -// apartments : Binky Moon, LLC -// https://www.iana.org/domains/root/db/apartments.html -apartments - -// app : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/app.html -app - -// apple : Apple Inc. -// https://www.iana.org/domains/root/db/apple.html -apple - -// aquarelle : Aquarelle.com -// https://www.iana.org/domains/root/db/aquarelle.html -aquarelle - -// arab : League of Arab States -// https://www.iana.org/domains/root/db/arab.html -arab - -// aramco : Aramco Services Company -// https://www.iana.org/domains/root/db/aramco.html -aramco - -// archi : Identity Digital Limited -// https://www.iana.org/domains/root/db/archi.html -archi - -// army : Dog Beach, LLC -// https://www.iana.org/domains/root/db/army.html -army - -// art : UK Creative Ideas Limited -// https://www.iana.org/domains/root/db/art.html -art - -// arte : Association Relative à la Télévision Européenne G.E.I.E. -// https://www.iana.org/domains/root/db/arte.html -arte - -// asda : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/asda.html -asda - -// associates : Binky Moon, LLC -// https://www.iana.org/domains/root/db/associates.html -associates - -// athleta : The Gap, Inc. -// https://www.iana.org/domains/root/db/athleta.html -athleta - -// attorney : Dog Beach, LLC -// https://www.iana.org/domains/root/db/attorney.html -attorney - -// auction : Dog Beach, LLC -// https://www.iana.org/domains/root/db/auction.html -auction - -// audi : AUDI Aktiengesellschaft -// https://www.iana.org/domains/root/db/audi.html -audi - -// audible : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/audible.html -audible - -// audio : XYZ.COM LLC -// https://www.iana.org/domains/root/db/audio.html -audio - -// auspost : Australian Postal Corporation -// https://www.iana.org/domains/root/db/auspost.html -auspost - -// author : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/author.html -author - -// auto : XYZ.COM LLC -// https://www.iana.org/domains/root/db/auto.html -auto - -// autos : XYZ.COM LLC -// https://www.iana.org/domains/root/db/autos.html -autos - -// aws : AWS Registry LLC -// https://www.iana.org/domains/root/db/aws.html -aws - -// axa : AXA Group Operations SAS -// https://www.iana.org/domains/root/db/axa.html -axa - -// azure : Microsoft Corporation -// https://www.iana.org/domains/root/db/azure.html -azure - -// baby : XYZ.COM LLC -// https://www.iana.org/domains/root/db/baby.html -baby - -// baidu : Baidu, Inc. -// https://www.iana.org/domains/root/db/baidu.html -baidu - -// banamex : Citigroup Inc. -// https://www.iana.org/domains/root/db/banamex.html -banamex - -// band : Dog Beach, LLC -// https://www.iana.org/domains/root/db/band.html -band - -// bank : fTLD Registry Services LLC -// https://www.iana.org/domains/root/db/bank.html -bank - -// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable -// https://www.iana.org/domains/root/db/bar.html -bar - -// barcelona : Municipi de Barcelona -// https://www.iana.org/domains/root/db/barcelona.html -barcelona - -// barclaycard : Barclays Bank PLC -// https://www.iana.org/domains/root/db/barclaycard.html -barclaycard - -// barclays : Barclays Bank PLC -// https://www.iana.org/domains/root/db/barclays.html -barclays - -// barefoot : Gallo Vineyards, Inc. -// https://www.iana.org/domains/root/db/barefoot.html -barefoot - -// bargains : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bargains.html -bargains - -// baseball : MLB Advanced Media DH, LLC -// https://www.iana.org/domains/root/db/baseball.html -baseball - -// basketball : Fédération Internationale de Basketball (FIBA) -// https://www.iana.org/domains/root/db/basketball.html -basketball - -// bauhaus : Werkhaus GmbH -// https://www.iana.org/domains/root/db/bauhaus.html -bauhaus - -// bayern : Bayern Connect GmbH -// https://www.iana.org/domains/root/db/bayern.html -bayern - -// bbc : British Broadcasting Corporation -// https://www.iana.org/domains/root/db/bbc.html -bbc - -// bbt : BB&T Corporation -// https://www.iana.org/domains/root/db/bbt.html -bbt - -// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. -// https://www.iana.org/domains/root/db/bbva.html -bbva - -// bcg : The Boston Consulting Group, Inc. -// https://www.iana.org/domains/root/db/bcg.html -bcg - -// bcn : Municipi de Barcelona -// https://www.iana.org/domains/root/db/bcn.html -bcn - -// beats : Beats Electronics, LLC -// https://www.iana.org/domains/root/db/beats.html -beats - -// beauty : XYZ.COM LLC -// https://www.iana.org/domains/root/db/beauty.html -beauty - -// beer : Registry Services, LLC -// https://www.iana.org/domains/root/db/beer.html -beer - -// bentley : Bentley Motors Limited -// https://www.iana.org/domains/root/db/bentley.html -bentley - -// berlin : dotBERLIN GmbH & Co. KG -// https://www.iana.org/domains/root/db/berlin.html -berlin - -// best : BestTLD Pty Ltd -// https://www.iana.org/domains/root/db/best.html -best - -// bestbuy : BBY Solutions, Inc. -// https://www.iana.org/domains/root/db/bestbuy.html -bestbuy - -// bet : Identity Digital Limited -// https://www.iana.org/domains/root/db/bet.html -bet - -// bharti : Bharti Enterprises (Holding) Private Limited -// https://www.iana.org/domains/root/db/bharti.html -bharti - -// bible : American Bible Society -// https://www.iana.org/domains/root/db/bible.html -bible - -// bid : dot Bid Limited -// https://www.iana.org/domains/root/db/bid.html -bid - -// bike : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bike.html -bike - -// bing : Microsoft Corporation -// https://www.iana.org/domains/root/db/bing.html -bing - -// bingo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/bingo.html -bingo - -// bio : Identity Digital Limited -// https://www.iana.org/domains/root/db/bio.html -bio - -// black : Identity Digital Limited -// https://www.iana.org/domains/root/db/black.html -black - -// blackfriday : Registry Services, LLC -// https://www.iana.org/domains/root/db/blackfriday.html -blackfriday - -// blockbuster : Dish DBS Corporation -// https://www.iana.org/domains/root/db/blockbuster.html -blockbuster - -// blog : Knock Knock WHOIS There, LLC -// https://www.iana.org/domains/root/db/blog.html -blog - -// bloomberg : Bloomberg IP Holdings LLC -// https://www.iana.org/domains/root/db/bloomberg.html -bloomberg - -// blue : Identity Digital Limited -// https://www.iana.org/domains/root/db/blue.html -blue - -// bms : Bristol-Myers Squibb Company -// https://www.iana.org/domains/root/db/bms.html -bms - -// bmw : Bayerische Motoren Werke Aktiengesellschaft -// https://www.iana.org/domains/root/db/bmw.html -bmw - -// bnpparibas : BNP Paribas -// https://www.iana.org/domains/root/db/bnpparibas.html -bnpparibas - -// boats : XYZ.COM LLC -// https://www.iana.org/domains/root/db/boats.html -boats - -// boehringer : Boehringer Ingelheim International GmbH -// https://www.iana.org/domains/root/db/boehringer.html -boehringer - -// bofa : Bank of America Corporation -// https://www.iana.org/domains/root/db/bofa.html -bofa - -// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br -// https://www.iana.org/domains/root/db/bom.html -bom - -// bond : ShortDot SA -// https://www.iana.org/domains/root/db/bond.html -bond - -// boo : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/boo.html -boo - -// book : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/book.html -book - -// booking : Booking.com B.V. -// https://www.iana.org/domains/root/db/booking.html -booking - -// bosch : Robert Bosch GMBH -// https://www.iana.org/domains/root/db/bosch.html -bosch - -// bostik : Bostik SA -// https://www.iana.org/domains/root/db/bostik.html -bostik - -// boston : Registry Services, LLC -// https://www.iana.org/domains/root/db/boston.html -boston - -// bot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/bot.html -bot - -// boutique : Binky Moon, LLC -// https://www.iana.org/domains/root/db/boutique.html -boutique - -// box : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/box.html -box - -// bradesco : Banco Bradesco S.A. -// https://www.iana.org/domains/root/db/bradesco.html -bradesco - -// bridgestone : Bridgestone Corporation -// https://www.iana.org/domains/root/db/bridgestone.html -bridgestone - -// broadway : Celebrate Broadway, Inc. -// https://www.iana.org/domains/root/db/broadway.html -broadway - -// broker : Dog Beach, LLC -// https://www.iana.org/domains/root/db/broker.html -broker - -// brother : Brother Industries, Ltd. -// https://www.iana.org/domains/root/db/brother.html -brother - -// brussels : DNS.be vzw -// https://www.iana.org/domains/root/db/brussels.html -brussels - -// build : Plan Bee LLC -// https://www.iana.org/domains/root/db/build.html -build - -// builders : Binky Moon, LLC -// https://www.iana.org/domains/root/db/builders.html -builders - -// business : Binky Moon, LLC -// https://www.iana.org/domains/root/db/business.html -business - -// buy : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/buy.html -buy - -// buzz : DOTSTRATEGY CO. -// https://www.iana.org/domains/root/db/buzz.html -buzz - -// bzh : Association www.bzh -// https://www.iana.org/domains/root/db/bzh.html -bzh - -// cab : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cab.html -cab - -// cafe : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cafe.html -cafe - -// cal : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/cal.html -cal - -// call : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/call.html -call - -// calvinklein : PVH gTLD Holdings LLC -// https://www.iana.org/domains/root/db/calvinklein.html -calvinklein - -// cam : Cam Connecting SARL -// https://www.iana.org/domains/root/db/cam.html -cam - -// camera : Binky Moon, LLC -// https://www.iana.org/domains/root/db/camera.html -camera - -// camp : Binky Moon, LLC -// https://www.iana.org/domains/root/db/camp.html -camp - -// canon : Canon Inc. -// https://www.iana.org/domains/root/db/canon.html -canon - -// capetown : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/capetown.html -capetown - -// capital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/capital.html -capital - -// capitalone : Capital One Financial Corporation -// https://www.iana.org/domains/root/db/capitalone.html -capitalone - -// car : XYZ.COM LLC -// https://www.iana.org/domains/root/db/car.html -car - -// caravan : Caravan International, Inc. -// https://www.iana.org/domains/root/db/caravan.html -caravan - -// cards : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cards.html -cards - -// care : Binky Moon, LLC -// https://www.iana.org/domains/root/db/care.html -care - -// career : dotCareer LLC -// https://www.iana.org/domains/root/db/career.html -career - -// careers : Binky Moon, LLC -// https://www.iana.org/domains/root/db/careers.html -careers - -// cars : XYZ.COM LLC -// https://www.iana.org/domains/root/db/cars.html -cars - -// casa : Registry Services, LLC -// https://www.iana.org/domains/root/db/casa.html -casa - -// case : Digity, LLC -// https://www.iana.org/domains/root/db/case.html -case - -// cash : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cash.html -cash - -// casino : Binky Moon, LLC -// https://www.iana.org/domains/root/db/casino.html -casino - -// catering : Binky Moon, LLC -// https://www.iana.org/domains/root/db/catering.html -catering - -// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/catholic.html -catholic - -// cba : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/cba.html -cba - -// cbn : The Christian Broadcasting Network, Inc. -// https://www.iana.org/domains/root/db/cbn.html -cbn - -// cbre : CBRE, Inc. -// https://www.iana.org/domains/root/db/cbre.html -cbre - -// center : Binky Moon, LLC -// https://www.iana.org/domains/root/db/center.html -center - -// ceo : XYZ.COM LLC -// https://www.iana.org/domains/root/db/ceo.html -ceo - -// cern : European Organization for Nuclear Research ("CERN") -// https://www.iana.org/domains/root/db/cern.html -cern - -// cfa : CFA Institute -// https://www.iana.org/domains/root/db/cfa.html -cfa - -// cfd : ShortDot SA -// https://www.iana.org/domains/root/db/cfd.html -cfd - -// chanel : Chanel International B.V. -// https://www.iana.org/domains/root/db/chanel.html -chanel - -// channel : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/channel.html -channel - -// charity : Public Interest Registry -// https://www.iana.org/domains/root/db/charity.html -charity - -// chase : JPMorgan Chase Bank, National Association -// https://www.iana.org/domains/root/db/chase.html -chase - -// chat : Binky Moon, LLC -// https://www.iana.org/domains/root/db/chat.html -chat - -// cheap : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cheap.html -cheap - -// chintai : CHINTAI Corporation -// https://www.iana.org/domains/root/db/chintai.html -chintai - -// christmas : XYZ.COM LLC -// https://www.iana.org/domains/root/db/christmas.html -christmas - -// chrome : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/chrome.html -chrome - -// church : Binky Moon, LLC -// https://www.iana.org/domains/root/db/church.html -church - -// cipriani : Hotel Cipriani Srl -// https://www.iana.org/domains/root/db/cipriani.html -cipriani - -// circle : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/circle.html -circle - -// cisco : Cisco Technology, Inc. -// https://www.iana.org/domains/root/db/cisco.html -cisco - -// citadel : Citadel Domain LLC -// https://www.iana.org/domains/root/db/citadel.html -citadel - -// citi : Citigroup Inc. -// https://www.iana.org/domains/root/db/citi.html -citi - -// citic : CITIC Group Corporation -// https://www.iana.org/domains/root/db/citic.html -citic - -// city : Binky Moon, LLC -// https://www.iana.org/domains/root/db/city.html -city - -// claims : Binky Moon, LLC -// https://www.iana.org/domains/root/db/claims.html -claims - -// cleaning : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cleaning.html -cleaning - -// click : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/click.html -click - -// clinic : Binky Moon, LLC -// https://www.iana.org/domains/root/db/clinic.html -clinic - -// clinique : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/clinique.html -clinique - -// clothing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/clothing.html -clothing - -// cloud : Aruba PEC S.p.A. -// https://www.iana.org/domains/root/db/cloud.html -cloud - -// club : Registry Services, LLC -// https://www.iana.org/domains/root/db/club.html -club - -// clubmed : Club Méditerranée S.A. -// https://www.iana.org/domains/root/db/clubmed.html -clubmed - -// coach : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coach.html -coach - -// codes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/codes.html -codes - -// coffee : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coffee.html -coffee - -// college : XYZ.COM LLC -// https://www.iana.org/domains/root/db/college.html -college - -// cologne : dotKoeln GmbH -// https://www.iana.org/domains/root/db/cologne.html -cologne - -// commbank : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/commbank.html -commbank - -// community : Binky Moon, LLC -// https://www.iana.org/domains/root/db/community.html -community - -// company : Binky Moon, LLC -// https://www.iana.org/domains/root/db/company.html -company - -// compare : Registry Services, LLC -// https://www.iana.org/domains/root/db/compare.html -compare - -// computer : Binky Moon, LLC -// https://www.iana.org/domains/root/db/computer.html -computer - -// comsec : VeriSign, Inc. -// https://www.iana.org/domains/root/db/comsec.html -comsec - -// condos : Binky Moon, LLC -// https://www.iana.org/domains/root/db/condos.html -condos - -// construction : Binky Moon, LLC -// https://www.iana.org/domains/root/db/construction.html -construction - -// consulting : Dog Beach, LLC -// https://www.iana.org/domains/root/db/consulting.html -consulting - -// contact : Dog Beach, LLC -// https://www.iana.org/domains/root/db/contact.html -contact - -// contractors : Binky Moon, LLC -// https://www.iana.org/domains/root/db/contractors.html -contractors - -// cooking : Registry Services, LLC -// https://www.iana.org/domains/root/db/cooking.html -cooking - -// cool : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cool.html -cool - -// corsica : Collectivité de Corse -// https://www.iana.org/domains/root/db/corsica.html -corsica - -// country : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/country.html -country - -// coupon : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/coupon.html -coupon - -// coupons : Binky Moon, LLC -// https://www.iana.org/domains/root/db/coupons.html -coupons - -// courses : Registry Services, LLC -// https://www.iana.org/domains/root/db/courses.html -courses - -// cpa : American Institute of Certified Public Accountants -// https://www.iana.org/domains/root/db/cpa.html -cpa - -// credit : Binky Moon, LLC -// https://www.iana.org/domains/root/db/credit.html -credit - -// creditcard : Binky Moon, LLC -// https://www.iana.org/domains/root/db/creditcard.html -creditcard - -// creditunion : DotCooperation LLC -// https://www.iana.org/domains/root/db/creditunion.html -creditunion - -// cricket : dot Cricket Limited -// https://www.iana.org/domains/root/db/cricket.html -cricket - -// crown : Crown Equipment Corporation -// https://www.iana.org/domains/root/db/crown.html -crown - -// crs : Federated Co-operatives Limited -// https://www.iana.org/domains/root/db/crs.html -crs - -// cruise : Viking River Cruises (Bermuda) Ltd. -// https://www.iana.org/domains/root/db/cruise.html -cruise - -// cruises : Binky Moon, LLC -// https://www.iana.org/domains/root/db/cruises.html -cruises - -// cuisinella : SCHMIDT GROUPE S.A.S. -// https://www.iana.org/domains/root/db/cuisinella.html -cuisinella - -// cymru : Nominet UK -// https://www.iana.org/domains/root/db/cymru.html -cymru - -// cyou : ShortDot SA -// https://www.iana.org/domains/root/db/cyou.html -cyou - -// dabur : Dabur India Limited -// https://www.iana.org/domains/root/db/dabur.html -dabur - -// dad : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dad.html -dad - -// dance : Dog Beach, LLC -// https://www.iana.org/domains/root/db/dance.html -dance - -// data : Dish DBS Corporation -// https://www.iana.org/domains/root/db/data.html -data - -// date : dot Date Limited -// https://www.iana.org/domains/root/db/date.html -date - -// dating : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dating.html -dating - -// datsun : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/datsun.html -datsun - -// day : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/day.html -day - -// dclk : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dclk.html -dclk - -// dds : Registry Services, LLC -// https://www.iana.org/domains/root/db/dds.html -dds - -// deal : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/deal.html -deal - -// dealer : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/dealer.html -dealer - -// deals : Binky Moon, LLC -// https://www.iana.org/domains/root/db/deals.html -deals - -// degree : Dog Beach, LLC -// https://www.iana.org/domains/root/db/degree.html -degree - -// delivery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/delivery.html -delivery - -// dell : Dell Inc. -// https://www.iana.org/domains/root/db/dell.html -dell - -// deloitte : Deloitte Touche Tohmatsu -// https://www.iana.org/domains/root/db/deloitte.html -deloitte - -// delta : Delta Air Lines, Inc. -// https://www.iana.org/domains/root/db/delta.html -delta - -// democrat : Dog Beach, LLC -// https://www.iana.org/domains/root/db/democrat.html -democrat - -// dental : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dental.html -dental - -// dentist : Dog Beach, LLC -// https://www.iana.org/domains/root/db/dentist.html -dentist - -// desi -// https://www.iana.org/domains/root/db/desi.html -desi - -// design : Registry Services, LLC -// https://www.iana.org/domains/root/db/design.html -design - -// dev : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/dev.html -dev - -// dhl : Deutsche Post AG -// https://www.iana.org/domains/root/db/dhl.html -dhl - -// diamonds : Binky Moon, LLC -// https://www.iana.org/domains/root/db/diamonds.html -diamonds - -// diet : XYZ.COM LLC -// https://www.iana.org/domains/root/db/diet.html -diet - -// digital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/digital.html -digital - -// direct : Binky Moon, LLC -// https://www.iana.org/domains/root/db/direct.html -direct - -// directory : Binky Moon, LLC -// https://www.iana.org/domains/root/db/directory.html -directory - -// discount : Binky Moon, LLC -// https://www.iana.org/domains/root/db/discount.html -discount - -// discover : Discover Financial Services -// https://www.iana.org/domains/root/db/discover.html -discover - -// dish : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dish.html -dish - -// diy : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/diy.html -diy - -// dnp : Dai Nippon Printing Co., Ltd. -// https://www.iana.org/domains/root/db/dnp.html -dnp - -// docs : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/docs.html -docs - -// doctor : Binky Moon, LLC -// https://www.iana.org/domains/root/db/doctor.html -doctor - -// dog : Binky Moon, LLC -// https://www.iana.org/domains/root/db/dog.html -dog - -// domains : Binky Moon, LLC -// https://www.iana.org/domains/root/db/domains.html -domains - -// dot : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dot.html -dot - -// download : dot Support Limited -// https://www.iana.org/domains/root/db/download.html -download - -// drive : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/drive.html -drive - -// dtv : Dish DBS Corporation -// https://www.iana.org/domains/root/db/dtv.html -dtv - -// dubai : Dubai Smart Government Department -// https://www.iana.org/domains/root/db/dubai.html -dubai - -// dunlop : The Goodyear Tire & Rubber Company -// https://www.iana.org/domains/root/db/dunlop.html -dunlop - -// dupont : DuPont Specialty Products USA, LLC -// https://www.iana.org/domains/root/db/dupont.html -dupont - -// durban : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/durban.html -durban - -// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/dvag.html -dvag - -// dvr : DISH Technologies L.L.C. -// https://www.iana.org/domains/root/db/dvr.html -dvr - -// earth : Interlink Systems Innovation Institute K.K. -// https://www.iana.org/domains/root/db/earth.html -earth - -// eat : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/eat.html -eat - -// eco : Big Room Inc. -// https://www.iana.org/domains/root/db/eco.html -eco - -// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. -// https://www.iana.org/domains/root/db/edeka.html -edeka - -// education : Binky Moon, LLC -// https://www.iana.org/domains/root/db/education.html -education - -// email : Binky Moon, LLC -// https://www.iana.org/domains/root/db/email.html -email - -// emerck : Merck KGaA -// https://www.iana.org/domains/root/db/emerck.html -emerck - -// energy : Binky Moon, LLC -// https://www.iana.org/domains/root/db/energy.html -energy - -// engineer : Dog Beach, LLC -// https://www.iana.org/domains/root/db/engineer.html -engineer - -// engineering : Binky Moon, LLC -// https://www.iana.org/domains/root/db/engineering.html -engineering - -// enterprises : Binky Moon, LLC -// https://www.iana.org/domains/root/db/enterprises.html -enterprises - -// epson : Seiko Epson Corporation -// https://www.iana.org/domains/root/db/epson.html -epson - -// equipment : Binky Moon, LLC -// https://www.iana.org/domains/root/db/equipment.html -equipment - -// ericsson : Telefonaktiebolaget L M Ericsson -// https://www.iana.org/domains/root/db/ericsson.html -ericsson - -// erni : ERNI Group Holding AG -// https://www.iana.org/domains/root/db/erni.html -erni - -// esq : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/esq.html -esq - -// estate : Binky Moon, LLC -// https://www.iana.org/domains/root/db/estate.html -estate - -// eurovision : European Broadcasting Union (EBU) -// https://www.iana.org/domains/root/db/eurovision.html -eurovision - -// eus : Puntueus Fundazioa -// https://www.iana.org/domains/root/db/eus.html -eus - -// events : Binky Moon, LLC -// https://www.iana.org/domains/root/db/events.html -events - -// exchange : Binky Moon, LLC -// https://www.iana.org/domains/root/db/exchange.html -exchange - -// expert : Binky Moon, LLC -// https://www.iana.org/domains/root/db/expert.html -expert - -// exposed : Binky Moon, LLC -// https://www.iana.org/domains/root/db/exposed.html -exposed - -// express : Binky Moon, LLC -// https://www.iana.org/domains/root/db/express.html -express - -// extraspace : Extra Space Storage LLC -// https://www.iana.org/domains/root/db/extraspace.html -extraspace - -// fage : Fage International S.A. -// https://www.iana.org/domains/root/db/fage.html -fage - -// fail : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fail.html -fail - -// fairwinds : FairWinds Partners, LLC -// https://www.iana.org/domains/root/db/fairwinds.html -fairwinds - -// faith : dot Faith Limited -// https://www.iana.org/domains/root/db/faith.html -faith - -// family : Dog Beach, LLC -// https://www.iana.org/domains/root/db/family.html -family - -// fan : Dog Beach, LLC -// https://www.iana.org/domains/root/db/fan.html -fan - -// fans : ZDNS International Limited -// https://www.iana.org/domains/root/db/fans.html -fans - -// farm : Binky Moon, LLC -// https://www.iana.org/domains/root/db/farm.html -farm - -// farmers : Farmers Insurance Exchange -// https://www.iana.org/domains/root/db/farmers.html -farmers - -// fashion : Registry Services, LLC -// https://www.iana.org/domains/root/db/fashion.html -fashion - -// fast : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/fast.html -fast - -// fedex : Federal Express Corporation -// https://www.iana.org/domains/root/db/fedex.html -fedex - -// feedback : Top Level Spectrum, Inc. -// https://www.iana.org/domains/root/db/feedback.html -feedback - -// ferrari : Fiat Chrysler Automobiles N.V. -// https://www.iana.org/domains/root/db/ferrari.html -ferrari - -// ferrero : Ferrero Trading Lux S.A. -// https://www.iana.org/domains/root/db/ferrero.html -ferrero - -// fidelity : Fidelity Brokerage Services LLC -// https://www.iana.org/domains/root/db/fidelity.html -fidelity - -// fido : Rogers Communications Canada Inc. -// https://www.iana.org/domains/root/db/fido.html -fido - -// film : Motion Picture Domain Registry Pty Ltd -// https://www.iana.org/domains/root/db/film.html -film - -// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br -// https://www.iana.org/domains/root/db/final.html -final - -// finance : Binky Moon, LLC -// https://www.iana.org/domains/root/db/finance.html -finance - -// financial : Binky Moon, LLC -// https://www.iana.org/domains/root/db/financial.html -financial - -// fire : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/fire.html -fire - -// firestone : Bridgestone Licensing Services, Inc -// https://www.iana.org/domains/root/db/firestone.html -firestone - -// firmdale : Firmdale Holdings Limited -// https://www.iana.org/domains/root/db/firmdale.html -firmdale - -// fish : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fish.html -fish - -// fishing : Registry Services, LLC -// https://www.iana.org/domains/root/db/fishing.html -fishing - -// fit : Registry Services, LLC -// https://www.iana.org/domains/root/db/fit.html -fit - -// fitness : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fitness.html -fitness - -// flickr : Flickr, Inc. -// https://www.iana.org/domains/root/db/flickr.html -flickr - -// flights : Binky Moon, LLC -// https://www.iana.org/domains/root/db/flights.html -flights - -// flir : FLIR Systems, Inc. -// https://www.iana.org/domains/root/db/flir.html -flir - -// florist : Binky Moon, LLC -// https://www.iana.org/domains/root/db/florist.html -florist - -// flowers : XYZ.COM LLC -// https://www.iana.org/domains/root/db/flowers.html -flowers - -// fly : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/fly.html -fly - -// foo : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/foo.html -foo - -// food : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/food.html -food - -// football : Binky Moon, LLC -// https://www.iana.org/domains/root/db/football.html -football - -// ford : Ford Motor Company -// https://www.iana.org/domains/root/db/ford.html -ford - -// forex : Dog Beach, LLC -// https://www.iana.org/domains/root/db/forex.html -forex - -// forsale : Dog Beach, LLC -// https://www.iana.org/domains/root/db/forsale.html -forsale - -// forum : Fegistry, LLC -// https://www.iana.org/domains/root/db/forum.html -forum - -// foundation : Public Interest Registry -// https://www.iana.org/domains/root/db/foundation.html -foundation - -// fox : FOX Registry, LLC -// https://www.iana.org/domains/root/db/fox.html -fox - -// free : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/free.html -free - -// fresenius : Fresenius Immobilien-Verwaltungs-GmbH -// https://www.iana.org/domains/root/db/fresenius.html -fresenius - -// frl : FRLregistry B.V. -// https://www.iana.org/domains/root/db/frl.html -frl - -// frogans : OP3FT -// https://www.iana.org/domains/root/db/frogans.html -frogans - -// frontier : Frontier Communications Corporation -// https://www.iana.org/domains/root/db/frontier.html -frontier - -// ftr : Frontier Communications Corporation -// https://www.iana.org/domains/root/db/ftr.html -ftr - -// fujitsu : Fujitsu Limited -// https://www.iana.org/domains/root/db/fujitsu.html -fujitsu - -// fun : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/fun.html -fun - -// fund : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fund.html -fund - -// furniture : Binky Moon, LLC -// https://www.iana.org/domains/root/db/furniture.html -furniture - -// futbol : Dog Beach, LLC -// https://www.iana.org/domains/root/db/futbol.html -futbol - -// fyi : Binky Moon, LLC -// https://www.iana.org/domains/root/db/fyi.html -fyi - -// gal : Asociación puntoGAL -// https://www.iana.org/domains/root/db/gal.html -gal - -// gallery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gallery.html -gallery - -// gallo : Gallo Vineyards, Inc. -// https://www.iana.org/domains/root/db/gallo.html -gallo - -// gallup : Gallup, Inc. -// https://www.iana.org/domains/root/db/gallup.html -gallup - -// game : XYZ.COM LLC -// https://www.iana.org/domains/root/db/game.html -game - -// games : Dog Beach, LLC -// https://www.iana.org/domains/root/db/games.html -games - -// gap : The Gap, Inc. -// https://www.iana.org/domains/root/db/gap.html -gap - -// garden : Registry Services, LLC -// https://www.iana.org/domains/root/db/garden.html -garden - -// gay : Registry Services, LLC -// https://www.iana.org/domains/root/db/gay.html -gay - -// gbiz : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gbiz.html -gbiz - -// gdn : Joint Stock Company "Navigation-information systems" -// https://www.iana.org/domains/root/db/gdn.html -gdn - -// gea : GEA Group Aktiengesellschaft -// https://www.iana.org/domains/root/db/gea.html -gea - -// gent : Easyhost BV -// https://www.iana.org/domains/root/db/gent.html -gent - -// genting : Resorts World Inc Pte. Ltd. -// https://www.iana.org/domains/root/db/genting.html -genting - -// george : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/george.html -george - -// ggee : GMO Internet, Inc. -// https://www.iana.org/domains/root/db/ggee.html -ggee - -// gift : DotGift, LLC -// https://www.iana.org/domains/root/db/gift.html -gift - -// gifts : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gifts.html -gifts - -// gives : Public Interest Registry -// https://www.iana.org/domains/root/db/gives.html -gives - -// giving : Public Interest Registry -// https://www.iana.org/domains/root/db/giving.html -giving - -// glass : Binky Moon, LLC -// https://www.iana.org/domains/root/db/glass.html -glass - -// gle : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gle.html -gle - -// global : Identity Digital Limited -// https://www.iana.org/domains/root/db/global.html -global - -// globo : Globo Comunicação e Participações S.A -// https://www.iana.org/domains/root/db/globo.html -globo - -// gmail : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/gmail.html -gmail - -// gmbh : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gmbh.html -gmbh - -// gmo : GMO Internet, Inc. -// https://www.iana.org/domains/root/db/gmo.html -gmo - -// gmx : 1&1 Mail & Media GmbH -// https://www.iana.org/domains/root/db/gmx.html -gmx - -// godaddy : Go Daddy East, LLC -// https://www.iana.org/domains/root/db/godaddy.html -godaddy - -// gold : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gold.html -gold - -// goldpoint : YODOBASHI CAMERA CO.,LTD. -// https://www.iana.org/domains/root/db/goldpoint.html -goldpoint - -// golf : Binky Moon, LLC -// https://www.iana.org/domains/root/db/golf.html -golf - -// goo : NTT DOCOMO, INC. -// https://www.iana.org/domains/root/db/goo.html -goo - -// goodyear : The Goodyear Tire & Rubber Company -// https://www.iana.org/domains/root/db/goodyear.html -goodyear - -// goog : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/goog.html -goog - -// google : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/google.html -google - -// gop : Republican State Leadership Committee, Inc. -// https://www.iana.org/domains/root/db/gop.html -gop - -// got : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/got.html -got - -// grainger : Grainger Registry Services, LLC -// https://www.iana.org/domains/root/db/grainger.html -grainger - -// graphics : Binky Moon, LLC -// https://www.iana.org/domains/root/db/graphics.html -graphics - -// gratis : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gratis.html -gratis - -// green : Identity Digital Limited -// https://www.iana.org/domains/root/db/green.html -green - -// gripe : Binky Moon, LLC -// https://www.iana.org/domains/root/db/gripe.html -gripe - -// grocery : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/grocery.html -grocery - -// group : Binky Moon, LLC -// https://www.iana.org/domains/root/db/group.html -group - -// gucci : Guccio Gucci S.p.a. -// https://www.iana.org/domains/root/db/gucci.html -gucci - -// guge : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/guge.html -guge - -// guide : Binky Moon, LLC -// https://www.iana.org/domains/root/db/guide.html -guide - -// guitars : XYZ.COM LLC -// https://www.iana.org/domains/root/db/guitars.html -guitars - -// guru : Binky Moon, LLC -// https://www.iana.org/domains/root/db/guru.html -guru - -// hair : XYZ.COM LLC -// https://www.iana.org/domains/root/db/hair.html -hair - -// hamburg : Hamburg Top-Level-Domain GmbH -// https://www.iana.org/domains/root/db/hamburg.html -hamburg - -// hangout : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/hangout.html -hangout - -// haus : Dog Beach, LLC -// https://www.iana.org/domains/root/db/haus.html -haus - -// hbo : HBO Registry Services, Inc. -// https://www.iana.org/domains/root/db/hbo.html -hbo - -// hdfc : HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED -// https://www.iana.org/domains/root/db/hdfc.html -hdfc - -// hdfcbank : HDFC Bank Limited -// https://www.iana.org/domains/root/db/hdfcbank.html -hdfcbank - -// health : Registry Services, LLC -// https://www.iana.org/domains/root/db/health.html -health - -// healthcare : Binky Moon, LLC -// https://www.iana.org/domains/root/db/healthcare.html -healthcare - -// help : Innovation service Limited -// https://www.iana.org/domains/root/db/help.html -help - -// helsinki : City of Helsinki -// https://www.iana.org/domains/root/db/helsinki.html -helsinki - -// here : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/here.html -here - -// hermes : HERMES INTERNATIONAL -// https://www.iana.org/domains/root/db/hermes.html -hermes - -// hiphop : Dot Hip Hop, LLC -// https://www.iana.org/domains/root/db/hiphop.html -hiphop - -// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. -// https://www.iana.org/domains/root/db/hisamitsu.html -hisamitsu - -// hitachi : Hitachi, Ltd. -// https://www.iana.org/domains/root/db/hitachi.html -hitachi - -// hiv : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/hiv.html -hiv - -// hkt : PCCW-HKT DataCom Services Limited -// https://www.iana.org/domains/root/db/hkt.html -hkt - -// hockey : Binky Moon, LLC -// https://www.iana.org/domains/root/db/hockey.html -hockey - -// holdings : Binky Moon, LLC -// https://www.iana.org/domains/root/db/holdings.html -holdings - -// holiday : Binky Moon, LLC -// https://www.iana.org/domains/root/db/holiday.html -holiday - -// homedepot : Home Depot Product Authority, LLC -// https://www.iana.org/domains/root/db/homedepot.html -homedepot - -// homegoods : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/homegoods.html -homegoods - -// homes : XYZ.COM LLC -// https://www.iana.org/domains/root/db/homes.html -homes - -// homesense : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/homesense.html -homesense - -// honda : Honda Motor Co., Ltd. -// https://www.iana.org/domains/root/db/honda.html -honda - -// horse : Registry Services, LLC -// https://www.iana.org/domains/root/db/horse.html -horse - -// hospital : Binky Moon, LLC -// https://www.iana.org/domains/root/db/hospital.html -hospital - -// host : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/host.html -host - -// hosting : XYZ.COM LLC -// https://www.iana.org/domains/root/db/hosting.html -hosting - -// hot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/hot.html -hot - -// hotels : Booking.com B.V. -// https://www.iana.org/domains/root/db/hotels.html -hotels - -// hotmail : Microsoft Corporation -// https://www.iana.org/domains/root/db/hotmail.html -hotmail - -// house : Binky Moon, LLC -// https://www.iana.org/domains/root/db/house.html -house - -// how : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/how.html -how - -// hsbc : HSBC Global Services (UK) Limited -// https://www.iana.org/domains/root/db/hsbc.html -hsbc - -// hughes : Hughes Satellite Systems Corporation -// https://www.iana.org/domains/root/db/hughes.html -hughes - -// hyatt : Hyatt GTLD, L.L.C. -// https://www.iana.org/domains/root/db/hyatt.html -hyatt - -// hyundai : Hyundai Motor Company -// https://www.iana.org/domains/root/db/hyundai.html -hyundai - -// ibm : International Business Machines Corporation -// https://www.iana.org/domains/root/db/ibm.html -ibm - -// icbc : Industrial and Commercial Bank of China Limited -// https://www.iana.org/domains/root/db/icbc.html -icbc - -// ice : IntercontinentalExchange, Inc. -// https://www.iana.org/domains/root/db/ice.html -ice - -// icu : ShortDot SA -// https://www.iana.org/domains/root/db/icu.html -icu - -// ieee : IEEE Global LLC -// https://www.iana.org/domains/root/db/ieee.html -ieee - -// ifm : ifm electronic gmbh -// https://www.iana.org/domains/root/db/ifm.html -ifm - -// ikano : Ikano S.A. -// https://www.iana.org/domains/root/db/ikano.html -ikano - -// imamat : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/imamat.html -imamat - -// imdb : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/imdb.html -imdb - -// immo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/immo.html -immo - -// immobilien : Dog Beach, LLC -// https://www.iana.org/domains/root/db/immobilien.html -immobilien - -// inc : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/inc.html -inc - -// industries : Binky Moon, LLC -// https://www.iana.org/domains/root/db/industries.html -industries - -// infiniti : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/infiniti.html -infiniti - -// ing : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/ing.html -ing - -// ink : Registry Services, LLC -// https://www.iana.org/domains/root/db/ink.html -ink - -// institute : Binky Moon, LLC -// https://www.iana.org/domains/root/db/institute.html -institute - -// insurance : fTLD Registry Services LLC -// https://www.iana.org/domains/root/db/insurance.html -insurance - -// insure : Binky Moon, LLC -// https://www.iana.org/domains/root/db/insure.html -insure - -// international : Binky Moon, LLC -// https://www.iana.org/domains/root/db/international.html -international - -// intuit : Intuit Administrative Services, Inc. -// https://www.iana.org/domains/root/db/intuit.html -intuit - -// investments : Binky Moon, LLC -// https://www.iana.org/domains/root/db/investments.html -investments - -// ipiranga : Ipiranga Produtos de Petroleo S.A. -// https://www.iana.org/domains/root/db/ipiranga.html -ipiranga - -// irish : Binky Moon, LLC -// https://www.iana.org/domains/root/db/irish.html -irish - -// ismaili : Fondation Aga Khan (Aga Khan Foundation) -// https://www.iana.org/domains/root/db/ismaili.html -ismaili - -// ist : Istanbul Metropolitan Municipality -// https://www.iana.org/domains/root/db/ist.html -ist - -// istanbul : Istanbul Metropolitan Municipality -// https://www.iana.org/domains/root/db/istanbul.html -istanbul - -// itau : Itau Unibanco Holding S.A. -// https://www.iana.org/domains/root/db/itau.html -itau - -// itv : ITV Services Limited -// https://www.iana.org/domains/root/db/itv.html -itv - -// jaguar : Jaguar Land Rover Ltd -// https://www.iana.org/domains/root/db/jaguar.html -jaguar - -// java : Oracle Corporation -// https://www.iana.org/domains/root/db/java.html -java - -// jcb : JCB Co., Ltd. -// https://www.iana.org/domains/root/db/jcb.html -jcb - -// jeep : FCA US LLC. -// https://www.iana.org/domains/root/db/jeep.html -jeep - -// jetzt : Binky Moon, LLC -// https://www.iana.org/domains/root/db/jetzt.html -jetzt - -// jewelry : Binky Moon, LLC -// https://www.iana.org/domains/root/db/jewelry.html -jewelry - -// jio : Reliance Industries Limited -// https://www.iana.org/domains/root/db/jio.html -jio - -// jll : Jones Lang LaSalle Incorporated -// https://www.iana.org/domains/root/db/jll.html -jll - -// jmp : Matrix IP LLC -// https://www.iana.org/domains/root/db/jmp.html -jmp - -// jnj : Johnson & Johnson Services, Inc. -// https://www.iana.org/domains/root/db/jnj.html -jnj - -// joburg : ZA Central Registry NPC trading as ZA Central Registry -// https://www.iana.org/domains/root/db/joburg.html -joburg - -// jot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/jot.html -jot - -// joy : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/joy.html -joy - -// jpmorgan : JPMorgan Chase Bank, National Association -// https://www.iana.org/domains/root/db/jpmorgan.html -jpmorgan - -// jprs : Japan Registry Services Co., Ltd. -// https://www.iana.org/domains/root/db/jprs.html -jprs - -// juegos : Dog Beach, LLC -// https://www.iana.org/domains/root/db/juegos.html -juegos - -// juniper : JUNIPER NETWORKS, INC. -// https://www.iana.org/domains/root/db/juniper.html -juniper - -// kaufen : Dog Beach, LLC -// https://www.iana.org/domains/root/db/kaufen.html -kaufen - -// kddi : KDDI CORPORATION -// https://www.iana.org/domains/root/db/kddi.html -kddi - -// kerryhotels : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kerryhotels.html -kerryhotels - -// kerrylogistics : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kerrylogistics.html -kerrylogistics - -// kerryproperties : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kerryproperties.html -kerryproperties - -// kfh : Kuwait Finance House -// https://www.iana.org/domains/root/db/kfh.html -kfh - -// kia : KIA MOTORS CORPORATION -// https://www.iana.org/domains/root/db/kia.html -kia - -// kids : DotKids Foundation Limited -// https://www.iana.org/domains/root/db/kids.html -kids - -// kim : Identity Digital Limited -// https://www.iana.org/domains/root/db/kim.html -kim - -// kindle : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/kindle.html -kindle - -// kitchen : Binky Moon, LLC -// https://www.iana.org/domains/root/db/kitchen.html -kitchen - -// kiwi : DOT KIWI LIMITED -// https://www.iana.org/domains/root/db/kiwi.html -kiwi - -// koeln : dotKoeln GmbH -// https://www.iana.org/domains/root/db/koeln.html -koeln - -// komatsu : Komatsu Ltd. -// https://www.iana.org/domains/root/db/komatsu.html -komatsu - -// kosher : Kosher Marketing Assets LLC -// https://www.iana.org/domains/root/db/kosher.html -kosher - -// kpmg : KPMG International Cooperative (KPMG International Genossenschaft) -// https://www.iana.org/domains/root/db/kpmg.html -kpmg - -// kpn : Koninklijke KPN N.V. -// https://www.iana.org/domains/root/db/kpn.html -kpn - -// krd : KRG Department of Information Technology -// https://www.iana.org/domains/root/db/krd.html -krd - -// kred : KredTLD Pty Ltd -// https://www.iana.org/domains/root/db/kred.html -kred - -// kuokgroup : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/kuokgroup.html -kuokgroup - -// kyoto : Academic Institution: Kyoto Jyoho Gakuen -// https://www.iana.org/domains/root/db/kyoto.html -kyoto - -// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” -// https://www.iana.org/domains/root/db/lacaixa.html -lacaixa - -// lamborghini : Automobili Lamborghini S.p.A. -// https://www.iana.org/domains/root/db/lamborghini.html -lamborghini - -// lamer : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/lamer.html -lamer - -// lancaster : LANCASTER -// https://www.iana.org/domains/root/db/lancaster.html -lancaster - -// land : Binky Moon, LLC -// https://www.iana.org/domains/root/db/land.html -land - -// landrover : Jaguar Land Rover Ltd -// https://www.iana.org/domains/root/db/landrover.html -landrover - -// lanxess : LANXESS Corporation -// https://www.iana.org/domains/root/db/lanxess.html -lanxess - -// lasalle : Jones Lang LaSalle Incorporated -// https://www.iana.org/domains/root/db/lasalle.html -lasalle - -// lat : XYZ.COM LLC -// https://www.iana.org/domains/root/db/lat.html -lat - -// latino : Dish DBS Corporation -// https://www.iana.org/domains/root/db/latino.html -latino - -// latrobe : La Trobe University -// https://www.iana.org/domains/root/db/latrobe.html -latrobe - -// law : Registry Services, LLC -// https://www.iana.org/domains/root/db/law.html -law - -// lawyer : Dog Beach, LLC -// https://www.iana.org/domains/root/db/lawyer.html -lawyer - -// lds : IRI Domain Management, LLC -// https://www.iana.org/domains/root/db/lds.html -lds - -// lease : Binky Moon, LLC -// https://www.iana.org/domains/root/db/lease.html -lease - -// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc -// https://www.iana.org/domains/root/db/leclerc.html -leclerc - -// lefrak : LeFrak Organization, Inc. -// https://www.iana.org/domains/root/db/lefrak.html -lefrak - -// legal : Binky Moon, LLC -// https://www.iana.org/domains/root/db/legal.html -legal - -// lego : LEGO Juris A/S -// https://www.iana.org/domains/root/db/lego.html -lego - -// lexus : TOYOTA MOTOR CORPORATION -// https://www.iana.org/domains/root/db/lexus.html -lexus - -// lgbt : Identity Digital Limited -// https://www.iana.org/domains/root/db/lgbt.html -lgbt - -// lidl : Schwarz Domains und Services GmbH & Co. KG -// https://www.iana.org/domains/root/db/lidl.html -lidl - -// life : Binky Moon, LLC -// https://www.iana.org/domains/root/db/life.html -life - -// lifeinsurance : American Council of Life Insurers -// https://www.iana.org/domains/root/db/lifeinsurance.html -lifeinsurance - -// lifestyle : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/lifestyle.html -lifestyle - -// lighting : Binky Moon, LLC -// https://www.iana.org/domains/root/db/lighting.html -lighting - -// like : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/like.html -like - -// lilly : Eli Lilly and Company -// https://www.iana.org/domains/root/db/lilly.html -lilly - -// limited : Binky Moon, LLC -// https://www.iana.org/domains/root/db/limited.html -limited - -// limo : Binky Moon, LLC -// https://www.iana.org/domains/root/db/limo.html -limo - -// lincoln : Ford Motor Company -// https://www.iana.org/domains/root/db/lincoln.html -lincoln - -// link : Nova Registry Ltd -// https://www.iana.org/domains/root/db/link.html -link - -// lipsy : Lipsy Ltd -// https://www.iana.org/domains/root/db/lipsy.html -lipsy - -// live : Dog Beach, LLC -// https://www.iana.org/domains/root/db/live.html -live - -// living : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/living.html -living - -// llc : Identity Digital Limited -// https://www.iana.org/domains/root/db/llc.html -llc - -// llp : Intercap Registry Inc. -// https://www.iana.org/domains/root/db/llp.html -llp - -// loan : dot Loan Limited -// https://www.iana.org/domains/root/db/loan.html -loan - -// loans : Binky Moon, LLC -// https://www.iana.org/domains/root/db/loans.html -loans - -// locker : Orange Domains LLC -// https://www.iana.org/domains/root/db/locker.html -locker - -// locus : Locus Analytics LLC -// https://www.iana.org/domains/root/db/locus.html -locus - -// lol : XYZ.COM LLC -// https://www.iana.org/domains/root/db/lol.html -lol - -// london : Dot London Domains Limited -// https://www.iana.org/domains/root/db/london.html -london - -// lotte : Lotte Holdings Co., Ltd. -// https://www.iana.org/domains/root/db/lotte.html -lotte - -// lotto : Identity Digital Limited -// https://www.iana.org/domains/root/db/lotto.html -lotto - -// love : Merchant Law Group LLP -// https://www.iana.org/domains/root/db/love.html -love - -// lpl : LPL Holdings, Inc. -// https://www.iana.org/domains/root/db/lpl.html -lpl - -// lplfinancial : LPL Holdings, Inc. -// https://www.iana.org/domains/root/db/lplfinancial.html -lplfinancial - -// ltd : Binky Moon, LLC -// https://www.iana.org/domains/root/db/ltd.html -ltd - -// ltda : InterNetX, Corp -// https://www.iana.org/domains/root/db/ltda.html -ltda - -// lundbeck : H. Lundbeck A/S -// https://www.iana.org/domains/root/db/lundbeck.html -lundbeck - -// luxe : Registry Services, LLC -// https://www.iana.org/domains/root/db/luxe.html -luxe - -// luxury : Luxury Partners, LLC -// https://www.iana.org/domains/root/db/luxury.html -luxury - -// madrid : Comunidad de Madrid -// https://www.iana.org/domains/root/db/madrid.html -madrid - -// maif : Mutuelle Assurance Instituteur France (MAIF) -// https://www.iana.org/domains/root/db/maif.html -maif - -// maison : Binky Moon, LLC -// https://www.iana.org/domains/root/db/maison.html -maison - -// makeup : XYZ.COM LLC -// https://www.iana.org/domains/root/db/makeup.html -makeup - -// man : MAN SE -// https://www.iana.org/domains/root/db/man.html -man - -// management : Binky Moon, LLC -// https://www.iana.org/domains/root/db/management.html -management - -// mango : PUNTO FA S.L. -// https://www.iana.org/domains/root/db/mango.html -mango - -// map : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/map.html -map - -// market : Dog Beach, LLC -// https://www.iana.org/domains/root/db/market.html -market - -// marketing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/marketing.html -marketing - -// markets : Dog Beach, LLC -// https://www.iana.org/domains/root/db/markets.html -markets - -// marriott : Marriott Worldwide Corporation -// https://www.iana.org/domains/root/db/marriott.html -marriott - -// marshalls : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/marshalls.html -marshalls - -// mattel : Mattel Sites, Inc. -// https://www.iana.org/domains/root/db/mattel.html -mattel - -// mba : Binky Moon, LLC -// https://www.iana.org/domains/root/db/mba.html -mba - -// mckinsey : McKinsey Holdings, Inc. -// https://www.iana.org/domains/root/db/mckinsey.html -mckinsey - -// med : Medistry LLC -// https://www.iana.org/domains/root/db/med.html -med - -// media : Binky Moon, LLC -// https://www.iana.org/domains/root/db/media.html -media - -// meet : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/meet.html -meet - -// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation -// https://www.iana.org/domains/root/db/melbourne.html -melbourne - -// meme : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/meme.html -meme - -// memorial : Dog Beach, LLC -// https://www.iana.org/domains/root/db/memorial.html -memorial - -// men : Exclusive Registry Limited -// https://www.iana.org/domains/root/db/men.html -men - -// menu : Dot Menu Registry, LLC -// https://www.iana.org/domains/root/db/menu.html -menu - -// merckmsd : MSD Registry Holdings, Inc. -// https://www.iana.org/domains/root/db/merckmsd.html -merckmsd - -// miami : Registry Services, LLC -// https://www.iana.org/domains/root/db/miami.html -miami - -// microsoft : Microsoft Corporation -// https://www.iana.org/domains/root/db/microsoft.html -microsoft - -// mini : Bayerische Motoren Werke Aktiengesellschaft -// https://www.iana.org/domains/root/db/mini.html -mini - -// mint : Intuit Administrative Services, Inc. -// https://www.iana.org/domains/root/db/mint.html -mint - -// mit : Massachusetts Institute of Technology -// https://www.iana.org/domains/root/db/mit.html -mit - -// mitsubishi : Mitsubishi Corporation -// https://www.iana.org/domains/root/db/mitsubishi.html -mitsubishi - -// mlb : MLB Advanced Media DH, LLC -// https://www.iana.org/domains/root/db/mlb.html -mlb - -// mls : The Canadian Real Estate Association -// https://www.iana.org/domains/root/db/mls.html -mls - -// mma : MMA IARD -// https://www.iana.org/domains/root/db/mma.html -mma - -// mobile : Dish DBS Corporation -// https://www.iana.org/domains/root/db/mobile.html -mobile - -// moda : Dog Beach, LLC -// https://www.iana.org/domains/root/db/moda.html -moda - -// moe : Interlink Systems Innovation Institute K.K. -// https://www.iana.org/domains/root/db/moe.html -moe - -// moi : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/moi.html -moi - -// mom : XYZ.COM LLC -// https://www.iana.org/domains/root/db/mom.html -mom - -// monash : Monash University -// https://www.iana.org/domains/root/db/monash.html -monash - -// money : Binky Moon, LLC -// https://www.iana.org/domains/root/db/money.html -money - -// monster : XYZ.COM LLC -// https://www.iana.org/domains/root/db/monster.html -monster - -// mormon : IRI Domain Management, LLC -// https://www.iana.org/domains/root/db/mormon.html -mormon - -// mortgage : Dog Beach, LLC -// https://www.iana.org/domains/root/db/mortgage.html -mortgage - -// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) -// https://www.iana.org/domains/root/db/moscow.html -moscow - -// moto : Motorola Trademark Holdings, LLC -// https://www.iana.org/domains/root/db/moto.html -moto - -// motorcycles : XYZ.COM LLC -// https://www.iana.org/domains/root/db/motorcycles.html -motorcycles - -// mov : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/mov.html -mov - -// movie : Binky Moon, LLC -// https://www.iana.org/domains/root/db/movie.html -movie - -// msd : MSD Registry Holdings, Inc. -// https://www.iana.org/domains/root/db/msd.html -msd - -// mtn : MTN Dubai Limited -// https://www.iana.org/domains/root/db/mtn.html -mtn - -// mtr : MTR Corporation Limited -// https://www.iana.org/domains/root/db/mtr.html -mtr - -// music : DotMusic Limited -// https://www.iana.org/domains/root/db/music.html -music - -// nab : National Australia Bank Limited -// https://www.iana.org/domains/root/db/nab.html -nab - -// nagoya : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/nagoya.html -nagoya - -// natura : NATURA COSMÉTICOS S.A. -// https://www.iana.org/domains/root/db/natura.html -natura - -// navy : Dog Beach, LLC -// https://www.iana.org/domains/root/db/navy.html -navy - -// nba : NBA REGISTRY, LLC -// https://www.iana.org/domains/root/db/nba.html -nba - -// nec : NEC Corporation -// https://www.iana.org/domains/root/db/nec.html -nec - -// netbank : COMMONWEALTH BANK OF AUSTRALIA -// https://www.iana.org/domains/root/db/netbank.html -netbank - -// netflix : Netflix, Inc. -// https://www.iana.org/domains/root/db/netflix.html -netflix - -// network : Binky Moon, LLC -// https://www.iana.org/domains/root/db/network.html -network - -// neustar : NeuStar, Inc. -// https://www.iana.org/domains/root/db/neustar.html -neustar - -// new : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/new.html -new - -// news : Dog Beach, LLC -// https://www.iana.org/domains/root/db/news.html -news - -// next : Next plc -// https://www.iana.org/domains/root/db/next.html -next - -// nextdirect : Next plc -// https://www.iana.org/domains/root/db/nextdirect.html -nextdirect - -// nexus : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/nexus.html -nexus - -// nfl : NFL Reg Ops LLC -// https://www.iana.org/domains/root/db/nfl.html -nfl - -// ngo : Public Interest Registry -// https://www.iana.org/domains/root/db/ngo.html -ngo - -// nhk : Japan Broadcasting Corporation (NHK) -// https://www.iana.org/domains/root/db/nhk.html -nhk - -// nico : DWANGO Co., Ltd. -// https://www.iana.org/domains/root/db/nico.html -nico - -// nike : NIKE, Inc. -// https://www.iana.org/domains/root/db/nike.html -nike - -// nikon : NIKON CORPORATION -// https://www.iana.org/domains/root/db/nikon.html -nikon - -// ninja : Dog Beach, LLC -// https://www.iana.org/domains/root/db/ninja.html -ninja - -// nissan : NISSAN MOTOR CO., LTD. -// https://www.iana.org/domains/root/db/nissan.html -nissan - -// nissay : Nippon Life Insurance Company -// https://www.iana.org/domains/root/db/nissay.html -nissay - -// nokia : Nokia Corporation -// https://www.iana.org/domains/root/db/nokia.html -nokia - -// norton : NortonLifeLock Inc. -// https://www.iana.org/domains/root/db/norton.html -norton - -// now : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/now.html -now - -// nowruz : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. -// https://www.iana.org/domains/root/db/nowruz.html -nowruz - -// nowtv : Starbucks (HK) Limited -// https://www.iana.org/domains/root/db/nowtv.html -nowtv - -// nra : NRA Holdings Company, INC. -// https://www.iana.org/domains/root/db/nra.html -nra - -// nrw : Minds + Machines GmbH -// https://www.iana.org/domains/root/db/nrw.html -nrw - -// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION -// https://www.iana.org/domains/root/db/ntt.html -ntt - -// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications -// https://www.iana.org/domains/root/db/nyc.html -nyc - -// obi : OBI Group Holding SE & Co. KGaA -// https://www.iana.org/domains/root/db/obi.html -obi - -// observer : Fegistry, LLC -// https://www.iana.org/domains/root/db/observer.html -observer - -// office : Microsoft Corporation -// https://www.iana.org/domains/root/db/office.html -office - -// okinawa : BRregistry, Inc. -// https://www.iana.org/domains/root/db/okinawa.html -okinawa - -// olayan : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/olayan.html -olayan - -// olayangroup : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/olayangroup.html -olayangroup - -// ollo : Dish DBS Corporation -// https://www.iana.org/domains/root/db/ollo.html -ollo - -// omega : The Swatch Group Ltd -// https://www.iana.org/domains/root/db/omega.html -omega - -// one : One.com A/S -// https://www.iana.org/domains/root/db/one.html -one - -// ong : Public Interest Registry -// https://www.iana.org/domains/root/db/ong.html -ong - -// onl : iRegistry GmbH -// https://www.iana.org/domains/root/db/onl.html -onl - -// online : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/online.html -online - -// ooo : INFIBEAM AVENUES LIMITED -// https://www.iana.org/domains/root/db/ooo.html -ooo - -// open : American Express Travel Related Services Company, Inc. -// https://www.iana.org/domains/root/db/open.html -open - -// oracle : Oracle Corporation -// https://www.iana.org/domains/root/db/oracle.html -oracle - -// orange : Orange Brand Services Limited -// https://www.iana.org/domains/root/db/orange.html -orange - -// organic : Identity Digital Limited -// https://www.iana.org/domains/root/db/organic.html -organic - -// origins : The Estée Lauder Companies Inc. -// https://www.iana.org/domains/root/db/origins.html -origins - -// osaka : Osaka Registry Co., Ltd. -// https://www.iana.org/domains/root/db/osaka.html -osaka - -// otsuka : Otsuka Holdings Co., Ltd. -// https://www.iana.org/domains/root/db/otsuka.html -otsuka - -// ott : Dish DBS Corporation -// https://www.iana.org/domains/root/db/ott.html -ott - -// ovh : MédiaBC -// https://www.iana.org/domains/root/db/ovh.html -ovh - -// page : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/page.html -page - -// panasonic : Panasonic Holdings Corporation -// https://www.iana.org/domains/root/db/panasonic.html -panasonic - -// paris : City of Paris -// https://www.iana.org/domains/root/db/paris.html -paris - -// pars : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. -// https://www.iana.org/domains/root/db/pars.html -pars - -// partners : Binky Moon, LLC -// https://www.iana.org/domains/root/db/partners.html -partners - -// parts : Binky Moon, LLC -// https://www.iana.org/domains/root/db/parts.html -parts - -// party : Blue Sky Registry Limited -// https://www.iana.org/domains/root/db/party.html -party - -// pay : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/pay.html -pay - -// pccw : PCCW Enterprises Limited -// https://www.iana.org/domains/root/db/pccw.html -pccw - -// pet : Identity Digital Limited -// https://www.iana.org/domains/root/db/pet.html -pet - -// pfizer : Pfizer Inc. -// https://www.iana.org/domains/root/db/pfizer.html -pfizer - -// pharmacy : National Association of Boards of Pharmacy -// https://www.iana.org/domains/root/db/pharmacy.html -pharmacy - -// phd : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/phd.html -phd - -// philips : Koninklijke Philips N.V. -// https://www.iana.org/domains/root/db/philips.html -philips - -// phone : Dish DBS Corporation -// https://www.iana.org/domains/root/db/phone.html -phone - -// photo : Registry Services, LLC -// https://www.iana.org/domains/root/db/photo.html -photo - -// photography : Binky Moon, LLC -// https://www.iana.org/domains/root/db/photography.html -photography - -// photos : Binky Moon, LLC -// https://www.iana.org/domains/root/db/photos.html -photos - -// physio : PhysBiz Pty Ltd -// https://www.iana.org/domains/root/db/physio.html -physio - -// pics : XYZ.COM LLC -// https://www.iana.org/domains/root/db/pics.html -pics - -// pictet : Pictet Europe S.A. -// https://www.iana.org/domains/root/db/pictet.html -pictet - -// pictures : Binky Moon, LLC -// https://www.iana.org/domains/root/db/pictures.html -pictures - -// pid : Top Level Spectrum, Inc. -// https://www.iana.org/domains/root/db/pid.html -pid - -// pin : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/pin.html -pin - -// ping : Ping Registry Provider, Inc. -// https://www.iana.org/domains/root/db/ping.html -ping - -// pink : Identity Digital Limited -// https://www.iana.org/domains/root/db/pink.html -pink - -// pioneer : Pioneer Corporation -// https://www.iana.org/domains/root/db/pioneer.html -pioneer - -// pizza : Binky Moon, LLC -// https://www.iana.org/domains/root/db/pizza.html -pizza - -// place : Binky Moon, LLC -// https://www.iana.org/domains/root/db/place.html -place - -// play : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/play.html -play - -// playstation : Sony Interactive Entertainment Inc. -// https://www.iana.org/domains/root/db/playstation.html -playstation - -// plumbing : Binky Moon, LLC -// https://www.iana.org/domains/root/db/plumbing.html -plumbing - -// plus : Binky Moon, LLC -// https://www.iana.org/domains/root/db/plus.html -plus - -// pnc : PNC Domain Co., LLC -// https://www.iana.org/domains/root/db/pnc.html -pnc - -// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/pohl.html -pohl - -// poker : Identity Digital Limited -// https://www.iana.org/domains/root/db/poker.html -poker - -// politie : Politie Nederland -// https://www.iana.org/domains/root/db/politie.html -politie - -// porn : ICM Registry PN LLC -// https://www.iana.org/domains/root/db/porn.html -porn - -// pramerica : Prudential Financial, Inc. -// https://www.iana.org/domains/root/db/pramerica.html -pramerica - -// praxi : Praxi S.p.A. -// https://www.iana.org/domains/root/db/praxi.html -praxi - -// press : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/press.html -press - -// prime : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/prime.html -prime - -// prod : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/prod.html -prod - -// productions : Binky Moon, LLC -// https://www.iana.org/domains/root/db/productions.html -productions - -// prof : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/prof.html -prof - -// progressive : Progressive Casualty Insurance Company -// https://www.iana.org/domains/root/db/progressive.html -progressive - -// promo : Identity Digital Limited -// https://www.iana.org/domains/root/db/promo.html -promo - -// properties : Binky Moon, LLC -// https://www.iana.org/domains/root/db/properties.html -properties - -// property : Digital Property Infrastructure Limited -// https://www.iana.org/domains/root/db/property.html -property - -// protection : XYZ.COM LLC -// https://www.iana.org/domains/root/db/protection.html -protection - -// pru : Prudential Financial, Inc. -// https://www.iana.org/domains/root/db/pru.html -pru - -// prudential : Prudential Financial, Inc. -// https://www.iana.org/domains/root/db/prudential.html -prudential - -// pub : Dog Beach, LLC -// https://www.iana.org/domains/root/db/pub.html -pub - -// pwc : PricewaterhouseCoopers LLP -// https://www.iana.org/domains/root/db/pwc.html -pwc - -// qpon : dotQPON LLC -// https://www.iana.org/domains/root/db/qpon.html -qpon - -// quebec : PointQuébec Inc -// https://www.iana.org/domains/root/db/quebec.html -quebec - -// quest : XYZ.COM LLC -// https://www.iana.org/domains/root/db/quest.html -quest - -// racing : Premier Registry Limited -// https://www.iana.org/domains/root/db/racing.html -racing - -// radio : European Broadcasting Union (EBU) -// https://www.iana.org/domains/root/db/radio.html -radio - -// read : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/read.html -read - -// realestate : dotRealEstate LLC -// https://www.iana.org/domains/root/db/realestate.html -realestate - -// realtor : Real Estate Domains LLC -// https://www.iana.org/domains/root/db/realtor.html -realtor - -// realty : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/realty.html -realty - -// recipes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/recipes.html -recipes - -// red : Identity Digital Limited -// https://www.iana.org/domains/root/db/red.html -red - -// redstone : Redstone Haute Couture Co., Ltd. -// https://www.iana.org/domains/root/db/redstone.html -redstone - -// redumbrella : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/redumbrella.html -redumbrella - -// rehab : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rehab.html -rehab - -// reise : Binky Moon, LLC -// https://www.iana.org/domains/root/db/reise.html -reise - -// reisen : Binky Moon, LLC -// https://www.iana.org/domains/root/db/reisen.html -reisen - -// reit : National Association of Real Estate Investment Trusts, Inc. -// https://www.iana.org/domains/root/db/reit.html -reit - -// reliance : Reliance Industries Limited -// https://www.iana.org/domains/root/db/reliance.html -reliance - -// ren : ZDNS International Limited -// https://www.iana.org/domains/root/db/ren.html -ren - -// rent : XYZ.COM LLC -// https://www.iana.org/domains/root/db/rent.html -rent - -// rentals : Binky Moon, LLC -// https://www.iana.org/domains/root/db/rentals.html -rentals - -// repair : Binky Moon, LLC -// https://www.iana.org/domains/root/db/repair.html -repair - -// report : Binky Moon, LLC -// https://www.iana.org/domains/root/db/report.html -report - -// republican : Dog Beach, LLC -// https://www.iana.org/domains/root/db/republican.html -republican - -// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable -// https://www.iana.org/domains/root/db/rest.html -rest - -// restaurant : Binky Moon, LLC -// https://www.iana.org/domains/root/db/restaurant.html -restaurant - -// review : dot Review Limited -// https://www.iana.org/domains/root/db/review.html -review - -// reviews : Dog Beach, LLC -// https://www.iana.org/domains/root/db/reviews.html -reviews - -// rexroth : Robert Bosch GMBH -// https://www.iana.org/domains/root/db/rexroth.html -rexroth - -// rich : iRegistry GmbH -// https://www.iana.org/domains/root/db/rich.html -rich - -// richardli : Pacific Century Asset Management (HK) Limited -// https://www.iana.org/domains/root/db/richardli.html -richardli - -// ricoh : Ricoh Company, Ltd. -// https://www.iana.org/domains/root/db/ricoh.html -ricoh - -// ril : Reliance Industries Limited -// https://www.iana.org/domains/root/db/ril.html -ril - -// rio : Empresa Municipal de Informática SA - IPLANRIO -// https://www.iana.org/domains/root/db/rio.html -rio - -// rip : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rip.html -rip - -// rocks : Dog Beach, LLC -// https://www.iana.org/domains/root/db/rocks.html -rocks - -// rodeo : Registry Services, LLC -// https://www.iana.org/domains/root/db/rodeo.html -rodeo - -// rogers : Rogers Communications Canada Inc. -// https://www.iana.org/domains/root/db/rogers.html -rogers - -// room : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/room.html -room - -// rsvp : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/rsvp.html -rsvp - -// rugby : World Rugby Strategic Developments Limited -// https://www.iana.org/domains/root/db/rugby.html -rugby - -// ruhr : dotSaarland GmbH -// https://www.iana.org/domains/root/db/ruhr.html -ruhr - -// run : Binky Moon, LLC -// https://www.iana.org/domains/root/db/run.html -run - -// rwe : RWE AG -// https://www.iana.org/domains/root/db/rwe.html -rwe - -// ryukyu : BRregistry, Inc. -// https://www.iana.org/domains/root/db/ryukyu.html -ryukyu - -// saarland : dotSaarland GmbH -// https://www.iana.org/domains/root/db/saarland.html -saarland - -// safe : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/safe.html -safe - -// safety : Safety Registry Services, LLC. -// https://www.iana.org/domains/root/db/safety.html -safety - -// sakura : SAKURA Internet Inc. -// https://www.iana.org/domains/root/db/sakura.html -sakura - -// sale : Dog Beach, LLC -// https://www.iana.org/domains/root/db/sale.html -sale - -// salon : Binky Moon, LLC -// https://www.iana.org/domains/root/db/salon.html -salon - -// samsclub : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/samsclub.html -samsclub - -// samsung : SAMSUNG SDS CO., LTD -// https://www.iana.org/domains/root/db/samsung.html -samsung - -// sandvik : Sandvik AB -// https://www.iana.org/domains/root/db/sandvik.html -sandvik - -// sandvikcoromant : Sandvik AB -// https://www.iana.org/domains/root/db/sandvikcoromant.html -sandvikcoromant - -// sanofi : Sanofi -// https://www.iana.org/domains/root/db/sanofi.html -sanofi - -// sap : SAP AG -// https://www.iana.org/domains/root/db/sap.html -sap - -// sarl : Binky Moon, LLC -// https://www.iana.org/domains/root/db/sarl.html -sarl - -// sas : Research IP LLC -// https://www.iana.org/domains/root/db/sas.html -sas - -// save : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/save.html -save - -// saxo : Saxo Bank A/S -// https://www.iana.org/domains/root/db/saxo.html -saxo - -// sbi : STATE BANK OF INDIA -// https://www.iana.org/domains/root/db/sbi.html -sbi - -// sbs : ShortDot SA -// https://www.iana.org/domains/root/db/sbs.html -sbs - -// scb : The Siam Commercial Bank Public Company Limited ("SCB") -// https://www.iana.org/domains/root/db/scb.html -scb - -// schaeffler : Schaeffler Technologies AG & Co. KG -// https://www.iana.org/domains/root/db/schaeffler.html -schaeffler - -// schmidt : SCHMIDT GROUPE S.A.S. -// https://www.iana.org/domains/root/db/schmidt.html -schmidt - -// scholarships : Scholarships.com, LLC -// https://www.iana.org/domains/root/db/scholarships.html -scholarships - -// school : Binky Moon, LLC -// https://www.iana.org/domains/root/db/school.html -school - -// schule : Binky Moon, LLC -// https://www.iana.org/domains/root/db/schule.html -schule - -// schwarz : Schwarz Domains und Services GmbH & Co. KG -// https://www.iana.org/domains/root/db/schwarz.html -schwarz - -// science : dot Science Limited -// https://www.iana.org/domains/root/db/science.html -science - -// scot : Dot Scot Registry Limited -// https://www.iana.org/domains/root/db/scot.html -scot - -// search : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/search.html -search - -// seat : SEAT, S.A. (Sociedad Unipersonal) -// https://www.iana.org/domains/root/db/seat.html -seat - -// secure : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/secure.html -secure - -// security : XYZ.COM LLC -// https://www.iana.org/domains/root/db/security.html -security - -// seek : Seek Limited -// https://www.iana.org/domains/root/db/seek.html -seek - -// select : Registry Services, LLC -// https://www.iana.org/domains/root/db/select.html -select - -// sener : Sener Ingeniería y Sistemas, S.A. -// https://www.iana.org/domains/root/db/sener.html -sener - -// services : Binky Moon, LLC -// https://www.iana.org/domains/root/db/services.html -services - -// seven : Seven West Media Ltd -// https://www.iana.org/domains/root/db/seven.html -seven - -// sew : SEW-EURODRIVE GmbH & Co KG -// https://www.iana.org/domains/root/db/sew.html -sew - -// sex : ICM Registry SX LLC -// https://www.iana.org/domains/root/db/sex.html -sex - -// sexy : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/sexy.html -sexy - -// sfr : Societe Francaise du Radiotelephone - SFR -// https://www.iana.org/domains/root/db/sfr.html -sfr - -// shangrila : Shangri‐La International Hotel Management Limited -// https://www.iana.org/domains/root/db/shangrila.html -shangrila - -// sharp : Sharp Corporation -// https://www.iana.org/domains/root/db/sharp.html -sharp - -// shaw : Shaw Cablesystems G.P. -// https://www.iana.org/domains/root/db/shaw.html -shaw - -// shell : Shell Information Technology International Inc -// https://www.iana.org/domains/root/db/shell.html -shell - -// shia : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. -// https://www.iana.org/domains/root/db/shia.html -shia - -// shiksha : Identity Digital Limited -// https://www.iana.org/domains/root/db/shiksha.html -shiksha - -// shoes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/shoes.html -shoes - -// shop : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/shop.html -shop - -// shopping : Binky Moon, LLC -// https://www.iana.org/domains/root/db/shopping.html -shopping - -// shouji : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/shouji.html -shouji - -// show : Binky Moon, LLC -// https://www.iana.org/domains/root/db/show.html -show - -// silk : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/silk.html -silk - -// sina : Sina Corporation -// https://www.iana.org/domains/root/db/sina.html -sina - -// singles : Binky Moon, LLC -// https://www.iana.org/domains/root/db/singles.html -singles - -// site : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/site.html -site - -// ski : Identity Digital Limited -// https://www.iana.org/domains/root/db/ski.html -ski - -// skin : XYZ.COM LLC -// https://www.iana.org/domains/root/db/skin.html -skin - -// sky : Sky International AG -// https://www.iana.org/domains/root/db/sky.html -sky - -// skype : Microsoft Corporation -// https://www.iana.org/domains/root/db/skype.html -skype - -// sling : DISH Technologies L.L.C. -// https://www.iana.org/domains/root/db/sling.html -sling - -// smart : Smart Communications, Inc. (SMART) -// https://www.iana.org/domains/root/db/smart.html -smart - -// smile : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/smile.html -smile - -// sncf : Société Nationale SNCF -// https://www.iana.org/domains/root/db/sncf.html -sncf - -// soccer : Binky Moon, LLC -// https://www.iana.org/domains/root/db/soccer.html -soccer - -// social : Dog Beach, LLC -// https://www.iana.org/domains/root/db/social.html -social - -// softbank : SoftBank Group Corp. -// https://www.iana.org/domains/root/db/softbank.html -softbank - -// software : Dog Beach, LLC -// https://www.iana.org/domains/root/db/software.html -software - -// sohu : Sohu.com Limited -// https://www.iana.org/domains/root/db/sohu.html -sohu - -// solar : Binky Moon, LLC -// https://www.iana.org/domains/root/db/solar.html -solar - -// solutions : Binky Moon, LLC -// https://www.iana.org/domains/root/db/solutions.html -solutions - -// song : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/song.html -song - -// sony : Sony Corporation -// https://www.iana.org/domains/root/db/sony.html -sony - -// soy : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/soy.html -soy - -// spa : Asia Spa and Wellness Promotion Council Limited -// https://www.iana.org/domains/root/db/spa.html -spa - -// space : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/space.html -space - -// sport : SportAccord -// https://www.iana.org/domains/root/db/sport.html -sport - -// spot : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/spot.html -spot - -// srl : InterNetX, Corp -// https://www.iana.org/domains/root/db/srl.html -srl - -// stada : STADA Arzneimittel AG -// https://www.iana.org/domains/root/db/stada.html -stada - -// staples : Staples, Inc. -// https://www.iana.org/domains/root/db/staples.html -staples - -// star : Star India Private Limited -// https://www.iana.org/domains/root/db/star.html -star - -// statebank : STATE BANK OF INDIA -// https://www.iana.org/domains/root/db/statebank.html -statebank - -// statefarm : State Farm Mutual Automobile Insurance Company -// https://www.iana.org/domains/root/db/statefarm.html -statefarm - -// stc : Saudi Telecom Company -// https://www.iana.org/domains/root/db/stc.html -stc - -// stcgroup : Saudi Telecom Company -// https://www.iana.org/domains/root/db/stcgroup.html -stcgroup - -// stockholm : Stockholms kommun -// https://www.iana.org/domains/root/db/stockholm.html -stockholm - -// storage : XYZ.COM LLC -// https://www.iana.org/domains/root/db/storage.html -storage - -// store : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/store.html -store - -// stream : dot Stream Limited -// https://www.iana.org/domains/root/db/stream.html -stream - -// studio : Dog Beach, LLC -// https://www.iana.org/domains/root/db/studio.html -studio - -// study : Registry Services, LLC -// https://www.iana.org/domains/root/db/study.html -study - -// style : Binky Moon, LLC -// https://www.iana.org/domains/root/db/style.html -style - -// sucks : Vox Populi Registry Ltd. -// https://www.iana.org/domains/root/db/sucks.html -sucks - -// supplies : Binky Moon, LLC -// https://www.iana.org/domains/root/db/supplies.html -supplies - -// supply : Binky Moon, LLC -// https://www.iana.org/domains/root/db/supply.html -supply - -// support : Binky Moon, LLC -// https://www.iana.org/domains/root/db/support.html -support - -// surf : Registry Services, LLC -// https://www.iana.org/domains/root/db/surf.html -surf - -// surgery : Binky Moon, LLC -// https://www.iana.org/domains/root/db/surgery.html -surgery - -// suzuki : SUZUKI MOTOR CORPORATION -// https://www.iana.org/domains/root/db/suzuki.html -suzuki - -// swatch : The Swatch Group Ltd -// https://www.iana.org/domains/root/db/swatch.html -swatch - -// swiss : Swiss Confederation -// https://www.iana.org/domains/root/db/swiss.html -swiss - -// sydney : State of New South Wales, Department of Premier and Cabinet -// https://www.iana.org/domains/root/db/sydney.html -sydney - -// systems : Binky Moon, LLC -// https://www.iana.org/domains/root/db/systems.html -systems - -// tab : Tabcorp Holdings Limited -// https://www.iana.org/domains/root/db/tab.html -tab - -// taipei : Taipei City Government -// https://www.iana.org/domains/root/db/taipei.html -taipei - -// talk : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/talk.html -talk - -// taobao : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/taobao.html -taobao - -// target : Target Domain Holdings, LLC -// https://www.iana.org/domains/root/db/target.html -target - -// tatamotors : Tata Motors Ltd -// https://www.iana.org/domains/root/db/tatamotors.html -tatamotors - -// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" -// https://www.iana.org/domains/root/db/tatar.html -tatar - -// tattoo : Registry Services, LLC -// https://www.iana.org/domains/root/db/tattoo.html -tattoo - -// tax : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tax.html -tax - -// taxi : Binky Moon, LLC -// https://www.iana.org/domains/root/db/taxi.html -taxi - -// tci : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. -// https://www.iana.org/domains/root/db/tci.html -tci - -// tdk : TDK Corporation -// https://www.iana.org/domains/root/db/tdk.html -tdk - -// team : Binky Moon, LLC -// https://www.iana.org/domains/root/db/team.html -team - -// tech : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/tech.html -tech - -// technology : Binky Moon, LLC -// https://www.iana.org/domains/root/db/technology.html -technology - -// temasek : Temasek Holdings (Private) Limited -// https://www.iana.org/domains/root/db/temasek.html -temasek - -// tennis : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tennis.html -tennis - -// teva : Teva Pharmaceutical Industries Limited -// https://www.iana.org/domains/root/db/teva.html -teva - -// thd : Home Depot Product Authority, LLC -// https://www.iana.org/domains/root/db/thd.html -thd - -// theater : Binky Moon, LLC -// https://www.iana.org/domains/root/db/theater.html -theater - -// theatre : XYZ.COM LLC -// https://www.iana.org/domains/root/db/theatre.html -theatre - -// tiaa : Teachers Insurance and Annuity Association of America -// https://www.iana.org/domains/root/db/tiaa.html -tiaa - -// tickets : XYZ.COM LLC -// https://www.iana.org/domains/root/db/tickets.html -tickets - -// tienda : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tienda.html -tienda - -// tips : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tips.html -tips - -// tires : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tires.html -tires - -// tirol : punkt Tirol GmbH -// https://www.iana.org/domains/root/db/tirol.html -tirol - -// tjmaxx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tjmaxx.html -tjmaxx - -// tjx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tjx.html -tjx - -// tkmaxx : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/tkmaxx.html -tkmaxx - -// tmall : Alibaba Group Holding Limited -// https://www.iana.org/domains/root/db/tmall.html -tmall - -// today : Binky Moon, LLC -// https://www.iana.org/domains/root/db/today.html -today - -// tokyo : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/tokyo.html -tokyo - -// tools : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tools.html -tools - -// top : .TOP Registry -// https://www.iana.org/domains/root/db/top.html -top - -// toray : Toray Industries, Inc. -// https://www.iana.org/domains/root/db/toray.html -toray - -// toshiba : TOSHIBA Corporation -// https://www.iana.org/domains/root/db/toshiba.html -toshiba - -// total : TotalEnergies SE -// https://www.iana.org/domains/root/db/total.html -total - -// tours : Binky Moon, LLC -// https://www.iana.org/domains/root/db/tours.html -tours - -// town : Binky Moon, LLC -// https://www.iana.org/domains/root/db/town.html -town - -// toyota : TOYOTA MOTOR CORPORATION -// https://www.iana.org/domains/root/db/toyota.html -toyota - -// toys : Binky Moon, LLC -// https://www.iana.org/domains/root/db/toys.html -toys - -// trade : Elite Registry Limited -// https://www.iana.org/domains/root/db/trade.html -trade - -// trading : Dog Beach, LLC -// https://www.iana.org/domains/root/db/trading.html -trading - -// training : Binky Moon, LLC -// https://www.iana.org/domains/root/db/training.html -training - -// travel : Dog Beach, LLC -// https://www.iana.org/domains/root/db/travel.html -travel - -// travelers : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/travelers.html -travelers - -// travelersinsurance : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/travelersinsurance.html -travelersinsurance - -// trust : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/trust.html -trust - -// trv : Travelers TLD, LLC -// https://www.iana.org/domains/root/db/trv.html -trv - -// tube : Latin American Telecom LLC -// https://www.iana.org/domains/root/db/tube.html -tube - -// tui : TUI AG -// https://www.iana.org/domains/root/db/tui.html -tui - -// tunes : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/tunes.html -tunes - -// tushu : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/tushu.html -tushu - -// tvs : T V SUNDRAM IYENGAR & SONS LIMITED -// https://www.iana.org/domains/root/db/tvs.html -tvs - -// ubank : National Australia Bank Limited -// https://www.iana.org/domains/root/db/ubank.html -ubank - -// ubs : UBS AG -// https://www.iana.org/domains/root/db/ubs.html -ubs - -// unicom : China United Network Communications Corporation Limited -// https://www.iana.org/domains/root/db/unicom.html -unicom - -// university : Binky Moon, LLC -// https://www.iana.org/domains/root/db/university.html -university - -// uno : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/uno.html -uno - -// uol : UBN INTERNET LTDA. -// https://www.iana.org/domains/root/db/uol.html -uol - -// ups : UPS Market Driver, Inc. -// https://www.iana.org/domains/root/db/ups.html -ups - -// vacations : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vacations.html -vacations - -// vana : Internet Naming Company LLC -// https://www.iana.org/domains/root/db/vana.html -vana - -// vanguard : The Vanguard Group, Inc. -// https://www.iana.org/domains/root/db/vanguard.html -vanguard - -// vegas : Dot Vegas, Inc. -// https://www.iana.org/domains/root/db/vegas.html -vegas - -// ventures : Binky Moon, LLC -// https://www.iana.org/domains/root/db/ventures.html -ventures - -// verisign : VeriSign, Inc. -// https://www.iana.org/domains/root/db/verisign.html -verisign - -// versicherung : tldbox GmbH -// https://www.iana.org/domains/root/db/versicherung.html -versicherung - -// vet : Dog Beach, LLC -// https://www.iana.org/domains/root/db/vet.html -vet - -// viajes : Binky Moon, LLC -// https://www.iana.org/domains/root/db/viajes.html -viajes - -// video : Dog Beach, LLC -// https://www.iana.org/domains/root/db/video.html -video - -// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe -// https://www.iana.org/domains/root/db/vig.html -vig - -// viking : Viking River Cruises (Bermuda) Ltd. -// https://www.iana.org/domains/root/db/viking.html -viking - -// villas : Binky Moon, LLC -// https://www.iana.org/domains/root/db/villas.html -villas - -// vin : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vin.html -vin - -// vip : Registry Services, LLC -// https://www.iana.org/domains/root/db/vip.html -vip - -// virgin : Virgin Enterprises Limited -// https://www.iana.org/domains/root/db/virgin.html -virgin - -// visa : Visa Worldwide Pte. Limited -// https://www.iana.org/domains/root/db/visa.html -visa - -// vision : Binky Moon, LLC -// https://www.iana.org/domains/root/db/vision.html -vision - -// viva : Saudi Telecom Company -// https://www.iana.org/domains/root/db/viva.html -viva - -// vivo : Telefonica Brasil S.A. -// https://www.iana.org/domains/root/db/vivo.html -vivo - -// vlaanderen : DNS.be vzw -// https://www.iana.org/domains/root/db/vlaanderen.html -vlaanderen - -// vodka : Registry Services, LLC -// https://www.iana.org/domains/root/db/vodka.html -vodka - -// volvo : Volvo Holding Sverige Aktiebolag -// https://www.iana.org/domains/root/db/volvo.html -volvo - -// vote : Monolith Registry LLC -// https://www.iana.org/domains/root/db/vote.html -vote - -// voting : Valuetainment Corp. -// https://www.iana.org/domains/root/db/voting.html -voting - -// voto : Monolith Registry LLC -// https://www.iana.org/domains/root/db/voto.html -voto - -// voyage : Binky Moon, LLC -// https://www.iana.org/domains/root/db/voyage.html -voyage - -// wales : Nominet UK -// https://www.iana.org/domains/root/db/wales.html -wales - -// walmart : Wal-Mart Stores, Inc. -// https://www.iana.org/domains/root/db/walmart.html -walmart - -// walter : Sandvik AB -// https://www.iana.org/domains/root/db/walter.html -walter - -// wang : Zodiac Wang Limited -// https://www.iana.org/domains/root/db/wang.html -wang - -// wanggou : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/wanggou.html -wanggou - -// watch : Binky Moon, LLC -// https://www.iana.org/domains/root/db/watch.html -watch - -// watches : Identity Digital Limited -// https://www.iana.org/domains/root/db/watches.html -watches - -// weather : International Business Machines Corporation -// https://www.iana.org/domains/root/db/weather.html -weather - -// weatherchannel : International Business Machines Corporation -// https://www.iana.org/domains/root/db/weatherchannel.html -weatherchannel - -// webcam : dot Webcam Limited -// https://www.iana.org/domains/root/db/webcam.html -webcam - -// weber : Saint-Gobain Weber SA -// https://www.iana.org/domains/root/db/weber.html -weber - -// website : Radix Technologies Inc. -// https://www.iana.org/domains/root/db/website.html -website - -// wed -// https://www.iana.org/domains/root/db/wed.html -wed - -// wedding : Registry Services, LLC -// https://www.iana.org/domains/root/db/wedding.html -wedding - -// weibo : Sina Corporation -// https://www.iana.org/domains/root/db/weibo.html -weibo - -// weir : Weir Group IP Limited -// https://www.iana.org/domains/root/db/weir.html -weir - -// whoswho : Who's Who Registry -// https://www.iana.org/domains/root/db/whoswho.html -whoswho - -// wien : punkt.wien GmbH -// https://www.iana.org/domains/root/db/wien.html -wien - -// wiki : Registry Services, LLC -// https://www.iana.org/domains/root/db/wiki.html -wiki - -// williamhill : William Hill Organization Limited -// https://www.iana.org/domains/root/db/williamhill.html -williamhill - -// win : First Registry Limited -// https://www.iana.org/domains/root/db/win.html -win - -// windows : Microsoft Corporation -// https://www.iana.org/domains/root/db/windows.html -windows - -// wine : Binky Moon, LLC -// https://www.iana.org/domains/root/db/wine.html -wine - -// winners : The TJX Companies, Inc. -// https://www.iana.org/domains/root/db/winners.html -winners - -// wme : William Morris Endeavor Entertainment, LLC -// https://www.iana.org/domains/root/db/wme.html -wme - -// wolterskluwer : Wolters Kluwer N.V. -// https://www.iana.org/domains/root/db/wolterskluwer.html -wolterskluwer - -// woodside : Woodside Petroleum Limited -// https://www.iana.org/domains/root/db/woodside.html -woodside - -// work : Registry Services, LLC -// https://www.iana.org/domains/root/db/work.html -work - -// works : Binky Moon, LLC -// https://www.iana.org/domains/root/db/works.html -works - -// world : Binky Moon, LLC -// https://www.iana.org/domains/root/db/world.html -world - -// wow : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/wow.html -wow - -// wtc : World Trade Centers Association, Inc. -// https://www.iana.org/domains/root/db/wtc.html -wtc - -// wtf : Binky Moon, LLC -// https://www.iana.org/domains/root/db/wtf.html -wtf - -// xbox : Microsoft Corporation -// https://www.iana.org/domains/root/db/xbox.html -xbox - -// xerox : Xerox DNHC LLC -// https://www.iana.org/domains/root/db/xerox.html -xerox - -// xihuan : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/xihuan.html -xihuan - -// xin : Elegant Leader Limited -// https://www.iana.org/domains/root/db/xin.html -xin - -// xn--11b4c3d : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--11b4c3d.html -कॉम - -// xn--1ck2e1b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--1ck2e1b.html -セール - -// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--1qqw23a.html -佛山 - -// xn--30rr7y : Excellent First Limited -// https://www.iana.org/domains/root/db/xn--30rr7y.html -慈善 - -// xn--3bst00m : Eagle Horizon Limited -// https://www.iana.org/domains/root/db/xn--3bst00m.html -集团 - -// xn--3ds443g : TLD REGISTRY LIMITED OY -// https://www.iana.org/domains/root/db/xn--3ds443g.html -在线 - -// xn--3pxu8k : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--3pxu8k.html -点看 - -// xn--42c2d9a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--42c2d9a.html -คอม - -// xn--45q11c : Zodiac Gemini Ltd -// https://www.iana.org/domains/root/db/xn--45q11c.html -八卦 - -// xn--4gbrim : Helium TLDs Ltd -// https://www.iana.org/domains/root/db/xn--4gbrim.html -موقع - -// xn--55qw42g : China Organizational Name Administration Center -// https://www.iana.org/domains/root/db/xn--55qw42g.html -公益 - -// xn--55qx5d : China Internet Network Information Center (CNNIC) -// https://www.iana.org/domains/root/db/xn--55qx5d.html -公司 - -// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited -// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html -香格里拉 - -// xn--5tzm5g : Global Website TLD Asia Limited -// https://www.iana.org/domains/root/db/xn--5tzm5g.html -网站 - -// xn--6frz82g : Identity Digital Limited -// https://www.iana.org/domains/root/db/xn--6frz82g.html -移动 - -// xn--6qq986b3xl : Tycoon Treasure Limited -// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html -我爱你 - -// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) -// https://www.iana.org/domains/root/db/xn--80adxhks.html -москва - -// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html -католик - -// xn--80asehdb : CORE Association -// https://www.iana.org/domains/root/db/xn--80asehdb.html -онлайн - -// xn--80aswg : CORE Association -// https://www.iana.org/domains/root/db/xn--80aswg.html -сайт - -// xn--8y0a063a : China United Network Communications Corporation Limited -// https://www.iana.org/domains/root/db/xn--8y0a063a.html -联通 - -// xn--9dbq2a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--9dbq2a.html -קום - -// xn--9et52u : RISE VICTORY LIMITED -// https://www.iana.org/domains/root/db/xn--9et52u.html -时尚 - -// xn--9krt00a : Sina Corporation -// https://www.iana.org/domains/root/db/xn--9krt00a.html -微博 - -// xn--b4w605ferd : Temasek Holdings (Private) Limited -// https://www.iana.org/domains/root/db/xn--b4w605ferd.html -淡马锡 - -// xn--bck1b9a5dre4c : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html -ファッション - -// xn--c1avg : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--c1avg.html -орг - -// xn--c2br7g : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--c2br7g.html -नेट - -// xn--cck2b3b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--cck2b3b.html -ストア - -// xn--cckwcxetd : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--cckwcxetd.html -アマゾン - -// xn--cg4bki : SAMSUNG SDS CO., LTD -// https://www.iana.org/domains/root/db/xn--cg4bki.html -삼성 - -// xn--czr694b : Internet DotTrademark Organisation Limited -// https://www.iana.org/domains/root/db/xn--czr694b.html -商标 - -// xn--czrs0t : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--czrs0t.html -商店 - -// xn--czru2d : Zodiac Aquarius Limited -// https://www.iana.org/domains/root/db/xn--czru2d.html -商城 - -// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” -// https://www.iana.org/domains/root/db/xn--d1acj3b.html -дети - -// xn--eckvdtc9d : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html -ポイント - -// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--efvy88h.html -新闻 - -// xn--fct429k : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--fct429k.html -家電 - -// xn--fhbei : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--fhbei.html -كوم - -// xn--fiq228c5hs : TLD REGISTRY LIMITED OY -// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html -中文网 - -// xn--fiq64b : CITIC Group Corporation -// https://www.iana.org/domains/root/db/xn--fiq64b.html -中信 - -// xn--fjq720a : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--fjq720a.html -娱乐 - -// xn--flw351e : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--flw351e.html -谷歌 - -// xn--fzys8d69uvgm : PCCW Enterprises Limited -// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html -電訊盈科 - -// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. -// https://www.iana.org/domains/root/db/xn--g2xx48c.html -购物 - -// xn--gckr3f0f : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--gckr3f0f.html -クラウド - -// xn--gk3at1e : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--gk3at1e.html -通販 - -// xn--hxt814e : Zodiac Taurus Limited -// https://www.iana.org/domains/root/db/xn--hxt814e.html -网店 - -// xn--i1b6b1a6a2e : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html -संगठन - -// xn--imr513n : Internet DotTrademark Organisation Limited -// https://www.iana.org/domains/root/db/xn--imr513n.html -餐厅 - -// xn--io0a7i : China Internet Network Information Center (CNNIC) -// https://www.iana.org/domains/root/db/xn--io0a7i.html -网络 - -// xn--j1aef : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--j1aef.html -ком - -// xn--jlq480n2rg : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html -亚马逊 - -// xn--jvr189m : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--jvr189m.html -食品 - -// xn--kcrx77d1x4a : Koninklijke Philips N.V. -// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html -飞利浦 - -// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd -// https://www.iana.org/domains/root/db/xn--kput3i.html -手机 - -// xn--mgba3a3ejt : Aramco Services Company -// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html -ارامكو - -// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl -// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html -العليان - -// xn--mgbab2bd : CORE Association -// https://www.iana.org/domains/root/db/xn--mgbab2bd.html -بازار - -// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre -// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html -ابوظبي - -// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html -كاثوليك - -// xn--mgbt3dhd : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. -// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html -همراه - -// xn--mk1bu44c : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--mk1bu44c.html -닷컴 - -// xn--mxtq1m : Net-Chinese Co., Ltd. -// https://www.iana.org/domains/root/db/xn--mxtq1m.html -政府 - -// xn--ngbc5azd : International Domain Registry Pty. Ltd. -// https://www.iana.org/domains/root/db/xn--ngbc5azd.html -شبكة - -// xn--ngbe9e0a : Kuwait Finance House -// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html -بيتك - -// xn--ngbrx : League of Arab States -// https://www.iana.org/domains/root/db/xn--ngbrx.html -عرب - -// xn--nqv7f : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--nqv7f.html -机构 - -// xn--nqv7fs00ema : Public Interest Registry -// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html -组织机构 - -// xn--nyqy26a : Stable Tone Limited -// https://www.iana.org/domains/root/db/xn--nyqy26a.html -健康 - -// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited -// https://www.iana.org/domains/root/db/xn--otu796d.html -招聘 - -// xn--p1acf : Rusnames Limited -// https://www.iana.org/domains/root/db/xn--p1acf.html -рус - -// xn--pssy2u : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--pssy2u.html -大拿 - -// xn--q9jyb4c : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--q9jyb4c.html -みんな - -// xn--qcka1pmc : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/xn--qcka1pmc.html -グーグル - -// xn--rhqv96g : Stable Tone Limited -// https://www.iana.org/domains/root/db/xn--rhqv96g.html -世界 - -// xn--rovu88b : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/xn--rovu88b.html -書籍 - -// xn--ses554g : KNET Co., Ltd. -// https://www.iana.org/domains/root/db/xn--ses554g.html -网址 - -// xn--t60b56a : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--t60b56a.html -닷넷 - -// xn--tckwe : VeriSign Sarl -// https://www.iana.org/domains/root/db/xn--tckwe.html -コム - -// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) -// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html -天主教 - -// xn--unup4y : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--unup4y.html -游戏 - -// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html -vermögensberater - -// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG -// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html -vermögensberatung - -// xn--vhquv : Binky Moon, LLC -// https://www.iana.org/domains/root/db/xn--vhquv.html -企业 - -// xn--vuq861b : Beijing Tele-info Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--vuq861b.html -信息 - -// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html -嘉里大酒店 - -// xn--w4rs40l : Kerry Trading Co. Limited -// https://www.iana.org/domains/root/db/xn--w4rs40l.html -嘉里 - -// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. -// https://www.iana.org/domains/root/db/xn--xhq521b.html -广东 - -// xn--zfr164b : China Organizational Name Administration Center -// https://www.iana.org/domains/root/db/xn--zfr164b.html -政务 - -// xyz : XYZ.COM LLC -// https://www.iana.org/domains/root/db/xyz.html -xyz - -// yachts : XYZ.COM LLC -// https://www.iana.org/domains/root/db/yachts.html -yachts - -// yahoo : Oath Inc. -// https://www.iana.org/domains/root/db/yahoo.html -yahoo - -// yamaxun : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/yamaxun.html -yamaxun - -// yandex : Yandex Europe B.V. -// https://www.iana.org/domains/root/db/yandex.html -yandex - -// yodobashi : YODOBASHI CAMERA CO.,LTD. -// https://www.iana.org/domains/root/db/yodobashi.html -yodobashi - -// yoga : Registry Services, LLC -// https://www.iana.org/domains/root/db/yoga.html -yoga - -// yokohama : GMO Registry, Inc. -// https://www.iana.org/domains/root/db/yokohama.html -yokohama - -// you : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/you.html -you - -// youtube : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/youtube.html -youtube - -// yun : Beijing Qihu Keji Co., Ltd. -// https://www.iana.org/domains/root/db/yun.html -yun - -// zappos : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/zappos.html -zappos - -// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) -// https://www.iana.org/domains/root/db/zara.html -zara - -// zero : Amazon Registry Services, Inc. -// https://www.iana.org/domains/root/db/zero.html -zero - -// zip : Charleston Road Registry Inc. -// https://www.iana.org/domains/root/db/zip.html -zip - -// zone : Binky Moon, LLC -// https://www.iana.org/domains/root/db/zone.html -zone - -// zuerich : Kanton Zürich (Canton of Zurich) -// https://www.iana.org/domains/root/db/zuerich.html -zuerich - - -// ===END ICANN DOMAINS=== -// ===BEGIN PRIVATE DOMAINS=== -// (Note: these are in alphabetical order by company name) - -// 12CHARS: https://12chars.com -// Submitted by Kenny Niehage -12chars.dev -12chars.it -12chars.pro - -// 1GB LLC : https://www.1gb.ua/ -// Submitted by 1GB LLC -cc.ua -inf.ua -ltd.ua - -// 611coin : https://611project.org/ -611.to - -// A2 Hosting -// Submitted by Tyler Hall -a2hosted.com -cpserver.com - -// Aaron Marais' Gitlab pages: https://lab.aaronleem.co.za -// Submitted by Aaron Marais -graphox.us - -// accesso Technology Group, plc. : https://accesso.com/ -// Submitted by accesso Team -*.devcdnaccesso.com - -// Acorn Labs : https://acorn.io -// Submitted by Craig Jellick -*.on-acorn.io - -// ActiveTrail: https://www.activetrail.biz/ -// Submitted by Ofer Kalaora -activetrail.biz - -// Adaptable.io : https://adaptable.io -// Submitted by Mark Terrel -adaptable.app - -// Adobe : https://www.adobe.com/ -// Submitted by Ian Boston and Lars Trieloff -adobeaemcloud.com -*.dev.adobeaemcloud.com -aem.live -hlx.live -adobeaemcloud.net -aem.page -hlx.page -hlx3.page - -// Adobe Developer Platform : https://developer.adobe.com -// Submitted by Jesse MacFadyen -adobeio-static.net -adobeioruntime.net - -// Agnat sp. z o.o. : https://domena.pl -// Submitted by Przemyslaw Plewa -beep.pl - -// Airkit : https://www.airkit.com/ -// Submitted by Grant Cooksey -airkitapps.com -airkitapps-au.com -airkitapps.eu - -// Aiven: https://aiven.io/ -// Submitted by Etienne Stalmans -aivencloud.com - -// Akamai : https://www.akamai.com/ -// Submitted by Akamai Team -akadns.net -akamai.net -akamai-staging.net -akamaiedge.net -akamaiedge-staging.net -akamaihd.net -akamaihd-staging.net -akamaiorigin.net -akamaiorigin-staging.net -akamaized.net -akamaized-staging.net -edgekey.net -edgekey-staging.net -edgesuite.net -edgesuite-staging.net - -// alboto.ca : http://alboto.ca -// Submitted by Anton Avramov -barsy.ca - -// Alces Software Ltd : http://alces-software.com -// Submitted by Mark J. Titorenko -*.compute.estate -*.alces.network - -// all-inkl.com : https://all-inkl.com -// Submitted by Werner Kaltofen -kasserver.com - -// Altervista: https://www.altervista.org -// Submitted by Carlo Cannas -altervista.org - -// alwaysdata : https://www.alwaysdata.com -// Submitted by Cyril -alwaysdata.net - -// Amaze Software : https://amaze.co -// Submitted by Domain Admin -myamaze.net - -// Amazon : https://www.amazon.com/ -// Submitted by AWS Security -// Subsections of Amazon/subsidiaries will appear until "concludes" tag - -// Amazon API Gateway -// Submitted by AWS Security -// Reference: 9e37648f-a66c-4655-9ab1-5981f8737197 -execute-api.cn-north-1.amazonaws.com.cn -execute-api.cn-northwest-1.amazonaws.com.cn -execute-api.af-south-1.amazonaws.com -execute-api.ap-east-1.amazonaws.com -execute-api.ap-northeast-1.amazonaws.com -execute-api.ap-northeast-2.amazonaws.com -execute-api.ap-northeast-3.amazonaws.com -execute-api.ap-south-1.amazonaws.com -execute-api.ap-south-2.amazonaws.com -execute-api.ap-southeast-1.amazonaws.com -execute-api.ap-southeast-2.amazonaws.com -execute-api.ap-southeast-3.amazonaws.com -execute-api.ap-southeast-4.amazonaws.com -execute-api.ca-central-1.amazonaws.com -execute-api.ca-west-1.amazonaws.com -execute-api.eu-central-1.amazonaws.com -execute-api.eu-central-2.amazonaws.com -execute-api.eu-north-1.amazonaws.com -execute-api.eu-south-1.amazonaws.com -execute-api.eu-south-2.amazonaws.com -execute-api.eu-west-1.amazonaws.com -execute-api.eu-west-2.amazonaws.com -execute-api.eu-west-3.amazonaws.com -execute-api.il-central-1.amazonaws.com -execute-api.me-central-1.amazonaws.com -execute-api.me-south-1.amazonaws.com -execute-api.sa-east-1.amazonaws.com -execute-api.us-east-1.amazonaws.com -execute-api.us-east-2.amazonaws.com -execute-api.us-gov-east-1.amazonaws.com -execute-api.us-gov-west-1.amazonaws.com -execute-api.us-west-1.amazonaws.com -execute-api.us-west-2.amazonaws.com - -// Amazon CloudFront -// Submitted by Donavan Miller -// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 -cloudfront.net - -// Amazon Cognito -// Submitted by AWS Security -// Reference: 7bee1013-f456-47df-bfe8-03c78d946d61 -auth.af-south-1.amazoncognito.com -auth.ap-northeast-1.amazoncognito.com -auth.ap-northeast-2.amazoncognito.com -auth.ap-northeast-3.amazoncognito.com -auth.ap-south-1.amazoncognito.com -auth.ap-southeast-1.amazoncognito.com -auth.ap-southeast-2.amazoncognito.com -auth.ap-southeast-3.amazoncognito.com -auth.ca-central-1.amazoncognito.com -auth.eu-central-1.amazoncognito.com -auth.eu-north-1.amazoncognito.com -auth.eu-south-1.amazoncognito.com -auth.eu-west-1.amazoncognito.com -auth.eu-west-2.amazoncognito.com -auth.eu-west-3.amazoncognito.com -auth.il-central-1.amazoncognito.com -auth.me-south-1.amazoncognito.com -auth.sa-east-1.amazoncognito.com -auth.us-east-1.amazoncognito.com -auth-fips.us-east-1.amazoncognito.com -auth.us-east-2.amazoncognito.com -auth-fips.us-east-2.amazoncognito.com -auth-fips.us-gov-west-1.amazoncognito.com -auth.us-west-1.amazoncognito.com -auth-fips.us-west-1.amazoncognito.com -auth.us-west-2.amazoncognito.com -auth-fips.us-west-2.amazoncognito.com - -// Amazon EC2 -// Submitted by Luke Wells -// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 -*.compute.amazonaws.com -*.compute-1.amazonaws.com -*.compute.amazonaws.com.cn -us-east-1.amazonaws.com - -// Amazon EMR -// Submitted by AWS Security -// Reference: 597f3f8e-9283-4e48-8e32-7ee25a1ff6ab -emrappui-prod.cn-north-1.amazonaws.com.cn -emrnotebooks-prod.cn-north-1.amazonaws.com.cn -emrstudio-prod.cn-north-1.amazonaws.com.cn -emrappui-prod.cn-northwest-1.amazonaws.com.cn -emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn -emrstudio-prod.cn-northwest-1.amazonaws.com.cn -emrappui-prod.af-south-1.amazonaws.com -emrnotebooks-prod.af-south-1.amazonaws.com -emrstudio-prod.af-south-1.amazonaws.com -emrappui-prod.ap-east-1.amazonaws.com -emrnotebooks-prod.ap-east-1.amazonaws.com -emrstudio-prod.ap-east-1.amazonaws.com -emrappui-prod.ap-northeast-1.amazonaws.com -emrnotebooks-prod.ap-northeast-1.amazonaws.com -emrstudio-prod.ap-northeast-1.amazonaws.com -emrappui-prod.ap-northeast-2.amazonaws.com -emrnotebooks-prod.ap-northeast-2.amazonaws.com -emrstudio-prod.ap-northeast-2.amazonaws.com -emrappui-prod.ap-northeast-3.amazonaws.com -emrnotebooks-prod.ap-northeast-3.amazonaws.com -emrstudio-prod.ap-northeast-3.amazonaws.com -emrappui-prod.ap-south-1.amazonaws.com -emrnotebooks-prod.ap-south-1.amazonaws.com -emrstudio-prod.ap-south-1.amazonaws.com -emrappui-prod.ap-southeast-1.amazonaws.com -emrnotebooks-prod.ap-southeast-1.amazonaws.com -emrstudio-prod.ap-southeast-1.amazonaws.com -emrappui-prod.ap-southeast-2.amazonaws.com -emrnotebooks-prod.ap-southeast-2.amazonaws.com -emrstudio-prod.ap-southeast-2.amazonaws.com -emrappui-prod.ap-southeast-3.amazonaws.com -emrnotebooks-prod.ap-southeast-3.amazonaws.com -emrstudio-prod.ap-southeast-3.amazonaws.com -emrappui-prod.ca-central-1.amazonaws.com -emrnotebooks-prod.ca-central-1.amazonaws.com -emrstudio-prod.ca-central-1.amazonaws.com -emrappui-prod.eu-central-1.amazonaws.com -emrnotebooks-prod.eu-central-1.amazonaws.com -emrstudio-prod.eu-central-1.amazonaws.com -emrappui-prod.eu-north-1.amazonaws.com -emrnotebooks-prod.eu-north-1.amazonaws.com -emrstudio-prod.eu-north-1.amazonaws.com -emrappui-prod.eu-south-1.amazonaws.com -emrnotebooks-prod.eu-south-1.amazonaws.com -emrstudio-prod.eu-south-1.amazonaws.com -emrappui-prod.eu-west-1.amazonaws.com -emrnotebooks-prod.eu-west-1.amazonaws.com -emrstudio-prod.eu-west-1.amazonaws.com -emrappui-prod.eu-west-2.amazonaws.com -emrnotebooks-prod.eu-west-2.amazonaws.com -emrstudio-prod.eu-west-2.amazonaws.com -emrappui-prod.eu-west-3.amazonaws.com -emrnotebooks-prod.eu-west-3.amazonaws.com -emrstudio-prod.eu-west-3.amazonaws.com -emrappui-prod.me-central-1.amazonaws.com -emrnotebooks-prod.me-central-1.amazonaws.com -emrstudio-prod.me-central-1.amazonaws.com -emrappui-prod.me-south-1.amazonaws.com -emrnotebooks-prod.me-south-1.amazonaws.com -emrstudio-prod.me-south-1.amazonaws.com -emrappui-prod.sa-east-1.amazonaws.com -emrnotebooks-prod.sa-east-1.amazonaws.com -emrstudio-prod.sa-east-1.amazonaws.com -emrappui-prod.us-east-1.amazonaws.com -emrnotebooks-prod.us-east-1.amazonaws.com -emrstudio-prod.us-east-1.amazonaws.com -emrappui-prod.us-east-2.amazonaws.com -emrnotebooks-prod.us-east-2.amazonaws.com -emrstudio-prod.us-east-2.amazonaws.com -emrappui-prod.us-gov-east-1.amazonaws.com -emrnotebooks-prod.us-gov-east-1.amazonaws.com -emrstudio-prod.us-gov-east-1.amazonaws.com -emrappui-prod.us-gov-west-1.amazonaws.com -emrnotebooks-prod.us-gov-west-1.amazonaws.com -emrstudio-prod.us-gov-west-1.amazonaws.com -emrappui-prod.us-west-1.amazonaws.com -emrnotebooks-prod.us-west-1.amazonaws.com -emrstudio-prod.us-west-1.amazonaws.com -emrappui-prod.us-west-2.amazonaws.com -emrnotebooks-prod.us-west-2.amazonaws.com -emrstudio-prod.us-west-2.amazonaws.com - -// Amazon Managed Workflows for Apache Airflow -// Submitted by AWS Security -// Reference: 4ab55e6f-90c0-4a8d-b6a0-52ca5dbb1c2e -*.cn-north-1.airflow.amazonaws.com.cn -*.cn-northwest-1.airflow.amazonaws.com.cn -*.ap-northeast-1.airflow.amazonaws.com -*.ap-northeast-2.airflow.amazonaws.com -*.ap-south-1.airflow.amazonaws.com -*.ap-southeast-1.airflow.amazonaws.com -*.ap-southeast-2.airflow.amazonaws.com -*.ca-central-1.airflow.amazonaws.com -*.eu-central-1.airflow.amazonaws.com -*.eu-north-1.airflow.amazonaws.com -*.eu-west-1.airflow.amazonaws.com -*.eu-west-2.airflow.amazonaws.com -*.eu-west-3.airflow.amazonaws.com -*.sa-east-1.airflow.amazonaws.com -*.us-east-1.airflow.amazonaws.com -*.us-east-2.airflow.amazonaws.com -*.us-west-2.airflow.amazonaws.com - -// Amazon S3 -// Submitted by AWS Security -// Reference: cd5c8b3a-67b7-4b40-9236-c87ce81a3d10 -s3.dualstack.cn-north-1.amazonaws.com.cn -s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn -s3-website.dualstack.cn-north-1.amazonaws.com.cn -s3.cn-north-1.amazonaws.com.cn -s3-accesspoint.cn-north-1.amazonaws.com.cn -s3-deprecated.cn-north-1.amazonaws.com.cn -s3-object-lambda.cn-north-1.amazonaws.com.cn -s3-website.cn-north-1.amazonaws.com.cn -s3.dualstack.cn-northwest-1.amazonaws.com.cn -s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn -s3.cn-northwest-1.amazonaws.com.cn -s3-accesspoint.cn-northwest-1.amazonaws.com.cn -s3-object-lambda.cn-northwest-1.amazonaws.com.cn -s3-website.cn-northwest-1.amazonaws.com.cn -s3.dualstack.af-south-1.amazonaws.com -s3-accesspoint.dualstack.af-south-1.amazonaws.com -s3-website.dualstack.af-south-1.amazonaws.com -s3.af-south-1.amazonaws.com -s3-accesspoint.af-south-1.amazonaws.com -s3-object-lambda.af-south-1.amazonaws.com -s3-website.af-south-1.amazonaws.com -s3.dualstack.ap-east-1.amazonaws.com -s3-accesspoint.dualstack.ap-east-1.amazonaws.com -s3.ap-east-1.amazonaws.com -s3-accesspoint.ap-east-1.amazonaws.com -s3-object-lambda.ap-east-1.amazonaws.com -s3-website.ap-east-1.amazonaws.com -s3.dualstack.ap-northeast-1.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com -s3-website.dualstack.ap-northeast-1.amazonaws.com -s3.ap-northeast-1.amazonaws.com -s3-accesspoint.ap-northeast-1.amazonaws.com -s3-object-lambda.ap-northeast-1.amazonaws.com -s3-website.ap-northeast-1.amazonaws.com -s3.dualstack.ap-northeast-2.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com -s3-website.dualstack.ap-northeast-2.amazonaws.com -s3.ap-northeast-2.amazonaws.com -s3-accesspoint.ap-northeast-2.amazonaws.com -s3-object-lambda.ap-northeast-2.amazonaws.com -s3-website.ap-northeast-2.amazonaws.com -s3.dualstack.ap-northeast-3.amazonaws.com -s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com -s3-website.dualstack.ap-northeast-3.amazonaws.com -s3.ap-northeast-3.amazonaws.com -s3-accesspoint.ap-northeast-3.amazonaws.com -s3-object-lambda.ap-northeast-3.amazonaws.com -s3-website.ap-northeast-3.amazonaws.com -s3.dualstack.ap-south-1.amazonaws.com -s3-accesspoint.dualstack.ap-south-1.amazonaws.com -s3-website.dualstack.ap-south-1.amazonaws.com -s3.ap-south-1.amazonaws.com -s3-accesspoint.ap-south-1.amazonaws.com -s3-object-lambda.ap-south-1.amazonaws.com -s3-website.ap-south-1.amazonaws.com -s3.dualstack.ap-south-2.amazonaws.com -s3-accesspoint.dualstack.ap-south-2.amazonaws.com -s3.ap-south-2.amazonaws.com -s3-accesspoint.ap-south-2.amazonaws.com -s3-object-lambda.ap-south-2.amazonaws.com -s3-website.ap-south-2.amazonaws.com -s3.dualstack.ap-southeast-1.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com -s3-website.dualstack.ap-southeast-1.amazonaws.com -s3.ap-southeast-1.amazonaws.com -s3-accesspoint.ap-southeast-1.amazonaws.com -s3-object-lambda.ap-southeast-1.amazonaws.com -s3-website.ap-southeast-1.amazonaws.com -s3.dualstack.ap-southeast-2.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com -s3-website.dualstack.ap-southeast-2.amazonaws.com -s3.ap-southeast-2.amazonaws.com -s3-accesspoint.ap-southeast-2.amazonaws.com -s3-object-lambda.ap-southeast-2.amazonaws.com -s3-website.ap-southeast-2.amazonaws.com -s3.dualstack.ap-southeast-3.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com -s3.ap-southeast-3.amazonaws.com -s3-accesspoint.ap-southeast-3.amazonaws.com -s3-object-lambda.ap-southeast-3.amazonaws.com -s3-website.ap-southeast-3.amazonaws.com -s3.dualstack.ap-southeast-4.amazonaws.com -s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com -s3.ap-southeast-4.amazonaws.com -s3-accesspoint.ap-southeast-4.amazonaws.com -s3-object-lambda.ap-southeast-4.amazonaws.com -s3-website.ap-southeast-4.amazonaws.com -s3.dualstack.ca-central-1.amazonaws.com -s3-accesspoint.dualstack.ca-central-1.amazonaws.com -s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com -s3-fips.dualstack.ca-central-1.amazonaws.com -s3-website.dualstack.ca-central-1.amazonaws.com -s3.ca-central-1.amazonaws.com -s3-accesspoint.ca-central-1.amazonaws.com -s3-accesspoint-fips.ca-central-1.amazonaws.com -s3-fips.ca-central-1.amazonaws.com -s3-object-lambda.ca-central-1.amazonaws.com -s3-website.ca-central-1.amazonaws.com -s3.dualstack.ca-west-1.amazonaws.com -s3-accesspoint.dualstack.ca-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com -s3-fips.dualstack.ca-west-1.amazonaws.com -s3-website.dualstack.ca-west-1.amazonaws.com -s3.ca-west-1.amazonaws.com -s3-accesspoint.ca-west-1.amazonaws.com -s3-accesspoint-fips.ca-west-1.amazonaws.com -s3-fips.ca-west-1.amazonaws.com -s3-website.ca-west-1.amazonaws.com -s3.dualstack.eu-central-1.amazonaws.com -s3-accesspoint.dualstack.eu-central-1.amazonaws.com -s3-website.dualstack.eu-central-1.amazonaws.com -s3.eu-central-1.amazonaws.com -s3-accesspoint.eu-central-1.amazonaws.com -s3-object-lambda.eu-central-1.amazonaws.com -s3-website.eu-central-1.amazonaws.com -s3.dualstack.eu-central-2.amazonaws.com -s3-accesspoint.dualstack.eu-central-2.amazonaws.com -s3.eu-central-2.amazonaws.com -s3-accesspoint.eu-central-2.amazonaws.com -s3-object-lambda.eu-central-2.amazonaws.com -s3-website.eu-central-2.amazonaws.com -s3.dualstack.eu-north-1.amazonaws.com -s3-accesspoint.dualstack.eu-north-1.amazonaws.com -s3.eu-north-1.amazonaws.com -s3-accesspoint.eu-north-1.amazonaws.com -s3-object-lambda.eu-north-1.amazonaws.com -s3-website.eu-north-1.amazonaws.com -s3.dualstack.eu-south-1.amazonaws.com -s3-accesspoint.dualstack.eu-south-1.amazonaws.com -s3-website.dualstack.eu-south-1.amazonaws.com -s3.eu-south-1.amazonaws.com -s3-accesspoint.eu-south-1.amazonaws.com -s3-object-lambda.eu-south-1.amazonaws.com -s3-website.eu-south-1.amazonaws.com -s3.dualstack.eu-south-2.amazonaws.com -s3-accesspoint.dualstack.eu-south-2.amazonaws.com -s3.eu-south-2.amazonaws.com -s3-accesspoint.eu-south-2.amazonaws.com -s3-object-lambda.eu-south-2.amazonaws.com -s3-website.eu-south-2.amazonaws.com -s3.dualstack.eu-west-1.amazonaws.com -s3-accesspoint.dualstack.eu-west-1.amazonaws.com -s3-website.dualstack.eu-west-1.amazonaws.com -s3.eu-west-1.amazonaws.com -s3-accesspoint.eu-west-1.amazonaws.com -s3-deprecated.eu-west-1.amazonaws.com -s3-object-lambda.eu-west-1.amazonaws.com -s3-website.eu-west-1.amazonaws.com -s3.dualstack.eu-west-2.amazonaws.com -s3-accesspoint.dualstack.eu-west-2.amazonaws.com -s3.eu-west-2.amazonaws.com -s3-accesspoint.eu-west-2.amazonaws.com -s3-object-lambda.eu-west-2.amazonaws.com -s3-website.eu-west-2.amazonaws.com -s3.dualstack.eu-west-3.amazonaws.com -s3-accesspoint.dualstack.eu-west-3.amazonaws.com -s3-website.dualstack.eu-west-3.amazonaws.com -s3.eu-west-3.amazonaws.com -s3-accesspoint.eu-west-3.amazonaws.com -s3-object-lambda.eu-west-3.amazonaws.com -s3-website.eu-west-3.amazonaws.com -s3.dualstack.il-central-1.amazonaws.com -s3-accesspoint.dualstack.il-central-1.amazonaws.com -s3.il-central-1.amazonaws.com -s3-accesspoint.il-central-1.amazonaws.com -s3-object-lambda.il-central-1.amazonaws.com -s3-website.il-central-1.amazonaws.com -s3.dualstack.me-central-1.amazonaws.com -s3-accesspoint.dualstack.me-central-1.amazonaws.com -s3.me-central-1.amazonaws.com -s3-accesspoint.me-central-1.amazonaws.com -s3-object-lambda.me-central-1.amazonaws.com -s3-website.me-central-1.amazonaws.com -s3.dualstack.me-south-1.amazonaws.com -s3-accesspoint.dualstack.me-south-1.amazonaws.com -s3.me-south-1.amazonaws.com -s3-accesspoint.me-south-1.amazonaws.com -s3-object-lambda.me-south-1.amazonaws.com -s3-website.me-south-1.amazonaws.com -s3.amazonaws.com -s3-1.amazonaws.com -s3-ap-east-1.amazonaws.com -s3-ap-northeast-1.amazonaws.com -s3-ap-northeast-2.amazonaws.com -s3-ap-northeast-3.amazonaws.com -s3-ap-south-1.amazonaws.com -s3-ap-southeast-1.amazonaws.com -s3-ap-southeast-2.amazonaws.com -s3-ca-central-1.amazonaws.com -s3-eu-central-1.amazonaws.com -s3-eu-north-1.amazonaws.com -s3-eu-west-1.amazonaws.com -s3-eu-west-2.amazonaws.com -s3-eu-west-3.amazonaws.com -s3-external-1.amazonaws.com -s3-fips-us-gov-east-1.amazonaws.com -s3-fips-us-gov-west-1.amazonaws.com -mrap.accesspoint.s3-global.amazonaws.com -s3-me-south-1.amazonaws.com -s3-sa-east-1.amazonaws.com -s3-us-east-2.amazonaws.com -s3-us-gov-east-1.amazonaws.com -s3-us-gov-west-1.amazonaws.com -s3-us-west-1.amazonaws.com -s3-us-west-2.amazonaws.com -s3-website-ap-northeast-1.amazonaws.com -s3-website-ap-southeast-1.amazonaws.com -s3-website-ap-southeast-2.amazonaws.com -s3-website-eu-west-1.amazonaws.com -s3-website-sa-east-1.amazonaws.com -s3-website-us-east-1.amazonaws.com -s3-website-us-gov-west-1.amazonaws.com -s3-website-us-west-1.amazonaws.com -s3-website-us-west-2.amazonaws.com -s3.dualstack.sa-east-1.amazonaws.com -s3-accesspoint.dualstack.sa-east-1.amazonaws.com -s3-website.dualstack.sa-east-1.amazonaws.com -s3.sa-east-1.amazonaws.com -s3-accesspoint.sa-east-1.amazonaws.com -s3-object-lambda.sa-east-1.amazonaws.com -s3-website.sa-east-1.amazonaws.com -s3.dualstack.us-east-1.amazonaws.com -s3-accesspoint.dualstack.us-east-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com -s3-fips.dualstack.us-east-1.amazonaws.com -s3-website.dualstack.us-east-1.amazonaws.com -s3.us-east-1.amazonaws.com -s3-accesspoint.us-east-1.amazonaws.com -s3-accesspoint-fips.us-east-1.amazonaws.com -s3-deprecated.us-east-1.amazonaws.com -s3-fips.us-east-1.amazonaws.com -s3-object-lambda.us-east-1.amazonaws.com -s3-website.us-east-1.amazonaws.com -s3.dualstack.us-east-2.amazonaws.com -s3-accesspoint.dualstack.us-east-2.amazonaws.com -s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com -s3-fips.dualstack.us-east-2.amazonaws.com -s3.us-east-2.amazonaws.com -s3-accesspoint.us-east-2.amazonaws.com -s3-accesspoint-fips.us-east-2.amazonaws.com -s3-deprecated.us-east-2.amazonaws.com -s3-fips.us-east-2.amazonaws.com -s3-object-lambda.us-east-2.amazonaws.com -s3-website.us-east-2.amazonaws.com -s3.dualstack.us-gov-east-1.amazonaws.com -s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com -s3-fips.dualstack.us-gov-east-1.amazonaws.com -s3.us-gov-east-1.amazonaws.com -s3-accesspoint.us-gov-east-1.amazonaws.com -s3-accesspoint-fips.us-gov-east-1.amazonaws.com -s3-fips.us-gov-east-1.amazonaws.com -s3-object-lambda.us-gov-east-1.amazonaws.com -s3-website.us-gov-east-1.amazonaws.com -s3.dualstack.us-gov-west-1.amazonaws.com -s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com -s3-fips.dualstack.us-gov-west-1.amazonaws.com -s3.us-gov-west-1.amazonaws.com -s3-accesspoint.us-gov-west-1.amazonaws.com -s3-accesspoint-fips.us-gov-west-1.amazonaws.com -s3-fips.us-gov-west-1.amazonaws.com -s3-object-lambda.us-gov-west-1.amazonaws.com -s3-website.us-gov-west-1.amazonaws.com -s3.dualstack.us-west-1.amazonaws.com -s3-accesspoint.dualstack.us-west-1.amazonaws.com -s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com -s3-fips.dualstack.us-west-1.amazonaws.com -s3-website.dualstack.us-west-1.amazonaws.com -s3.us-west-1.amazonaws.com -s3-accesspoint.us-west-1.amazonaws.com -s3-accesspoint-fips.us-west-1.amazonaws.com -s3-fips.us-west-1.amazonaws.com -s3-object-lambda.us-west-1.amazonaws.com -s3-website.us-west-1.amazonaws.com -s3.dualstack.us-west-2.amazonaws.com -s3-accesspoint.dualstack.us-west-2.amazonaws.com -s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com -s3-fips.dualstack.us-west-2.amazonaws.com -s3-website.dualstack.us-west-2.amazonaws.com -s3.us-west-2.amazonaws.com -s3-accesspoint.us-west-2.amazonaws.com -s3-accesspoint-fips.us-west-2.amazonaws.com -s3-deprecated.us-west-2.amazonaws.com -s3-fips.us-west-2.amazonaws.com -s3-object-lambda.us-west-2.amazonaws.com -s3-website.us-west-2.amazonaws.com - -// Amazon SageMaker Notebook Instances -// Submitted by AWS Security -// Reference: ce8ae0b1-0070-496d-be88-37c31837af9d -notebook.af-south-1.sagemaker.aws -notebook.ap-east-1.sagemaker.aws -notebook.ap-northeast-1.sagemaker.aws -notebook.ap-northeast-2.sagemaker.aws -notebook.ap-northeast-3.sagemaker.aws -notebook.ap-south-1.sagemaker.aws -notebook.ap-south-2.sagemaker.aws -notebook.ap-southeast-1.sagemaker.aws -notebook.ap-southeast-2.sagemaker.aws -notebook.ap-southeast-3.sagemaker.aws -notebook.ap-southeast-4.sagemaker.aws -notebook.ca-central-1.sagemaker.aws -notebook-fips.ca-central-1.sagemaker.aws -notebook.ca-west-1.sagemaker.aws -notebook-fips.ca-west-1.sagemaker.aws -notebook.eu-central-1.sagemaker.aws -notebook.eu-central-2.sagemaker.aws -notebook.eu-north-1.sagemaker.aws -notebook.eu-south-1.sagemaker.aws -notebook.eu-south-2.sagemaker.aws -notebook.eu-west-1.sagemaker.aws -notebook.eu-west-2.sagemaker.aws -notebook.eu-west-3.sagemaker.aws -notebook.il-central-1.sagemaker.aws -notebook.me-central-1.sagemaker.aws -notebook.me-south-1.sagemaker.aws -notebook.sa-east-1.sagemaker.aws -notebook.us-east-1.sagemaker.aws -notebook-fips.us-east-1.sagemaker.aws -notebook.us-east-2.sagemaker.aws -notebook-fips.us-east-2.sagemaker.aws -notebook.us-gov-east-1.sagemaker.aws -notebook-fips.us-gov-east-1.sagemaker.aws -notebook.us-gov-west-1.sagemaker.aws -notebook-fips.us-gov-west-1.sagemaker.aws -notebook.us-west-1.sagemaker.aws -notebook.us-west-2.sagemaker.aws -notebook-fips.us-west-2.sagemaker.aws -notebook.cn-north-1.sagemaker.com.cn -notebook.cn-northwest-1.sagemaker.com.cn - -// Amazon SageMaker Studio -// Submitted by AWS Security -// Reference: 057ee397-6bf8-4f20-b807-d7bc145ac980 -studio.af-south-1.sagemaker.aws -studio.ap-east-1.sagemaker.aws -studio.ap-northeast-1.sagemaker.aws -studio.ap-northeast-2.sagemaker.aws -studio.ap-northeast-3.sagemaker.aws -studio.ap-south-1.sagemaker.aws -studio.ap-southeast-1.sagemaker.aws -studio.ap-southeast-2.sagemaker.aws -studio.ap-southeast-3.sagemaker.aws -studio.ca-central-1.sagemaker.aws -studio.eu-central-1.sagemaker.aws -studio.eu-north-1.sagemaker.aws -studio.eu-south-1.sagemaker.aws -studio.eu-west-1.sagemaker.aws -studio.eu-west-2.sagemaker.aws -studio.eu-west-3.sagemaker.aws -studio.il-central-1.sagemaker.aws -studio.me-central-1.sagemaker.aws -studio.me-south-1.sagemaker.aws -studio.sa-east-1.sagemaker.aws -studio.us-east-1.sagemaker.aws -studio.us-east-2.sagemaker.aws -studio.us-gov-east-1.sagemaker.aws -studio-fips.us-gov-east-1.sagemaker.aws -studio.us-gov-west-1.sagemaker.aws -studio-fips.us-gov-west-1.sagemaker.aws -studio.us-west-1.sagemaker.aws -studio.us-west-2.sagemaker.aws -studio.cn-north-1.sagemaker.com.cn -studio.cn-northwest-1.sagemaker.com.cn - -// Analytics on AWS -// Submitted by AWS Security -// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd -analytics-gateway.ap-northeast-1.amazonaws.com -analytics-gateway.ap-northeast-2.amazonaws.com -analytics-gateway.ap-south-1.amazonaws.com -analytics-gateway.ap-southeast-1.amazonaws.com -analytics-gateway.ap-southeast-2.amazonaws.com -analytics-gateway.eu-central-1.amazonaws.com -analytics-gateway.eu-west-1.amazonaws.com -analytics-gateway.us-east-1.amazonaws.com -analytics-gateway.us-east-2.amazonaws.com -analytics-gateway.us-west-2.amazonaws.com - -// AWS Amplify -// Submitted by AWS Security -// Reference: 5ecce854-c033-4fc4-a755-1a9916d9a9bb -*.amplifyapp.com - -// AWS App Runner -// Submitted by AWS Security -// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 -*.awsapprunner.com - -// AWS Cloud9 -// Submitted by: AWS Security -// Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 -webview-assets.aws-cloud9.af-south-1.amazonaws.com -vfs.cloud9.af-south-1.amazonaws.com -webview-assets.cloud9.af-south-1.amazonaws.com -webview-assets.aws-cloud9.ap-east-1.amazonaws.com -vfs.cloud9.ap-east-1.amazonaws.com -webview-assets.cloud9.ap-east-1.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com -vfs.cloud9.ap-northeast-1.amazonaws.com -webview-assets.cloud9.ap-northeast-1.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com -vfs.cloud9.ap-northeast-2.amazonaws.com -webview-assets.cloud9.ap-northeast-2.amazonaws.com -webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com -vfs.cloud9.ap-northeast-3.amazonaws.com -webview-assets.cloud9.ap-northeast-3.amazonaws.com -webview-assets.aws-cloud9.ap-south-1.amazonaws.com -vfs.cloud9.ap-south-1.amazonaws.com -webview-assets.cloud9.ap-south-1.amazonaws.com -webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com -vfs.cloud9.ap-southeast-1.amazonaws.com -webview-assets.cloud9.ap-southeast-1.amazonaws.com -webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com -vfs.cloud9.ap-southeast-2.amazonaws.com -webview-assets.cloud9.ap-southeast-2.amazonaws.com -webview-assets.aws-cloud9.ca-central-1.amazonaws.com -vfs.cloud9.ca-central-1.amazonaws.com -webview-assets.cloud9.ca-central-1.amazonaws.com -webview-assets.aws-cloud9.eu-central-1.amazonaws.com -vfs.cloud9.eu-central-1.amazonaws.com -webview-assets.cloud9.eu-central-1.amazonaws.com -webview-assets.aws-cloud9.eu-north-1.amazonaws.com -vfs.cloud9.eu-north-1.amazonaws.com -webview-assets.cloud9.eu-north-1.amazonaws.com -webview-assets.aws-cloud9.eu-south-1.amazonaws.com -vfs.cloud9.eu-south-1.amazonaws.com -webview-assets.cloud9.eu-south-1.amazonaws.com -webview-assets.aws-cloud9.eu-west-1.amazonaws.com -vfs.cloud9.eu-west-1.amazonaws.com -webview-assets.cloud9.eu-west-1.amazonaws.com -webview-assets.aws-cloud9.eu-west-2.amazonaws.com -vfs.cloud9.eu-west-2.amazonaws.com -webview-assets.cloud9.eu-west-2.amazonaws.com -webview-assets.aws-cloud9.eu-west-3.amazonaws.com -vfs.cloud9.eu-west-3.amazonaws.com -webview-assets.cloud9.eu-west-3.amazonaws.com -webview-assets.aws-cloud9.il-central-1.amazonaws.com -vfs.cloud9.il-central-1.amazonaws.com -webview-assets.aws-cloud9.me-south-1.amazonaws.com -vfs.cloud9.me-south-1.amazonaws.com -webview-assets.cloud9.me-south-1.amazonaws.com -webview-assets.aws-cloud9.sa-east-1.amazonaws.com -vfs.cloud9.sa-east-1.amazonaws.com -webview-assets.cloud9.sa-east-1.amazonaws.com -webview-assets.aws-cloud9.us-east-1.amazonaws.com -vfs.cloud9.us-east-1.amazonaws.com -webview-assets.cloud9.us-east-1.amazonaws.com -webview-assets.aws-cloud9.us-east-2.amazonaws.com -vfs.cloud9.us-east-2.amazonaws.com -webview-assets.cloud9.us-east-2.amazonaws.com -webview-assets.aws-cloud9.us-west-1.amazonaws.com -vfs.cloud9.us-west-1.amazonaws.com -webview-assets.cloud9.us-west-1.amazonaws.com -webview-assets.aws-cloud9.us-west-2.amazonaws.com -vfs.cloud9.us-west-2.amazonaws.com -webview-assets.cloud9.us-west-2.amazonaws.com - -// AWS Elastic Beanstalk -// Submitted by AWS Security -// Reference: bb5a965c-dec3-4967-aa22-e306ad064797 -cn-north-1.eb.amazonaws.com.cn -cn-northwest-1.eb.amazonaws.com.cn -elasticbeanstalk.com -af-south-1.elasticbeanstalk.com -ap-east-1.elasticbeanstalk.com -ap-northeast-1.elasticbeanstalk.com -ap-northeast-2.elasticbeanstalk.com -ap-northeast-3.elasticbeanstalk.com -ap-south-1.elasticbeanstalk.com -ap-southeast-1.elasticbeanstalk.com -ap-southeast-2.elasticbeanstalk.com -ap-southeast-3.elasticbeanstalk.com -ca-central-1.elasticbeanstalk.com -eu-central-1.elasticbeanstalk.com -eu-north-1.elasticbeanstalk.com -eu-south-1.elasticbeanstalk.com -eu-west-1.elasticbeanstalk.com -eu-west-2.elasticbeanstalk.com -eu-west-3.elasticbeanstalk.com -il-central-1.elasticbeanstalk.com -me-south-1.elasticbeanstalk.com -sa-east-1.elasticbeanstalk.com -us-east-1.elasticbeanstalk.com -us-east-2.elasticbeanstalk.com -us-gov-east-1.elasticbeanstalk.com -us-gov-west-1.elasticbeanstalk.com -us-west-1.elasticbeanstalk.com -us-west-2.elasticbeanstalk.com - -// (AWS) Elastic Load Balancing -// Submitted by Luke Wells -// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 -*.elb.amazonaws.com.cn -*.elb.amazonaws.com - -// AWS Global Accelerator -// Submitted by Daniel Massaguer -// Reference: d916759d-a08b-4241-b536-4db887383a6a -awsglobalaccelerator.com - -// AWS re:Post Private -// Submitted by AWS Security -// Reference: 83385945-225f-416e-9aa0-ad0632bfdcee -*.private.repost.aws - -// eero -// Submitted by Yue Kang -// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 -eero.online -eero-stage.online - -// concludes Amazon - -// Amune : https://amune.org/ -// Submitted by Team Amune -t3l3p0rt.net -tele.amune.org - -// Apigee : https://apigee.com/ -// Submitted by Apigee Security Team -apigee.io - -// Apis Networks: https://apisnetworks.com -// Submitted by Matt Saladna -panel.dev - -// Apphud : https://apphud.com -// Submitted by Alexander Selivanov -siiites.com - -// Appspace : https://www.appspace.com -// Submitted by Appspace Security Team -appspacehosted.com -appspaceusercontent.com - -// Appudo UG (haftungsbeschränkt) : https://www.appudo.com -// Submitted by Alexander Hochbaum -appudo.net - -// Aptible : https://www.aptible.com/ -// Submitted by Thomas Orozco -on-aptible.com - -// Aquapal : https://aquapal.net/ -// Submitted by Aki Ueno -f5.si - -// ASEINet : https://www.aseinet.com/ -// Submitted by Asei SEKIGUCHI -user.aseinet.ne.jp -gv.vc -d.gv.vc - -// Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ -// Submitted by Hector Martin -user.party.eus - -// Association potager.org : https://potager.org/ -// Submitted by Lunar -pimienta.org -poivron.org -potager.org -sweetpepper.org - -// ASUSTOR Inc. : http://www.asustor.com -// Submitted by Vincent Tseng -myasustor.com - -// Atlassian : https://atlassian.com -// Submitted by Sam Smyth -cdn.prod.atlassian-dev.net - -// Authentick UG (haftungsbeschränkt) : https://authentick.net -// Submitted by Lukas Reschke -translated.page - -// Autocode : https://autocode.com -// Submitted by Jacob Lee -autocode.dev - -// AVM : https://avm.de -// Submitted by Andreas Weise -myfritz.link -myfritz.net - -// AVStack Pte. Ltd. : https://avstack.io -// Submitted by Jasper Hugo -onavstack.net - -// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com -// Submitted by James Kennedy -*.awdev.ca -*.advisor.ws - -// AZ.pl sp. z.o.o: https://az.pl -// Submitted by Krzysztof Wolski -ecommerce-shop.pl - -// b-data GmbH : https://www.b-data.io -// Submitted by Olivier Benz -b-data.io - -// backplane : https://www.backplane.io -// Submitted by Anthony Voutas -backplaneapp.io - -// Balena : https://www.balena.io -// Submitted by Petros Angelatos -balena-devices.com - -// University of Banja Luka : https://unibl.org -// Domains for Republic of Srpska administrative entity. -// Submitted by Marko Ivanovic -rs.ba - -// Banzai Cloud -// Submitted by Janos Matyas -*.banzai.cloud -app.banzaicloud.io -*.backyards.banzaicloud.io - -// BASE, Inc. : https://binc.jp -// Submitted by Yuya NAGASAWA -base.ec -official.ec -buyshop.jp -fashionstore.jp -handcrafted.jp -kawaiishop.jp -supersale.jp -theshop.jp -shopselect.net -base.shop - -// BeagleBoard.org Foundation : https://beagleboard.org -// Submitted by Jason Kridner -beagleboard.io - -// Beget Ltd -// Submitted by Lev Nekrasov -*.beget.app - -// Besties : https://besties.house -// Submitted by Hazel Cora -pages.gay - -// BetaInABox -// Submitted by Adrian -betainabox.com - -// BinaryLane : http://www.binarylane.com -// Submitted by Nathan O'Sullivan -bnr.la - -// Bitbucket : http://bitbucket.org -// Submitted by Andy Ortlieb -bitbucket.io - -// Blackbaud, Inc. : https://www.blackbaud.com -// Submitted by Paul Crowder -blackbaudcdn.net - -// Blatech : http://www.blatech.net -// Submitted by Luke Bratch -of.je - -// Blue Bite, LLC : https://bluebite.com -// Submitted by Joshua Weiss -bluebite.io - -// Boomla : https://boomla.com -// Submitted by Tibor Halter -boomla.net - -// Boutir : https://www.boutir.com -// Submitted by Eric Ng Ka Ka -boutir.com - -// Boxfuse : https://boxfuse.com -// Submitted by Axel Fontaine -boxfuse.io - -// bplaced : https://www.bplaced.net/ -// Submitted by Miroslav Bozic -square7.ch -bplaced.com -bplaced.de -square7.de -bplaced.net -square7.net - -// Brave : https://brave.com -// Submitted by Andrea Brancaleoni -*.s.brave.io - -// Brendly : https://brendly.rs -// Submitted by Dusan Radovanovic -shop.brendly.rs - -// BrowserSafetyMark -// Submitted by Dave Tharp -browsersafetymark.io - -// Bytemark Hosting : https://www.bytemark.co.uk -// Submitted by Paul Cammish -uk0.bigv.io -dh.bytemark.co.uk -vm.bytemark.co.uk - -// Caf.js Labs LLC : https://www.cafjs.com -// Submitted by Antonio Lain -cafjs.com - -// callidomus : https://www.callidomus.com/ -// Submitted by Marcus Popp -mycd.eu - -// Canva Pty Ltd : https://canva.com/ -// Submitted by Joel Aquilina -canva-apps.cn -*.my.canvasite.cn -canva-apps.com -*.my.canva.site - -// Carrd : https://carrd.co -// Submitted by AJ -drr.ac -uwu.ai -carrd.co -crd.co -ju.mp - -// CentralNic : http://www.centralnic.com/names/domains -// Submitted by registry -ae.org -br.com -cn.com -com.de -com.se -de.com -eu.com -gb.net -hu.net -jp.net -jpn.com -mex.com -ru.com -sa.com -se.net -uk.com -uk.net -us.com -za.bz -za.com - -// No longer operated by CentralNic, these entries should be adopted and/or removed by current operators -// Submitted by Gavin Brown -ar.com -hu.com -kr.com -no.com -qc.com -uy.com - -// Africa.com Web Solutions Ltd : https://registry.africa.com -// Submitted by Gavin Brown -africa.com - -// iDOT Services Limited : http://www.domain.gr.com -// Submitted by Gavin Brown -gr.com - -// Radix FZC : http://domains.in.net -// Submitted by Gavin Brown -in.net -web.in - -// US REGISTRY LLC : http://us.org -// Submitted by Gavin Brown -us.org - -// co.com Registry, LLC : https://registry.co.com -// Submitted by Gavin Brown -co.com - -// Roar Domains LLC : https://roar.basketball/ -// Submitted by Gavin Brown -aus.basketball -nz.basketball - -// BRS Media : https://brsmedia.com/ -// Submitted by Gavin Brown -radio.am -radio.fm - -// c.la : http://www.c.la/ -c.la - -// certmgr.org : https://certmgr.org -// Submitted by B. Blechschmidt -certmgr.org - -// Cityhost LLC : https://cityhost.ua -// Submitted by Maksym Rivtin -cx.ua - -// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ -// Submitted by Rishabh Nambiar & Michael Brown -discourse.group -discourse.team - -// Clever Cloud : https://www.clever-cloud.com/ -// Submitted by Quentin Adam -cleverapps.io - -// Clerk : https://www.clerk.dev -// Submitted by Colin Sidoti -clerk.app -clerkstage.app -*.lcl.dev -*.lclstage.dev -*.stg.dev -*.stgstage.dev - -// ClickRising : https://clickrising.com/ -// Submitted by Umut Gumeli -clickrising.net - -// Cloud66 : https://www.cloud66.com/ -// Submitted by Khash Sajadi -c66.me -cloud66.ws -cloud66.zone - -// CloudAccess.net : https://www.cloudaccess.net/ -// Submitted by Pawel Panek -jdevcloud.com -wpdevcloud.com -cloudaccess.host -freesite.host -cloudaccess.net - -// cloudControl : https://www.cloudcontrol.com/ -// Submitted by Tobias Wilken -cloudcontrolled.com -cloudcontrolapp.com - -// Cloudera, Inc. : https://www.cloudera.com/ -// Submitted by Kedarnath Waikar -*.cloudera.site - -// Cloudflare, Inc. : https://www.cloudflare.com/ -// Submitted by Cloudflare Team -cf-ipfs.com -cloudflare-ipfs.com -trycloudflare.com -pages.dev -r2.dev -workers.dev - -// cloudscale.ch AG : https://www.cloudscale.ch/ -// Submitted by Gaudenz Steinlin -cust.cloudscale.ch -objects.lpg.cloudscale.ch -objects.rma.cloudscale.ch - -// Clovyr : https://clovyr.io -// Submitted by Patrick Nielsen -wnext.app - -// co.ca : http://registry.co.ca/ -co.ca - -// Co & Co : https://co-co.nl/ -// Submitted by Govert Versluis -*.otap.co - -// i-registry s.r.o. : http://www.i-registry.cz/ -// Submitted by Martin Semrad -co.cz - -// CDN77.com : http://www.cdn77.com -// Submitted by Jan Krpes -cdn77-storage.com -rsc.contentproxy9.cz -cdn77-ssl.net -r.cdn77.net -ssl.origin.cdn77-secure.org -c.cdn77.org -rsc.cdn77.org - -// Cloud DNS Ltd : http://www.cloudns.net -// Submitted by Aleksander Hristov & Boyan Peychev -cloudns.asia -cloudns.be -cloudns.biz -cloudns.cc -cloudns.ch -cloudns.cl -cloudns.club -dnsabr.com -cloudns.cx -cloudns.eu -cloudns.in -cloudns.info -dns-cloud.net -dns-dynamic.net -cloudns.nz -cloudns.org -cloudns.ph -cloudns.pro -cloudns.pw -cloudns.us - -// CNPY : https://cnpy.gdn -// Submitted by Angelo Gladding -cnpy.gdn - -// Codeberg e. V. : https://codeberg.org -// Submitted by Moritz Marquardt -codeberg.page - -// CodeSandbox B.V. : https://codesandbox.io -// Submitted by Ives van Hoorne -csb.app -preview.csb.app - -// CoDNS B.V. -co.nl -co.no - -// Combell.com : https://www.combell.com -// Submitted by Thomas Wouters -webhosting.be -hosting-cluster.nl - -// Convex : https://convex.dev/ -// Submitted by James Cowling -convex.site - -// Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ -// Submitted by George Georgievsky -ac.ru -edu.ru -gov.ru -int.ru -mil.ru -test.ru - -// COSIMO GmbH : http://www.cosimo.de -// Submitted by Rene Marticke -dyn.cosidns.de -dynamisches-dns.de -dnsupdater.de -internet-dns.de -l-o-g-i-n.de -dynamic-dns.info -feste-ip.net -knx-server.net -static-access.net - -// cPanel L.L.C. : https://www.cpanel.net/ -// Submitted by Dustin Scherer -*.cprapid.com - -// Craynic, s.r.o. : http://www.craynic.com/ -// Submitted by Ales Krajnik -realm.cz - -// Crisp IM SAS : https://crisp.chat/ -// Submitted by Baptiste Jamin -on.crisp.email - -// Cryptonomic : https://cryptonomic.net/ -// Submitted by Andrew Cady -*.cryptonomic.net - -// Cupcake : https://cupcake.io/ -// Submitted by Jonathan Rudenberg -cupcake.is - -// Curv UG : https://curv-labs.de/ -// Submitted by Marvin Wiesner -curv.dev - -// Customer OCI - Oracle Dyn https://cloud.oracle.com/home https://dyn.com/dns/ -// Submitted by Gregory Drake -// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label -*.customer-oci.com -*.oci.customer-oci.com -*.ocp.customer-oci.com -*.ocs.customer-oci.com - -// Cyclic Software : https://www.cyclic.sh -// Submitted by Kam Lasater -cyclic.app -cyclic.cloud -cyclic-app.com -cyclic.co.in - -// cyon GmbH : https://www.cyon.ch/ -// Submitted by Dominic Luechinger -cyon.link -cyon.site - -// Danger Science Group: https://dangerscience.com/ -// Submitted by Skylar MacDonald -fnwk.site -folionetwork.site -platform0.app - -// Daplie, Inc : https://daplie.com -// Submitted by AJ ONeal -daplie.me -localhost.daplie.me - -// Datto, Inc. : https://www.datto.com/ -// Submitted by Philipp Heckel -dattolocal.com -dattorelay.com -dattoweb.com -mydatto.com -dattolocal.net -mydatto.net - -// Dansk.net : http://www.dansk.net/ -// Submitted by Anani Voule -biz.dk -co.dk -firm.dk -reg.dk -store.dk - -// dappnode.io : https://dappnode.io/ -// Submitted by Abel Boldu / DAppNode Team -dyndns.dappnode.io - -// dapps.earth : https://dapps.earth/ -// Submitted by Daniil Burdakov -*.dapps.earth -*.bzz.dapps.earth - -// Dark, Inc. : https://darklang.com -// Submitted by Paul Biggar -builtwithdark.com -darklang.io - -// DataDetect, LLC. : https://datadetect.com -// Submitted by Andrew Banchich -demo.datadetect.com -instance.datadetect.com - -// Datawire, Inc : https://www.datawire.io -// Submitted by Richard Li -edgestack.me - -// DDNS5 : https://ddns5.com -// Submitted by Cameron Elliott -ddns5.com - -// Debian : https://www.debian.org/ -// Submitted by Peter Palfrader / Debian Sysadmin Team -debian.net - -// Deno Land Inc : https://deno.com/ -// Submitted by Luca Casonato -deno.dev -deno-staging.dev - -// deSEC : https://desec.io/ -// Submitted by Peter Thomassen -dedyn.io - -// Deta: https://www.deta.sh/ -// Submitted by Aavash Shrestha -deta.app -deta.dev - -// Diher Solutions : https://diher.solutions -// Submitted by Didi Hermawan -*.rss.my.id -*.diher.solutions - -// Discord Inc : https://discord.com -// Submitted by Sahn Lam -discordsays.com -discordsez.com - -// DNS Africa Ltd https://dns.business -// Submitted by Calvin Browne -jozi.biz - -// DNShome : https://www.dnshome.de/ -// Submitted by Norbert Auler -dnshome.de - -// DotArai : https://www.dotarai.com/ -// Submitted by Atsadawat Netcharadsang -online.th -shop.th - -// DrayTek Corp. : https://www.draytek.com/ -// Submitted by Paul Fang -drayddns.com - -// DreamCommerce : https://shoper.pl/ -// Submitted by Konrad Kotarba -shoparena.pl - -// DreamHost : http://www.dreamhost.com/ -// Submitted by Andrew Farmer -dreamhosters.com - -// Drobo : http://www.drobo.com/ -// Submitted by Ricardo Padilha -mydrobo.com - -// Drud Holdings, LLC. : https://www.drud.com/ -// Submitted by Kevin Bridges -drud.io -drud.us - -// DuckDNS : http://www.duckdns.org/ -// Submitted by Richard Harper -duckdns.org - -// Bip : https://bip.sh -// Submitted by Joel Kennedy -bip.sh - -// bitbridge.net : Submitted by Craig Welch, abeliidev@gmail.com -bitbridge.net - -// dy.fi : http://dy.fi/ -// Submitted by Heikki Hannikainen -dy.fi -tunk.org - -// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ -dyndns-at-home.com -dyndns-at-work.com -dyndns-blog.com -dyndns-free.com -dyndns-home.com -dyndns-ip.com -dyndns-mail.com -dyndns-office.com -dyndns-pics.com -dyndns-remote.com -dyndns-server.com -dyndns-web.com -dyndns-wiki.com -dyndns-work.com -dyndns.biz -dyndns.info -dyndns.org -dyndns.tv -at-band-camp.net -ath.cx -barrel-of-knowledge.info -barrell-of-knowledge.info -better-than.tv -blogdns.com -blogdns.net -blogdns.org -blogsite.org -boldlygoingnowhere.org -broke-it.net -buyshouses.net -cechire.com -dnsalias.com -dnsalias.net -dnsalias.org -dnsdojo.com -dnsdojo.net -dnsdojo.org -does-it.net -doesntexist.com -doesntexist.org -dontexist.com -dontexist.net -dontexist.org -doomdns.com -doomdns.org -dvrdns.org -dyn-o-saur.com -dynalias.com -dynalias.net -dynalias.org -dynathome.net -dyndns.ws -endofinternet.net -endofinternet.org -endoftheinternet.org -est-a-la-maison.com -est-a-la-masion.com -est-le-patron.com -est-mon-blogueur.com -for-better.biz -for-more.biz -for-our.info -for-some.biz -for-the.biz -forgot.her.name -forgot.his.name -from-ak.com -from-al.com -from-ar.com -from-az.net -from-ca.com -from-co.net -from-ct.com -from-dc.com -from-de.com -from-fl.com -from-ga.com -from-hi.com -from-ia.com -from-id.com -from-il.com -from-in.com -from-ks.com -from-ky.com -from-la.net -from-ma.com -from-md.com -from-me.org -from-mi.com -from-mn.com -from-mo.com -from-ms.com -from-mt.com -from-nc.com -from-nd.com -from-ne.com -from-nh.com -from-nj.com -from-nm.com -from-nv.com -from-ny.net -from-oh.com -from-ok.com -from-or.com -from-pa.com -from-pr.com -from-ri.com -from-sc.com -from-sd.com -from-tn.com -from-tx.com -from-ut.com -from-va.com -from-vt.com -from-wa.com -from-wi.com -from-wv.com -from-wy.com -ftpaccess.cc -fuettertdasnetz.de -game-host.org -game-server.cc -getmyip.com -gets-it.net -go.dyndns.org -gotdns.com -gotdns.org -groks-the.info -groks-this.info -ham-radio-op.net -here-for-more.info -hobby-site.com -hobby-site.org -home.dyndns.org -homedns.org -homeftp.net -homeftp.org -homeip.net -homelinux.com -homelinux.net -homelinux.org -homeunix.com -homeunix.net -homeunix.org -iamallama.com -in-the-band.net -is-a-anarchist.com -is-a-blogger.com -is-a-bookkeeper.com -is-a-bruinsfan.org -is-a-bulls-fan.com -is-a-candidate.org -is-a-caterer.com -is-a-celticsfan.org -is-a-chef.com -is-a-chef.net -is-a-chef.org -is-a-conservative.com -is-a-cpa.com -is-a-cubicle-slave.com -is-a-democrat.com -is-a-designer.com -is-a-doctor.com -is-a-financialadvisor.com -is-a-geek.com -is-a-geek.net -is-a-geek.org -is-a-green.com -is-a-guru.com -is-a-hard-worker.com -is-a-hunter.com -is-a-knight.org -is-a-landscaper.com -is-a-lawyer.com -is-a-liberal.com -is-a-libertarian.com -is-a-linux-user.org -is-a-llama.com -is-a-musician.com -is-a-nascarfan.com -is-a-nurse.com -is-a-painter.com -is-a-patsfan.org -is-a-personaltrainer.com -is-a-photographer.com -is-a-player.com -is-a-republican.com -is-a-rockstar.com -is-a-socialist.com -is-a-soxfan.org -is-a-student.com -is-a-teacher.com -is-a-techie.com -is-a-therapist.com -is-an-accountant.com -is-an-actor.com -is-an-actress.com -is-an-anarchist.com -is-an-artist.com -is-an-engineer.com -is-an-entertainer.com -is-by.us -is-certified.com -is-found.org -is-gone.com -is-into-anime.com -is-into-cars.com -is-into-cartoons.com -is-into-games.com -is-leet.com -is-lost.org -is-not-certified.com -is-saved.org -is-slick.com -is-uberleet.com -is-very-bad.org -is-very-evil.org -is-very-good.org -is-very-nice.org -is-very-sweet.org -is-with-theband.com -isa-geek.com -isa-geek.net -isa-geek.org -isa-hockeynut.com -issmarterthanyou.com -isteingeek.de -istmein.de -kicks-ass.net -kicks-ass.org -knowsitall.info -land-4-sale.us -lebtimnetz.de -leitungsen.de -likes-pie.com -likescandy.com -merseine.nu -mine.nu -misconfused.org -mypets.ws -myphotos.cc -neat-url.com -office-on-the.net -on-the-web.tv -podzone.net -podzone.org -readmyblog.org -saves-the-whales.com -scrapper-site.net -scrapping.cc -selfip.biz -selfip.com -selfip.info -selfip.net -selfip.org -sells-for-less.com -sells-for-u.com -sells-it.net -sellsyourhome.org -servebbs.com -servebbs.net -servebbs.org -serveftp.net -serveftp.org -servegame.org -shacknet.nu -simple-url.com -space-to-rent.com -stuff-4-sale.org -stuff-4-sale.us -teaches-yoga.com -thruhere.net -traeumtgerade.de -webhop.biz -webhop.info -webhop.net -webhop.org -worse-than.tv -writesthisblog.com - -// ddnss.de : https://www.ddnss.de/ -// Submitted by Robert Niedziela -ddnss.de -dyn.ddnss.de -dyndns.ddnss.de -dyndns1.de -dyn-ip24.de -home-webserver.de -dyn.home-webserver.de -myhome-server.de -ddnss.org - -// Definima : http://www.definima.com/ -// Submitted by Maxence Bitterli -definima.net -definima.io - -// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ -// Submitted by Braxton Huggins -ondigitalocean.app - -// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ -// Submitted by Robin H. Johnson -*.digitaloceanspaces.com - -// dnstrace.pro : https://dnstrace.pro/ -// Submitted by Chris Partridge -bci.dnstrace.pro - -// Dynu.com : https://www.dynu.com/ -// Submitted by Sue Ye -ddnsfree.com -ddnsgeek.com -giize.com -gleeze.com -kozow.com -loseyourip.com -ooguy.com -theworkpc.com -casacam.net -dynu.net -accesscam.org -camdvr.org -freeddns.org -mywire.org -webredirect.org -myddns.rocks -blogsite.xyz - -// dynv6 : https://dynv6.com -// Submitted by Dominik Menke -dynv6.net - -// E4YOU spol. s.r.o. : https://e4you.cz/ -// Submitted by Vladimir Dudr -e4.cz - -// Easypanel : https://easypanel.io -// Submitted by Andrei Canta -easypanel.app -easypanel.host - -// EasyWP : https://www.easywp.com -// Submitted by -*.ewp.live - -// Electromagnetic Field : https://www.emfcamp.org -// Submitted by -at.emf.camp - -// Elefunc, Inc. : https://elefunc.com -// Submitted by Cetin Sert -rt.ht - -// Elementor : Elementor Ltd. -// Submitted by Anton Barkan -elementor.cloud -elementor.cool - -// En root‽ : https://en-root.org -// Submitted by Emmanuel Raviart -en-root.fr - -// Enalean SAS: https://www.enalean.com -// Submitted by Thomas Cottier -mytuleap.com -tuleap-partners.com - -// Encoretivity AB: https://encore.dev -// Submitted by André Eriksson -encr.app -encoreapi.com - -// ECG Robotics, Inc: https://ecgrobotics.org -// Submitted by -onred.one -staging.onred.one - -// encoway GmbH : https://www.encoway.de -// Submitted by Marcel Daus -eu.encoway.cloud - -// EU.org https://eu.org/ -// Submitted by Pierre Beyssac -eu.org -al.eu.org -asso.eu.org -at.eu.org -au.eu.org -be.eu.org -bg.eu.org -ca.eu.org -cd.eu.org -ch.eu.org -cn.eu.org -cy.eu.org -cz.eu.org -de.eu.org -dk.eu.org -edu.eu.org -ee.eu.org -es.eu.org -fi.eu.org -fr.eu.org -gr.eu.org -hr.eu.org -hu.eu.org -ie.eu.org -il.eu.org -in.eu.org -int.eu.org -is.eu.org -it.eu.org -jp.eu.org -kr.eu.org -lt.eu.org -lu.eu.org -lv.eu.org -mc.eu.org -me.eu.org -mk.eu.org -mt.eu.org -my.eu.org -net.eu.org -ng.eu.org -nl.eu.org -no.eu.org -nz.eu.org -paris.eu.org -pl.eu.org -pt.eu.org -q-a.eu.org -ro.eu.org -ru.eu.org -se.eu.org -si.eu.org -sk.eu.org -tr.eu.org -uk.eu.org -us.eu.org - -// Eurobyte : https://eurobyte.ru -// Submitted by Evgeniy Subbotin -eurodir.ru - -// Evennode : http://www.evennode.com/ -// Submitted by Michal Kralik -eu-1.evennode.com -eu-2.evennode.com -eu-3.evennode.com -eu-4.evennode.com -us-1.evennode.com -us-2.evennode.com -us-3.evennode.com -us-4.evennode.com - -// eDirect Corp. : https://hosting.url.com.tw/ -// Submitted by C.S. chang -twmail.cc -twmail.net -twmail.org -mymailer.com.tw -url.tw - -// Fabrica Technologies, Inc. : https://www.fabrica.dev/ -// Submitted by Eric Jiang -onfabrica.com - -// FAITID : https://faitid.org/ -// Submitted by Maxim Alzoba -// https://www.flexireg.net/stat_info -ru.net -adygeya.ru -bashkiria.ru -bir.ru -cbg.ru -com.ru -dagestan.ru -grozny.ru -kalmykia.ru -kustanai.ru -marine.ru -mordovia.ru -msk.ru -mytis.ru -nalchik.ru -nov.ru -pyatigorsk.ru -spb.ru -vladikavkaz.ru -vladimir.ru -abkhazia.su -adygeya.su -aktyubinsk.su -arkhangelsk.su -armenia.su -ashgabad.su -azerbaijan.su -balashov.su -bashkiria.su -bryansk.su -bukhara.su -chimkent.su -dagestan.su -east-kazakhstan.su -exnet.su -georgia.su -grozny.su -ivanovo.su -jambyl.su -kalmykia.su -kaluga.su -karacol.su -karaganda.su -karelia.su -khakassia.su -krasnodar.su -kurgan.su -kustanai.su -lenug.su -mangyshlak.su -mordovia.su -msk.su -murmansk.su -nalchik.su -navoi.su -north-kazakhstan.su -nov.su -obninsk.su -penza.su -pokrovsk.su -sochi.su -spb.su -tashkent.su -termez.su -togliatti.su -troitsk.su -tselinograd.su -tula.su -tuva.su -vladikavkaz.su -vladimir.su -vologda.su - -// Fancy Bits, LLC : http://getchannels.com -// Submitted by Aman Gupta -channelsdvr.net -u.channelsdvr.net - -// Fastly Inc. : http://www.fastly.com/ -// Submitted by Fastly Security -edgecompute.app -fastly-edge.com -fastly-terrarium.com -fastlylb.net -map.fastlylb.net -freetls.fastly.net -map.fastly.net -a.prod.fastly.net -global.prod.fastly.net -a.ssl.fastly.net -b.ssl.fastly.net -global.ssl.fastly.net - -// Fastmail : https://www.fastmail.com/ -// Submitted by Marc Bradshaw -*.user.fm - -// FASTVPS EESTI OU : https://fastvps.ru/ -// Submitted by Likhachev Vasiliy -fastvps-server.com -fastvps.host -myfast.host -fastvps.site -myfast.space - -// Fedora : https://fedoraproject.org/ -// submitted by Patrick Uiterwijk -fedorainfracloud.org -fedorapeople.org -cloud.fedoraproject.org -app.os.fedoraproject.org -app.os.stg.fedoraproject.org - -// FearWorks Media Ltd. : https://fearworksmedia.co.uk -// submitted by Keith Fairley -conn.uk -copro.uk -hosp.uk - -// Fermax : https://fermax.com/ -// submitted by Koen Van Isterdael -mydobiss.com - -// FH Muenster : https://www.fh-muenster.de -// Submitted by Robin Naundorf -fh-muenster.io - -// Filegear Inc. : https://www.filegear.com -// Submitted by Jason Zhu -filegear.me -filegear-au.me -filegear-de.me -filegear-gb.me -filegear-ie.me -filegear-jp.me -filegear-sg.me - -// Firebase, Inc. -// Submitted by Chris Raynor -firebaseapp.com - -// Firewebkit : https://www.firewebkit.com -// Submitted by Majid Qureshi -fireweb.app - -// FLAP : https://www.flap.cloud -// Submitted by Louis Chemineau -flap.id - -// FlashDrive : https://flashdrive.io -// Submitted by Eric Chan -onflashdrive.app -fldrv.com - -// FlutterFlow : https://flutterflow.io -// Submitted by Anton Emelyanov -flutterflow.app - -// fly.io: https://fly.io -// Submitted by Kurt Mackey -fly.dev -edgeapp.net -shw.io - -// Flynn : https://flynn.io -// Submitted by Jonathan Rudenberg -flynnhosting.net - -// Forgerock : https://www.forgerock.com -// Submitted by Roderick Parr -forgeblocks.com -id.forgerock.io - -// Framer : https://www.framer.com -// Submitted by Koen Rouwhorst -framer.ai -framer.app -framercanvas.com -framer.media -framer.photos -framer.website -framer.wiki - -// Frusky MEDIA&PR : https://www.frusky.de -// Submitted by Victor Pupynin -*.frusky.de - -// RavPage : https://www.ravpage.co.il -// Submitted by Roni Horowitz -ravpage.co.il - -// Frederik Braun https://frederik-braun.com -// Submitted by Frederik Braun -0e.vc - -// Freebox : http://www.freebox.fr -// Submitted by Romain Fliedel -freebox-os.com -freeboxos.com -fbx-os.fr -fbxos.fr -freebox-os.fr -freeboxos.fr - -// freedesktop.org : https://www.freedesktop.org -// Submitted by Daniel Stone -freedesktop.org - -// freemyip.com : https://freemyip.com -// Submitted by Cadence -freemyip.com - -// FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at -// Submitted by Daniel A. Maierhofer -wien.funkfeuer.at - -// Future Versatile Group. :https://www.fvg-on.net/ -// T.Kabu -daemon.asia -dix.asia -mydns.bz -0am.jp -0g0.jp -0j0.jp -0t0.jp -mydns.jp -pgw.jp -wjg.jp -keyword-on.net -live-on.net -server-on.net -mydns.tw -mydns.vc - -// Futureweb GmbH : https://www.futureweb.at -// Submitted by Andreas Schnederle-Wagner -*.futurecms.at -*.ex.futurecms.at -*.in.futurecms.at -futurehosting.at -futuremailing.at -*.ex.ortsinfo.at -*.kunden.ortsinfo.at -*.statics.cloud - -// GCom Internet : https://www.gcom.net.au -// Submitted by Leo Julius -aliases121.com - -// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names -// Submitted by Stephen Ford -independent-commission.uk -independent-inquest.uk -independent-inquiry.uk -independent-panel.uk -independent-review.uk -public-inquiry.uk -royal-commission.uk -campaign.gov.uk -service.gov.uk - -// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk -// Submitted by Jamie Tanna -api.gov.uk - -// Gehirn Inc. : https://www.gehirn.co.jp/ -// Submitted by Kohei YOSHIDA -gehirn.ne.jp -usercontent.jp - -// Gentlent, Inc. : https://www.gentlent.com -// Submitted by Tom Klein -gentapps.com -gentlentapis.com -lab.ms -cdn-edges.net - -// Getlocalcert: https://www.getlocalcert.net -// Submitted by Robert Alexander -localcert.net -localhostcert.net -corpnet.work - -// Ghost Foundation : https://ghost.org -// Submitted by Matt Hanley -ghost.io - -// GignoSystemJapan: http://gsj.bz -// Submitted by GignoSystemJapan -gsj.bz - -// GitHub, Inc. -// Submitted by Patrick Toomey -githubusercontent.com -githubpreview.dev -github.io - -// GitLab, Inc. -// Submitted by Alex Hanselka -gitlab.io - -// Gitplac.si - https://gitplac.si -// Submitted by Aljaž Starc -gitapp.si -gitpage.si - -// Glitch, Inc : https://glitch.com -// Submitted by Mads Hartmann -glitch.me - -// Global NOG Alliance : https://nogalliance.org/ -// Submitted by Sander Steffann -nog.community - -// Globe Hosting SRL : https://www.globehosting.com/ -// Submitted by Gavin Brown -co.ro -shop.ro - -// GMO Pepabo, Inc. : https://pepabo.com/ -// Submitted by Hosting Div -lolipop.io -angry.jp -babyblue.jp -babymilk.jp -backdrop.jp -bambina.jp -bitter.jp -blush.jp -boo.jp -boy.jp -boyfriend.jp -but.jp -candypop.jp -capoo.jp -catfood.jp -cheap.jp -chicappa.jp -chillout.jp -chips.jp -chowder.jp -chu.jp -ciao.jp -cocotte.jp -coolblog.jp -cranky.jp -cutegirl.jp -daa.jp -deca.jp -deci.jp -digick.jp -egoism.jp -fakefur.jp -fem.jp -flier.jp -floppy.jp -fool.jp -frenchkiss.jp -girlfriend.jp -girly.jp -gloomy.jp -gonna.jp -greater.jp -hacca.jp -heavy.jp -her.jp -hiho.jp -hippy.jp -holy.jp -hungry.jp -icurus.jp -itigo.jp -jellybean.jp -kikirara.jp -kill.jp -kilo.jp -kuron.jp -littlestar.jp -lolipopmc.jp -lolitapunk.jp -lomo.jp -lovepop.jp -lovesick.jp -main.jp -mods.jp -mond.jp -mongolian.jp -moo.jp -namaste.jp -nikita.jp -nobushi.jp -noor.jp -oops.jp -parallel.jp -parasite.jp -pecori.jp -peewee.jp -penne.jp -pepper.jp -perma.jp -pigboat.jp -pinoko.jp -punyu.jp -pupu.jp -pussycat.jp -pya.jp -raindrop.jp -readymade.jp -sadist.jp -schoolbus.jp -secret.jp -staba.jp -stripper.jp -sub.jp -sunnyday.jp -thick.jp -tonkotsu.jp -under.jp -upper.jp -velvet.jp -verse.jp -versus.jp -vivian.jp -watson.jp -weblike.jp -whitesnow.jp -zombie.jp -heteml.net - -// GoDaddy Registry : https://registry.godaddy -// Submitted by Rohan Durrant -graphic.design - -// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ -// Submitted by Tom Whitwell -cloudapps.digital -london.cloudapps.digital - -// GOV.UK Pay : https://www.payments.service.gov.uk/ -// Submitted by Richard Baker -pymnt.uk - -// GlobeHosting, Inc. -// Submitted by Zoltan Egresi -ro.im - -// GoIP DNS Services : http://www.goip.de -// Submitted by Christian Poulter -goip.de - -// Google, Inc. -// Submitted by Eduardo Vela -*.run.app -web.app -*.0emm.com -appspot.com -*.r.appspot.com -codespot.com -googleapis.com -googlecode.com -pagespeedmobilizer.com -publishproxy.com -withgoogle.com -withyoutube.com -*.gateway.dev -cloud.goog -translate.goog -*.usercontent.goog -cloudfunctions.net -blogspot.ae -blogspot.al -blogspot.am -blogspot.ba -blogspot.be -blogspot.bg -blogspot.bj -blogspot.ca -blogspot.cf -blogspot.ch -blogspot.cl -blogspot.co.at -blogspot.co.id -blogspot.co.il -blogspot.co.ke -blogspot.co.nz -blogspot.co.uk -blogspot.co.za -blogspot.com -blogspot.com.ar -blogspot.com.au -blogspot.com.br -blogspot.com.by -blogspot.com.co -blogspot.com.cy -blogspot.com.ee -blogspot.com.eg -blogspot.com.es -blogspot.com.mt -blogspot.com.ng -blogspot.com.tr -blogspot.com.uy -blogspot.cv -blogspot.cz -blogspot.de -blogspot.dk -blogspot.fi -blogspot.fr -blogspot.gr -blogspot.hk -blogspot.hr -blogspot.hu -blogspot.ie -blogspot.in -blogspot.is -blogspot.it -blogspot.jp -blogspot.kr -blogspot.li -blogspot.lt -blogspot.lu -blogspot.md -blogspot.mk -blogspot.mr -blogspot.mx -blogspot.my -blogspot.nl -blogspot.no -blogspot.pe -blogspot.pt -blogspot.qa -blogspot.re -blogspot.ro -blogspot.rs -blogspot.ru -blogspot.se -blogspot.sg -blogspot.si -blogspot.sk -blogspot.sn -blogspot.td -blogspot.tw -blogspot.ug -blogspot.vn - -// Goupile : https://goupile.fr -// Submitted by Niels Martignene -goupile.fr - -// Government of the Netherlands: https://www.government.nl -// Submitted by -gov.nl - -// GrayJay Web Solutions Inc. : https://grayjaysports.ca -// Submitted by Matt Yamkowy -grayjayleagues.com - -// Group 53, LLC : https://www.group53.com -// Submitted by Tyler Todd -awsmppl.com - -// GünstigBestellen : https://günstigbestellen.de -// Submitted by Furkan Akkoc -günstigbestellen.de -günstigliefern.de - -// Hakaran group: http://hakaran.cz -// Submitted by Arseniy Sokolov -fin.ci -free.hr -caa.li -ua.rs -conf.se - -// Handshake : https://handshake.org -// Submitted by Mike Damm -hs.zone -hs.run - -// Hashbang : https://hashbang.sh -hashbang.sh - -// Hasura : https://hasura.io -// Submitted by Shahidh K Muhammed -hasura.app -hasura-app.io - -// Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages): https://www.hs-heilbronn.de -// Submitted by Richard Zowalla -pages.it.hs-heilbronn.de - -// Helio Networks : https://heliohost.org -// Submitted by Ben Frede -helioho.st -heliohost.us - -// Hepforge : https://www.hepforge.org -// Submitted by David Grellscheid -hepforge.org - -// Heroku : https://www.heroku.com/ -// Submitted by Tom Maher -herokuapp.com -herokussl.com - -// Hibernating Rhinos -// Submitted by Oren Eini -ravendb.cloud -ravendb.community -development.run -ravendb.run - -// home.pl S.A.: https://home.pl -// Submitted by Krzysztof Wolski -homesklep.pl - -// Homebase : https://homebase.id/ -// Submitted by Jason Babo -*.kin.one -*.id.pub -*.kin.pub - -// Hong Kong Productivity Council: https://www.hkpc.org/ -// Submitted by SECaaS Team -secaas.hk - -// Hoplix : https://www.hoplix.com -// Submitted by Danilo De Franco -hoplix.shop - - -// HOSTBIP REGISTRY : https://www.hostbip.com/ -// Submitted by Atanunu Igbunuroghene -orx.biz -biz.gl -col.ng -firm.ng -gen.ng -ltd.ng -ngo.ng -edu.scot -sch.so - -// HostFly : https://www.ie.ua -// Submitted by Bohdan Dub -ie.ua - -// HostyHosting (hostyhosting.com) -hostyhosting.io - -// Häkkinen.fi -// Submitted by Eero Häkkinen -häkkinen.fi - -// Ici la Lune : http://www.icilalune.com/ -// Submitted by Simon Morvan -*.moonscale.io -moonscale.net - -// iki.fi -// Submitted by Hannu Aronsson -iki.fi - -// iliad italia: https://www.iliad.it -// Submitted by Marios Makassikis -ibxos.it -iliadboxos.it - -// Impertrix Solutions : -// Submitted by Zhixiang Zhao -impertrixcdn.com -impertrix.com - -// Incsub, LLC: https://incsub.com/ -// Submitted by Aaron Edwards -smushcdn.com -wphostedmail.com -wpmucdn.com -tempurl.host -wpmudev.host - -// Individual Network Berlin e.V. : https://www.in-berlin.de/ -// Submitted by Christian Seitz -dyn-berlin.de -in-berlin.de -in-brb.de -in-butter.de -in-dsl.de -in-dsl.net -in-dsl.org -in-vpn.de -in-vpn.net -in-vpn.org - -// info.at : http://www.info.at/ -biz.at -info.at - -// info.cx : http://info.cx -// Submitted by June Slater -info.cx - -// Interlegis : http://www.interlegis.leg.br -// Submitted by Gabriel Ferreira -ac.leg.br -al.leg.br -am.leg.br -ap.leg.br -ba.leg.br -ce.leg.br -df.leg.br -es.leg.br -go.leg.br -ma.leg.br -mg.leg.br -ms.leg.br -mt.leg.br -pa.leg.br -pb.leg.br -pe.leg.br -pi.leg.br -pr.leg.br -rj.leg.br -rn.leg.br -ro.leg.br -rr.leg.br -rs.leg.br -sc.leg.br -se.leg.br -sp.leg.br -to.leg.br - -// intermetrics GmbH : https://pixolino.com/ -// Submitted by Wolfgang Schwarz -pixolino.com - -// Internet-Pro, LLP: https://netangels.ru/ -// Submitted by Vasiliy Sheredeko -na4u.ru - -// iopsys software solutions AB : https://iopsys.eu/ -// Submitted by Roman Azarenko -iopsys.se - -// IPiFony Systems, Inc. : https://www.ipifony.com/ -// Submitted by Matthew Hardeman -ipifony.net - -// is-a.dev : https://www.is-a.dev -// Submitted by William Harrison -is-a.dev - -// ir.md : https://nic.ir.md -// Submitted by Ali Soizi -ir.md - -// IServ GmbH : https://iserv.de -// Submitted by Mario Hoberg -iservschule.de -mein-iserv.de -schulplattform.de -schulserver.de -test-iserv.de -iserv.dev - -// I-O DATA DEVICE, INC. : http://www.iodata.com/ -// Submitted by Yuji Minagawa -iobb.net - -// Jelastic, Inc. : https://jelastic.com/ -// Submitted by Ihor Kolodyuk -mel.cloudlets.com.au -cloud.interhostsolutions.be -mycloud.by -alp1.ae.flow.ch -appengine.flow.ch -es-1.axarnet.cloud -diadem.cloud -vip.jelastic.cloud -jele.cloud -it1.eur.aruba.jenv-aruba.cloud -it1.jenv-aruba.cloud -keliweb.cloud -cs.keliweb.cloud -oxa.cloud -tn.oxa.cloud -uk.oxa.cloud -primetel.cloud -uk.primetel.cloud -ca.reclaim.cloud -uk.reclaim.cloud -us.reclaim.cloud -ch.trendhosting.cloud -de.trendhosting.cloud -jele.club -amscompute.com -dopaas.com -paas.hosted-by-previder.com -rag-cloud.hosteur.com -rag-cloud-ch.hosteur.com -jcloud.ik-server.com -jcloud-ver-jpc.ik-server.com -demo.jelastic.com -kilatiron.com -paas.massivegrid.com -jed.wafaicloud.com -lon.wafaicloud.com -ryd.wafaicloud.com -j.scaleforce.com.cy -jelastic.dogado.eu -fi.cloudplatform.fi -demo.datacenter.fi -paas.datacenter.fi -jele.host -mircloud.host -paas.beebyte.io -sekd1.beebyteapp.io -jele.io -cloud-fr1.unispace.io -jc.neen.it -cloud.jelastic.open.tim.it -jcloud.kz -upaas.kazteleport.kz -cloudjiffy.net -fra1-de.cloudjiffy.net -west1-us.cloudjiffy.net -jls-sto1.elastx.net -jls-sto2.elastx.net -jls-sto3.elastx.net -faststacks.net -fr-1.paas.massivegrid.net -lon-1.paas.massivegrid.net -lon-2.paas.massivegrid.net -ny-1.paas.massivegrid.net -ny-2.paas.massivegrid.net -sg-1.paas.massivegrid.net -jelastic.saveincloud.net -nordeste-idc.saveincloud.net -j.scaleforce.net -jelastic.tsukaeru.net -sdscloud.pl -unicloud.pl -mircloud.ru -jelastic.regruhosting.ru -enscaled.sg -jele.site -jelastic.team -orangecloud.tn -j.layershift.co.uk -phx.enscaled.us -mircloud.us - -// Jino : https://www.jino.ru -// Submitted by Sergey Ulyashin -myjino.ru -*.hosting.myjino.ru -*.landing.myjino.ru -*.spectrum.myjino.ru -*.vps.myjino.ru - -// Jotelulu S.L. : https://jotelulu.com -// Submitted by Daniel Fariña -jotelulu.cloud - -// Joyent : https://www.joyent.com/ -// Submitted by Brian Bennett -*.triton.zone -*.cns.joyent.com - -// JS.ORG : http://dns.js.org -// Submitted by Stefan Keim -js.org - -// KaasHosting : http://www.kaashosting.nl/ -// Submitted by Wouter Bakker -kaas.gg -khplay.nl - -// Kakao : https://www.kakaocorp.com/ -// Submitted by JaeYoong Lee -ktistory.com - -// Kapsi : https://kapsi.fi -// Submitted by Tomi Juntunen -kapsi.fi - -// Keyweb AG : https://www.keyweb.de -// Submitted by Martin Dannehl -keymachine.de - -// KingHost : https://king.host -// Submitted by Felipe Keller Braz -kinghost.net -uni5.net - -// KnightPoint Systems, LLC : http://www.knightpoint.com/ -// Submitted by Roy Keene -knightpoint.systems - -// KoobinEvent, SL: https://www.koobin.com -// Submitted by Iván Oliva -koobin.events - -// KUROKU LTD : https://kuroku.ltd/ -// Submitted by DisposaBoy -oya.to - -// Katholieke Universiteit Leuven: https://www.kuleuven.be -// Submitted by Abuse KU Leuven -kuleuven.cloud -ezproxy.kuleuven.be - -// .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf -co.krd -edu.krd - -// Krellian Ltd. : https://krellian.com -// Submitted by Ben Francis -krellian.net -webthings.io - -// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de -// Submitted by Lars Laehn -git-repos.de -lcube-server.de -svn-repos.de - -// Leadpages : https://www.leadpages.net -// Submitted by Greg Dallavalle -leadpages.co -lpages.co -lpusercontent.com - -// Lelux.fi : https://lelux.fi/ -// Submitted by Lelux Admin -lelux.site - -// Libre IT Ltd : https://libre.nz -// Submitted by Tomas Maggio -runcontainers.dev - -// Lifetime Hosting : https://Lifetime.Hosting/ -// Submitted by Mike Fillator -co.business -co.education -co.events -co.financial -co.network -co.place -co.technology - -// Lightmaker Property Manager, Inc. : https://app.lmpm.com/ -// Submitted by Greg Holland -app.lmpm.com - -// linkyard ldt: https://www.linkyard.ch/ -// Submitted by Mario Siegenthaler -linkyard.cloud -linkyard-cloud.ch - -// Linode : https://linode.com -// Submitted by -members.linode.com -*.nodebalancer.linode.com -*.linodeobjects.com -ip.linodeusercontent.com - -// LiquidNet Ltd : http://www.liquidnetlimited.com/ -// Submitted by Victor Velchev -we.bs - -// Localcert : https://localcert.dev -// Submitted by Lann Martin -*.user.localcert.dev - -// localzone.xyz -// Submitted by Kenny Niehage -localzone.xyz - -// Log'in Line : https://www.loginline.com/ -// Submitted by Rémi Mach -loginline.app -loginline.dev -loginline.io -loginline.services -loginline.site - -// Lokalized : https://lokalized.nl -// Submitted by Noah Taheij -servers.run - -// Lõhmus Family, The -// Submitted by Heiki Lõhmus -lohmus.me - -// LubMAN UMCS Sp. z o.o : https://lubman.pl/ -// Submitted by Ireneusz Maliszewski -krasnik.pl -leczna.pl -lubartow.pl -lublin.pl -poniatowa.pl -swidnik.pl - -// Lug.org.uk : https://lug.org.uk -// Submitted by Jon Spriggs -glug.org.uk -lug.org.uk -lugs.org.uk - -// Lukanet Ltd : https://lukanet.com -// Submitted by Anton Avramov -barsy.bg -barsy.co.uk -barsyonline.co.uk -barsycenter.com -barsyonline.com -barsy.club -barsy.de -barsy.eu -barsy.in -barsy.info -barsy.io -barsy.me -barsy.menu -barsy.mobi -barsy.net -barsy.online -barsy.org -barsy.pro -barsy.pub -barsy.ro -barsy.shop -barsy.site -barsy.support -barsy.uk - -// Magento Commerce -// Submitted by Damien Tournoud -*.magentosite.cloud - -// May First - People Link : https://mayfirst.org/ -// Submitted by Jamie McClelland -mayfirst.info -mayfirst.org - -// Mail.Ru Group : https://hb.cldmail.ru -// Submitted by Ilya Zaretskiy -hb.cldmail.ru - -// Mail Transfer Platform : https://www.neupeer.com -// Submitted by Li Hui -cn.vu - -// Maze Play: https://www.mazeplay.com -// Submitted by Adam Humpherys -mazeplay.com - -// mcpe.me : https://mcpe.me -// Submitted by Noa Heyl -mcpe.me - -// McHost : https://mchost.ru -// Submitted by Evgeniy Subbotin -mcdir.me -mcdir.ru -mcpre.ru -vps.mcdir.ru - -// Mediatech : https://mediatech.by -// Submitted by Evgeniy Kozhuhovskiy -mediatech.by -mediatech.dev - -// Medicom Health : https://medicomhealth.com -// Submitted by Michael Olson -hra.health - -// Memset hosting : https://www.memset.com -// Submitted by Tom Whitwell -miniserver.com -memset.net - -// Messerli Informatik AG : https://www.messerli.ch/ -// Submitted by Ruben Schmidmeister -messerli.app - -// Meta Platforms, Inc. : https://meta.com/ -// Submitted by Jacob Cordero -atmeta.com -apps.fbsbx.com - -// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ -// Submitted by Zdeněk Šustr -*.cloud.metacentrum.cz -custom.metacentrum.cz - -// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ -// Submitted by Radim Janča -flt.cloud.muni.cz -usr.cloud.muni.cz - -// Meteor Development Group : https://www.meteor.com/hosting -// Submitted by Pierre Carrier -meteorapp.com -eu.meteorapp.com - -// Michau Enterprises Limited : http://www.co.pl/ -co.pl - -// Microsoft Corporation : http://microsoft.com -// Submitted by Public Suffix List Admin -// Managed by Corporate Domains -// Microsoft Azure : https://home.azure -*.azurecontainer.io -cloudapp.azure.com -azure-api.net -azureedge.net -azurefd.net -azurewebsites.net -azure-mobile.net -azurestaticapps.net -1.azurestaticapps.net -2.azurestaticapps.net -3.azurestaticapps.net -4.azurestaticapps.net -5.azurestaticapps.net -6.azurestaticapps.net -7.azurestaticapps.net -centralus.azurestaticapps.net -eastasia.azurestaticapps.net -eastus2.azurestaticapps.net -westeurope.azurestaticapps.net -westus2.azurestaticapps.net -cloudapp.net -trafficmanager.net -blob.core.windows.net -servicebus.windows.net - -// minion.systems : http://minion.systems -// Submitted by Robert Böttinger -csx.cc - -// Mintere : https://mintere.com/ -// Submitted by Ben Aubin -mintere.site - -// MobileEducation, LLC : https://joinforte.com -// Submitted by Grayson Martin -forte.id - -// MODX Systems LLC : https://modx.com -// Submitted by Elizabeth Southwell -modx.dev - -// Mozilla Corporation : https://mozilla.com -// Submitted by Ben Francis -mozilla-iot.org - -// Mozilla Foundation : https://mozilla.org/ -// Submitted by glob -bmoattachments.org - -// MSK-IX : https://www.msk-ix.ru/ -// Submitted by Khannanov Roman -net.ru -org.ru -pp.ru - -// Mythic Beasts : https://www.mythic-beasts.com -// Submitted by Paul Cammish -hostedpi.com -customer.mythic-beasts.com -caracal.mythic-beasts.com -fentiger.mythic-beasts.com -lynx.mythic-beasts.com -ocelot.mythic-beasts.com -oncilla.mythic-beasts.com -onza.mythic-beasts.com -sphinx.mythic-beasts.com -vs.mythic-beasts.com -x.mythic-beasts.com -yali.mythic-beasts.com -cust.retrosnub.co.uk - -// Nabu Casa : https://www.nabucasa.com -// Submitted by Paulus Schoutsen -ui.nabu.casa - -// Net at Work Gmbh : https://www.netatwork.de -// Submitted by Jan Jaeschke -cloud.nospamproxy.com - -// Netlify : https://www.netlify.com -// Submitted by Jessica Parsons -netlify.app - -// Neustar Inc. -// Submitted by Trung Tran -4u.com - -// ngrok : https://ngrok.com/ -// Submitted by Alan Shreve -ngrok.app -ngrok-free.app -ngrok.dev -ngrok-free.dev -ngrok.io -ap.ngrok.io -au.ngrok.io -eu.ngrok.io -in.ngrok.io -jp.ngrok.io -sa.ngrok.io -us.ngrok.io -ngrok.pizza -ngrok.pro - -// Nicolaus Copernicus University in Torun - MSK TORMAN (https://www.man.torun.pl) -torun.pl - -// Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ -// Submitted by Nicholas Ford -nh-serv.co.uk -nimsite.uk - -// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ -// Submitted by Jeff Wheelhouse -nfshost.com - -// NFT.Storage : https://nft.storage/ -// Submitted by Vasco Santos or -ipfs.nftstorage.link - -// Noop : https://noop.app -// Submitted by Nathaniel Schweinberg -*.developer.app -noop.app - -// Northflank Ltd. : https://northflank.com/ -// Submitted by Marco Suter -*.northflank.app -*.build.run -*.code.run -*.database.run -*.migration.run - -// Noticeable : https://noticeable.io -// Submitted by Laurent Pellegrino -noticeable.news - -// Now-DNS : https://now-dns.com -// Submitted by Steve Russell -dnsking.ch -mypi.co -n4t.co -001www.com -ddnslive.com -myiphost.com -forumz.info -16-b.it -32-b.it -64-b.it -soundcast.me -tcp4.me -dnsup.net -hicam.net -now-dns.net -ownip.net -vpndns.net -dynserv.org -now-dns.org -x443.pw -now-dns.top -ntdll.top -freeddns.us -crafting.xyz -zapto.xyz - -// nsupdate.info : https://www.nsupdate.info/ -// Submitted by Thomas Waldmann -nsupdate.info -nerdpol.ovh - -// No-IP.com : https://noip.com/ -// Submitted by Deven Reza -blogsyte.com -brasilia.me -cable-modem.org -ciscofreak.com -collegefan.org -couchpotatofries.org -damnserver.com -ddns.me -ditchyourip.com -dnsfor.me -dnsiskinky.com -dvrcam.info -dynns.com -eating-organic.net -fantasyleague.cc -geekgalaxy.com -golffan.us -health-carereform.com -homesecuritymac.com -homesecuritypc.com -hopto.me -ilovecollege.info -loginto.me -mlbfan.org -mmafan.biz -myactivedirectory.com -mydissent.net -myeffect.net -mymediapc.net -mypsx.net -mysecuritycamera.com -mysecuritycamera.net -mysecuritycamera.org -net-freaks.com -nflfan.org -nhlfan.net -no-ip.ca -no-ip.co.uk -no-ip.net -noip.us -onthewifi.com -pgafan.net -point2this.com -pointto.us -privatizehealthinsurance.net -quicksytes.com -read-books.org -securitytactics.com -serveexchange.com -servehumour.com -servep2p.com -servesarcasm.com -stufftoread.com -ufcfan.org -unusualperson.com -workisboring.com -3utilities.com -bounceme.net -ddns.net -ddnsking.com -gotdns.ch -hopto.org -myftp.biz -myftp.org -myvnc.com -no-ip.biz -no-ip.info -no-ip.org -noip.me -redirectme.net -servebeer.com -serveblog.net -servecounterstrike.com -serveftp.com -servegame.com -servehalflife.com -servehttp.com -serveirc.com -serveminecraft.net -servemp3.com -servepics.com -servequake.com -sytes.net -webhop.me -zapto.org - -// NodeArt : https://nodeart.io -// Submitted by Konstantin Nosov -stage.nodeart.io - -// Nucleos Inc. : https://nucleos.com -// Submitted by Piotr Zduniak -pcloud.host - -// NYC.mn : http://www.information.nyc.mn -// Submitted by Matthew Brown -nyc.mn - -// Observable, Inc. : https://observablehq.com -// Submitted by Mike Bostock -static.observableusercontent.com - -// Octopodal Solutions, LLC. : https://ulterius.io/ -// Submitted by Andrew Sampson -cya.gg - -// OMG.LOL : -// Submitted by Adam Newbold -omg.lol - -// Omnibond Systems, LLC. : https://www.omnibond.com -// Submitted by Cole Estep -cloudycluster.net - -// OmniWe Limited: https://omniwe.com -// Submitted by Vicary Archangel -omniwe.site - -// One.com: https://www.one.com/ -// Submitted by Jacob Bunk Nielsen -123hjemmeside.dk -123hjemmeside.no -123homepage.it -123kotisivu.fi -123minsida.se -123miweb.es -123paginaweb.pt -123siteweb.fr -123webseite.at -123webseite.de -123website.be -123website.ch -123website.lu -123website.nl -service.one -simplesite.com -simplesite.com.br -simplesite.gr -simplesite.pl - -// One Fold Media : http://www.onefoldmedia.com/ -// Submitted by Eddie Jones -nid.io - -// Open Domains : https://open-domains.net -// Submitted by William Harrison -is-cool.dev -is-not-a.dev -localplayer.dev -is-local.org - -// Open Social : https://www.getopensocial.com/ -// Submitted by Alexander Varwijk -opensocial.site - -// OpenCraft GmbH : http://opencraft.com/ -// Submitted by Sven Marnach -opencraft.hosting - -// OpenResearch GmbH: https://openresearch.com/ -// Submitted by Philipp Schmid -orsites.com - -// Opera Software, A.S.A. -// Submitted by Yngve Pettersen -operaunite.com - -// Orange : https://www.orange.com -// Submitted by Alexandre Linte -tech.orange - -// OsSav Technology Ltd. : https://ossav.com/ -// TLD Nic: http://nic.can.re - TLD Whois Server: whois.can.re -// Submitted by OsSav Technology Ltd. -can.re - -// Oursky Limited : https://authgear.com/, https://skygear.io/ -// Submitted by Authgear Team , Skygear Developer -authgear-staging.com -authgearapps.com -skygearapp.com - -// OutSystems -// Submitted by Duarte Santos -outsystemscloud.com - -// OVHcloud: https://ovhcloud.com -// Submitted by Vincent Cassé -*.webpaas.ovh.net -*.hosting.ovh.net - -// OwnProvider GmbH: http://www.ownprovider.com -// Submitted by Jan Moennich -ownprovider.com -own.pm - -// OwO : https://whats-th.is/ -// Submitted by Dean Sheather -*.owo.codes - -// OX : http://www.ox.rs -// Submitted by Adam Grand -ox.rs - -// oy.lc -// Submitted by Charly Coste -oy.lc - -// Pagefog : https://pagefog.com/ -// Submitted by Derek Myers -pgfog.com - -// Pagefront : https://www.pagefronthq.com/ -// Submitted by Jason Kriss -pagefrontapp.com - -// PageXL : https://pagexl.com -// Submitted by Yann Guichard -pagexl.com - -// Paywhirl, Inc : https://paywhirl.com/ -// Submitted by Daniel Netzer -*.paywhirl.com - -// pcarrier.ca Software Inc: https://pcarrier.ca/ -// Submitted by Pierre Carrier -*.xmit.co -bar0.net -bar1.net -bar2.net -rdv.to -srv.us -gh.srv.us -gl.srv.us - -// .pl domains (grandfathered) -art.pl -gliwice.pl -krakow.pl -poznan.pl -wroc.pl -zakopane.pl - -// Pantheon Systems, Inc. : https://pantheon.io/ -// Submitted by Gary Dylina -pantheonsite.io -gotpantheon.com - -// Peplink | Pepwave : http://peplink.com/ -// Submitted by Steve Leung -mypep.link - -// Perspecta : https://perspecta.com/ -// Submitted by Kenneth Van Alstyne -perspecta.cloud - -// PE Ulyanov Kirill Sergeevich : https://airy.host -// Submitted by Kirill Ulyanov -lk3.ru - -// Planet-Work : https://www.planet-work.com/ -// Submitted by Frédéric VANNIÈRE -on-web.fr - -// Platform.sh : https://platform.sh -// Submitted by Nikola Kotur -*.upsun.app -upsunapp.com -ent.platform.sh -eu.platform.sh -us.platform.sh -*.platformsh.site -*.tst.site - -// Platter: https://platter.dev -// Submitted by Patrick Flor -platter-app.com -platter-app.dev -platterp.us - -// Plesk : https://www.plesk.com/ -// Submitted by Anton Akhtyamov -pdns.page -plesk.page -pleskns.com - -// Pley AB : https://www.pley.com/ -// Submitted by Henning Pohl -pley.games - -// Port53 : https://port53.io/ -// Submitted by Maximilian Schieder -dyn53.io - -// Porter : https://porter.run/ -// Submitted by Rudraksh MK -onporter.run - -// Positive Codes Technology Company : http://co.bn/faq.html -// Submitted by Zulfais -co.bn - -// Postman, Inc : https://postman.com -// Submitted by Rahul Dhawan -postman-echo.com -pstmn.io -mock.pstmn.io -httpbin.org - -//prequalifyme.today : https://prequalifyme.today -//Submitted by DeepakTiwari deepak@ivylead.io -prequalifyme.today - -// prgmr.com : https://prgmr.com/ -// Submitted by Sarah Newman -xen.prgmr.com - -// priv.at : http://www.nic.priv.at/ -// Submitted by registry -priv.at - -// privacytools.io : https://www.privacytools.io/ -// Submitted by Jonah Aragon -prvcy.page - -// Protocol Labs : https://protocol.ai/ -// Submitted by Michael Burns -*.dweb.link - -// Protonet GmbH : http://protonet.io -// Submitted by Martin Meier -protonet.io - -// Publication Presse Communication SARL : https://ppcom.fr -// Submitted by Yaacov Akiba Slama -chirurgiens-dentistes-en-france.fr -byen.site - -// pubtls.org: https://www.pubtls.org -// Submitted by Kor Nielsen -pubtls.org - -// PythonAnywhere LLP: https://www.pythonanywhere.com -// Submitted by Giles Thomas -pythonanywhere.com -eu.pythonanywhere.com - -// QOTO, Org. -// Submitted by Jeffrey Phillips Freeman -qoto.io - -// Qualifio : https://qualifio.com/ -// Submitted by Xavier De Cock -qualifioapp.com - -// Quality Unit: https://qualityunit.com -// Submitted by Vasyl Tsalko -ladesk.com - -// QuickBackend: https://www.quickbackend.com -// Submitted by Dani Biro -qbuser.com - -// Rad Web Hosting: https://radwebhosting.com -// Submitted by Scott Claeys -cloudsite.builders -myradweb.net -servername.us - -// Redgate Software: https://red-gate.com -// Submitted by Andrew Farries -instances.spawn.cc - -// Redstar Consultants : https://www.redstarconsultants.com/ -// Submitted by Jons Slemmer -instantcloud.cn - -// Russian Academy of Sciences -// Submitted by Tech Support -ras.ru - -// QA2 -// Submitted by Daniel Dent (https://www.danieldent.com/) -qa2.com - -// QCX -// Submitted by Cassandra Beelen -qcx.io -*.sys.qcx.io - -// QNAP System Inc : https://www.qnap.com -// Submitted by Nick Chang -dev-myqnapcloud.com -alpha-myqnapcloud.com -myqnapcloud.com - -// Quip : https://quip.com -// Submitted by Patrick Linehan -*.quipelements.com - -// Qutheory LLC : http://qutheory.io -// Submitted by Jonas Schwartz -vapor.cloud -vaporcloud.io - -// Rackmaze LLC : https://www.rackmaze.com -// Submitted by Kirill Pertsev -rackmaze.com -rackmaze.net - -// Rakuten Games, Inc : https://dev.viberplay.io -// Submitted by Joshua Zhang -g.vbrplsbx.io - -// Rancher Labs, Inc : https://rancher.com -// Submitted by Vincent Fiduccia -*.on-k3s.io -*.on-rancher.cloud -*.on-rio.io - -// Read The Docs, Inc : https://www.readthedocs.org -// Submitted by David Fischer -readthedocs.io - -// Red Hat, Inc. OpenShift : https://openshift.redhat.com/ -// Submitted by Tim Kramer -rhcloud.com - -// Render : https://render.com -// Submitted by Anurag Goel -app.render.com -onrender.com - -// Repl.it : https://repl.it -// Submitted by Lincoln Bergeson -replit.app -id.replit.app -firewalledreplit.co -id.firewalledreplit.co -repl.co -id.repl.co -replit.dev -archer.replit.dev -bones.replit.dev -canary.replit.dev -global.replit.dev -hacker.replit.dev -id.replit.dev -janeway.replit.dev -kim.replit.dev -kira.replit.dev -kirk.replit.dev -odo.replit.dev -paris.replit.dev -picard.replit.dev -pike.replit.dev -prerelease.replit.dev -reed.replit.dev -riker.replit.dev -sisko.replit.dev -spock.replit.dev -staging.replit.dev -sulu.replit.dev -tarpit.replit.dev -teams.replit.dev -tucker.replit.dev -wesley.replit.dev -worf.replit.dev -repl.run - -// Resin.io : https://resin.io -// Submitted by Tim Perry -resindevice.io -devices.resinstaging.io - -// RethinkDB : https://www.rethinkdb.com/ -// Submitted by Chris Kastorff -hzc.io - -// Revitalised Limited : http://www.revitalised.co.uk -// Submitted by Jack Price -wellbeingzone.eu -wellbeingzone.co.uk - -// Rico Developments Limited : https://adimo.co -// Submitted by Colin Brown -adimo.co.uk - -// Riseup Networks : https://riseup.net -// Submitted by Micah Anderson -itcouldbewor.se - -// Rochester Institute of Technology : http://www.rit.edu/ -// Submitted by Jennifer Herting -git-pages.rit.edu - -// Rocky Enterprise Software Foundation : https://resf.org -// Submitted by Neil Hanlon -rocky.page - -// Rusnames Limited: http://rusnames.ru/ -// Submitted by Sergey Zotov -биз.рус -ком.рус -крым.рус -мир.рус -мск.рус -орг.рус -самара.рус -сочи.рус -спб.рус -я.рус - -// SAKURA Internet Inc. : https://www.sakura.ad.jp/ -// Submitted by Internet Service Department -180r.com -dojin.com -sakuratan.com -sakuraweb.com -x0.com -2-d.jp -bona.jp -crap.jp -daynight.jp -eek.jp -flop.jp -halfmoon.jp -jeez.jp -matrix.jp -mimoza.jp -ivory.ne.jp -mail-box.ne.jp -mints.ne.jp -mokuren.ne.jp -opal.ne.jp -sakura.ne.jp -sumomo.ne.jp -topaz.ne.jp -netgamers.jp -nyanta.jp -o0o0.jp -rdy.jp -rgr.jp -rulez.jp -s3.isk01.sakurastorage.jp -s3.isk02.sakurastorage.jp -saloon.jp -sblo.jp -skr.jp -tank.jp -uh-oh.jp -undo.jp -rs.webaccel.jp -user.webaccel.jp -websozai.jp -xii.jp -squares.net -jpn.org -kirara.st -x0.to -from.tv -sakura.tv - -// Salesforce.com, Inc. https://salesforce.com/ -// Submitted by Michael Biven and Aaron Romeo -*.builder.code.com -*.dev-builder.code.com -*.stg-builder.code.com -*.001.test.code-builder-stg.platform.salesforce.com - -// Sandstorm Development Group, Inc. : https://sandcats.io/ -// Submitted by Asheesh Laroia -sandcats.io - -// SBE network solutions GmbH : https://www.sbe.de/ -// Submitted by Norman Meilick -logoip.de -logoip.com - -// Scaleway : https://www.scaleway.com/ -// Submitted by Rémy Léone -fr-par-1.baremetal.scw.cloud -fr-par-2.baremetal.scw.cloud -nl-ams-1.baremetal.scw.cloud -cockpit.fr-par.scw.cloud -fnc.fr-par.scw.cloud -functions.fnc.fr-par.scw.cloud -k8s.fr-par.scw.cloud -nodes.k8s.fr-par.scw.cloud -s3.fr-par.scw.cloud -s3-website.fr-par.scw.cloud -whm.fr-par.scw.cloud -priv.instances.scw.cloud -pub.instances.scw.cloud -k8s.scw.cloud -cockpit.nl-ams.scw.cloud -k8s.nl-ams.scw.cloud -nodes.k8s.nl-ams.scw.cloud -s3.nl-ams.scw.cloud -s3-website.nl-ams.scw.cloud -whm.nl-ams.scw.cloud -cockpit.pl-waw.scw.cloud -k8s.pl-waw.scw.cloud -nodes.k8s.pl-waw.scw.cloud -s3.pl-waw.scw.cloud -s3-website.pl-waw.scw.cloud -scalebook.scw.cloud -smartlabeling.scw.cloud -dedibox.fr - -// schokokeks.org GbR : https://schokokeks.org/ -// Submitted by Hanno Böck -schokokeks.net - -// Scottish Government: https://www.gov.scot -// Submitted by Martin Ellis -gov.scot -service.gov.scot - -// Scry Security : http://www.scrysec.com -// Submitted by Shante Adam -scrysec.com - -// Scrypted : https://scrypted.app -// Submitted by Koushik Dutta -client.scrypted.io - -// Securepoint GmbH : https://www.securepoint.de -// Submitted by Erik Anders -firewall-gateway.com -firewall-gateway.de -my-gateway.de -my-router.de -spdns.de -spdns.eu -firewall-gateway.net -my-firewall.org -myfirewall.org -spdns.org - -// Seidat : https://www.seidat.com -// Submitted by Artem Kondratev -seidat.net - -// Sellfy : https://sellfy.com -// Submitted by Yuriy Romadin -sellfy.store - -// Senseering GmbH : https://www.senseering.de -// Submitted by Felix Mönckemeyer -senseering.net - -// Sendmsg: https://www.sendmsg.co.il -// Submitted by Assaf Stern -minisite.ms - -// Service Magnet : https://myservicemagnet.com -// Submitted by Dave Sanders -magnet.page - -// Service Online LLC : http://drs.ua/ -// Submitted by Serhii Bulakh -biz.ua -co.ua -pp.ua - -// Shift Crypto AG : https://shiftcrypto.ch -// Submitted by alex -shiftcrypto.dev -shiftcrypto.io - -// ShiftEdit : https://shiftedit.net/ -// Submitted by Adam Jimenez -shiftedit.io - -// Shopblocks : http://www.shopblocks.com/ -// Submitted by Alex Bowers -myshopblocks.com - -// Shopify : https://www.shopify.com -// Submitted by Alex Richter -myshopify.com - -// Shopit : https://www.shopitcommerce.com/ -// Submitted by Craig McMahon -shopitsite.com - -// shopware AG : https://shopware.com -// Submitted by Jens Küper -shopware.store - -// Siemens Mobility GmbH -// Submitted by Oliver Graebner -mo-siemens.io - -// SinaAppEngine : http://sae.sina.com.cn/ -// Submitted by SinaAppEngine -1kapp.com -appchizi.com -applinzi.com -sinaapp.com -vipsinaapp.com - -// Siteleaf : https://www.siteleaf.com/ -// Submitted by Skylar Challand -siteleaf.net - -// Skyhat : http://www.skyhat.io -// Submitted by Shante Adam -bounty-full.com -alpha.bounty-full.com -beta.bounty-full.com - -// Smallregistry by Promopixel SARL: https://www.smallregistry.net -// Former AFNIC's SLDs -// Submitted by Jérôme Lipowicz -aeroport.fr -avocat.fr -chambagri.fr -chirurgiens-dentistes.fr -experts-comptables.fr -medecin.fr -notaires.fr -pharmacien.fr -port.fr -veterinaire.fr - -// Small Technology Foundation : https://small-tech.org -// Submitted by Aral Balkan -small-web.org - -// Smoove.io : https://www.smoove.io/ -// Submitted by Dan Kozak -vp4.me - -// Snowflake Inc : https://www.snowflake.com/ -// Submitted by Sam Haar -*.snowflake.app -*.privatelink.snowflake.app -streamlit.app -streamlitapp.com - -// Snowplow Analytics : https://snowplowanalytics.com/ -// Submitted by Ian Streeter -try-snowplow.com - -// SourceHut : https://sourcehut.org -// Submitted by Drew DeVault -srht.site - -// StackBlitz : https://stackblitz.com -// Submitted by Dominic Elm -w-corp-staticblitz.com -w-credentialless-staticblitz.com -w-staticblitz.com - -// Stackhero : https://www.stackhero.io -// Submitted by Adrien Gillon -stackhero-network.com - -// STACKIT : https://www.stackit.de/en/ -// Submitted by STACKIT-DNS Team (Simon Stier) -runs.onstackit.cloud -stackit.gg -stackit.rocks -stackit.run -stackit.zone - -// Staclar : https://staclar.com -// Submitted by Q Misell -musician.io -// Submitted by Matthias Merkel -novecore.site - -// staticland : https://static.land -// Submitted by Seth Vincent -static.land -dev.static.land -sites.static.land - -// Storebase : https://www.storebase.io -// Submitted by Tony Schirmer -storebase.store - -// Strategic System Consulting (eApps Hosting): https://www.eapps.com/ -// Submitted by Alex Oancea -vps-host.net -atl.jelastic.vps-host.net -njs.jelastic.vps-host.net -ric.jelastic.vps-host.net - -// Sony Interactive Entertainment LLC : https://sie.com/ -// Submitted by David Coles -playstation-cloud.com - -// SourceLair PC : https://www.sourcelair.com -// Submitted by Antonis Kalipetis -apps.lair.io -*.stolos.io - -// SpaceKit : https://www.spacekit.io/ -// Submitted by Reza Akhavan -spacekit.io - -// SpeedPartner GmbH: https://www.speedpartner.de/ -// Submitted by Stefan Neufeind -customer.speedpartner.de - -// Spreadshop (sprd.net AG) : https://www.spreadshop.com/ -// Submitted by Martin Breest -myspreadshop.at -myspreadshop.com.au -myspreadshop.be -myspreadshop.ca -myspreadshop.ch -myspreadshop.com -myspreadshop.de -myspreadshop.dk -myspreadshop.es -myspreadshop.fi -myspreadshop.fr -myspreadshop.ie -myspreadshop.it -myspreadshop.net -myspreadshop.nl -myspreadshop.no -myspreadshop.pl -myspreadshop.se -myspreadshop.co.uk - -// Standard Library : https://stdlib.com -// Submitted by Jacob Lee -api.stdlib.com - -// stereosense GmbH : https://www.involve.me -// Submitted by Florian Burmann -feedback.ac -forms.ac -assessments.cx -calculators.cx -funnels.cx -paynow.cx -quizzes.cx -researched.cx -tests.cx -surveys.so - -// Storipress : https://storipress.com -// Submitted by Benno Liu -storipress.app - -// Storj Labs Inc. : https://storj.io/ -// Submitted by Philip Hutchins -storj.farm - -// Streak : https://streak.com -// Submitted by Blake Kadatz -streak-link.com -streaklinks.com -streakusercontent.com - -// Studenten Net Twente : http://www.snt.utwente.nl/ -// Submitted by Silke Hofstra -utwente.io - -// Student-Run Computing Facility : https://www.srcf.net/ -// Submitted by Edwin Balani -soc.srcf.net -user.srcf.net - -// Sub 6 Limited: http://www.sub6.com -// Submitted by Dan Miller -temp-dns.com - -// Supabase : https://supabase.io -// Submitted by Inian Parameshwaran -supabase.co -supabase.in -supabase.net -su.paba.se - -// Symfony, SAS : https://symfony.com/ -// Submitted by Fabien Potencier -*.s5y.io -*.sensiosite.cloud - -// Syncloud : https://syncloud.org -// Submitted by Boris Rybalkin -syncloud.it - -// Synology, Inc. : https://www.synology.com/ -// Submitted by Rony Weng -dscloud.biz -direct.quickconnect.cn -dsmynas.com -familyds.com -diskstation.me -dscloud.me -i234.me -myds.me -synology.me -dscloud.mobi -dsmynas.net -familyds.net -dsmynas.org -familyds.org -vpnplus.to -direct.quickconnect.to - -// Tabit Technologies Ltd. : https://tabit.cloud/ -// Submitted by Oren Agiv -tabitorder.co.il -mytabit.co.il -mytabit.com - -// TAIFUN Software AG : http://taifun-software.de -// Submitted by Bjoern Henke -taifun-dns.de - -// Tailscale Inc. : https://www.tailscale.com -// Submitted by David Anderson -beta.tailscale.net -ts.net -*.c.ts.net - -// TASK geographical domains (www.task.gda.pl/uslugi/dns) -gda.pl -gdansk.pl -gdynia.pl -med.pl -sopot.pl - -// team.blue https://team.blue -// Submitted by Cedric Dubois -site.tb-hosting.com - -// Teckids e.V. : https://www.teckids.org -// Submitted by Dominik George -edugit.io -s3.teckids.org - -// Telebit : https://telebit.cloud -// Submitted by AJ ONeal -telebit.app -telebit.io -*.telebit.xyz - -// Thingdust AG : https://thingdust.com/ -// Submitted by Adrian Imboden -*.firenet.ch -*.svc.firenet.ch -reservd.com -thingdustdata.com -cust.dev.thingdust.io -cust.disrec.thingdust.io -cust.prod.thingdust.io -cust.testing.thingdust.io -reservd.dev.thingdust.io -reservd.disrec.thingdust.io -reservd.testing.thingdust.io - -// ticket i/O GmbH : https://ticket.io -// Submitted by Christian Franke -tickets.io - -// Tlon.io : https://tlon.io -// Submitted by Mark Staarink -arvo.network -azimuth.network -tlon.network - -// Tor Project, Inc. : https://torproject.org -// Submitted by Antoine Beaupré -bloxcms.com -townnews-staging.com - -// TrafficPlex GmbH : https://www.trafficplex.de/ -// Submitted by Phillipp Röll -12hp.at -2ix.at -4lima.at -lima-city.at -12hp.ch -2ix.ch -4lima.ch -lima-city.ch -trafficplex.cloud -de.cool -12hp.de -2ix.de -4lima.de -lima-city.de -1337.pictures -clan.rip -lima-city.rocks -webspace.rocks -lima.zone - -// TransIP : https://www.transip.nl -// Submitted by Rory Breuk -*.transurl.be -*.transurl.eu -*.transurl.nl - -// TransIP: https://www.transip.nl -// Submitted by Cedric Dubois -site.transip.me - -// TuxFamily : http://tuxfamily.org -// Submitted by TuxFamily administrators -tuxfamily.org - -// TwoDNS : https://www.twodns.de/ -// Submitted by TwoDNS-Support -dd-dns.de -diskstation.eu -diskstation.org -dray-dns.de -draydns.de -dyn-vpn.de -dynvpn.de -mein-vigor.de -my-vigor.de -my-wan.de -syno-ds.de -synology-diskstation.de -synology-ds.de - -// Typedream : https://typedream.com -// Submitted by Putri Karunia -typedream.app - -// Typeform : https://www.typeform.com -// Submitted by Sergi Ferriz -pro.typeform.com - -// Uberspace : https://uberspace.de -// Submitted by Moritz Werner -uber.space -*.uberspace.de - -// UDR Limited : http://www.udr.hk.com -// Submitted by registry -hk.com -hk.org -ltd.hk -inc.hk - -// UK Intis Telecom LTD : https://it.com -// Submitted by ITComdomains -it.com - -// Unison Computing, PBC : https://unison.cloud -// Submitted by Simon Højberg -unison-services.cloud - -// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ -// see also: whois -h whois.udr.org.yt help -// Submitted by Atanunu Igbunuroghene -name.pm -sch.tf -biz.wf -sch.wf -org.yt - -// United Gameserver GmbH : https://united-gameserver.de -// Submitted by Stefan Schwarz -virtualuser.de -virtual-user.de - -// Upli : https://upli.io -// Submitted by Lenny Bakkalian -upli.io - -// urown.net : https://urown.net -// Submitted by Hostmaster -urown.cloud -dnsupdate.info - -// .US -// Submitted by Ed Moore -lib.de.us - -// VeryPositive SIA : http://very.lv -// Submitted by Danko Aleksejevs -2038.io - -// Vercel, Inc : https://vercel.com/ -// Submitted by Connor Davis -vercel.app -vercel.dev -now.sh - -// Viprinet Europe GmbH : http://www.viprinet.com -// Submitted by Simon Kissel -router.management - -// Virtual-Info : https://www.virtual-info.info/ -// Submitted by Adnan RIHAN -v-info.info - -// Voorloper.com: https://voorloper.com -// Submitted by Nathan van Bakel -voorloper.cloud - -// Voxel.sh DNS : https://voxel.sh/dns/ -// Submitted by Mia Rehlinger -neko.am -nyaa.am -be.ax -cat.ax -es.ax -eu.ax -gg.ax -mc.ax -us.ax -xy.ax -nl.ci -xx.gl -app.gp -blog.gt -de.gt -to.gt -be.gy -cc.hn -io.kg -jp.kg -tv.kg -uk.kg -us.kg -de.ls -at.md -de.md -jp.md -to.md -indie.porn -vxl.sh -ch.tc -me.tc -we.tc -nyan.to -at.vg -blog.vu -dev.vu -me.vu - -// V.UA Domain Administrator : https://domain.v.ua/ -// Submitted by Serhii Rostilo -v.ua - -// Vultr Objects : https://www.vultr.com/products/object-storage/ -// Submitted by Niels Maumenee -*.vultrobjects.com - -// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com -// Submitted by Masayuki Note -wafflecell.com - -// Webflow, Inc. : https://www.webflow.com -// Submitted by Webflow Security Team -webflow.io -webflowtest.io - -// WebHare bv: https://www.webhare.com/ -// Submitted by Arnold Hendriks -*.webhare.dev - -// WebHotelier Technologies Ltd: https://www.webhotelier.net/ -// Submitted by Apostolos Tsakpinis -reserve-online.net -reserve-online.com -bookonline.app -hotelwithflight.com - -// WebWaddle Ltd: https://webwaddle.com/ -// Submitted by Merlin Glander -*.wadl.top - -// WeDeploy by Liferay, Inc. : https://www.wedeploy.com -// Submitted by Henrique Vicente -wedeploy.io -wedeploy.me -wedeploy.sh - -// Western Digital Technologies, Inc : https://www.wdc.com -// Submitted by Jung Jin -remotewd.com - -// WIARD Enterprises : https://wiardweb.com -// Submitted by Kidd Hustle -pages.wiardweb.com - -// Wikimedia Labs : https://wikitech.wikimedia.org -// Submitted by Arturo Borrero Gonzalez -wmflabs.org -toolforge.org -wmcloud.org - -// WISP : https://wisp.gg -// Submitted by Stepan Fedotov -panel.gg -daemon.panel.gg - -// Wizard Zines : https://wizardzines.com -// Submitted by Julia Evans -messwithdns.com - -// WoltLab GmbH : https://www.woltlab.com -// Submitted by Tim Düsterhus -woltlab-demo.com -myforum.community -community-pro.de -diskussionsbereich.de -community-pro.net -meinforum.net - -// Woods Valldata : https://www.woodsvalldata.co.uk/ -// Submitted by Chris Whittle -affinitylottery.org.uk -raffleentry.org.uk -weeklylottery.org.uk - -// WP Engine : https://wpengine.com/ -// Submitted by Michael Smith -// Submitted by Brandon DuRette -wpenginepowered.com -js.wpenginepowered.com - -// Wix.com, Inc. : https://www.wix.com -// Submitted by Shahar Talmi -wixsite.com -editorx.io -wixstudio.io -wix.run - -// XenonCloud GbR: https://xenoncloud.net -// Submitted by Julian Uphoff -half.host - -// XnBay Technology : http://www.xnbay.com/ -// Submitted by XnBay Developer -xnbay.com -u2.xnbay.com -u2-local.xnbay.com - -// XS4ALL Internet bv : https://www.xs4all.nl/ -// Submitted by Daniel Mostertman -cistron.nl -demon.nl -xs4all.space - -// Yandex.Cloud LLC: https://cloud.yandex.com -// Submitted by Alexander Lodin -yandexcloud.net -storage.yandexcloud.net -website.yandexcloud.net - -// YesCourse Pty Ltd : https://yescourse.com -// Submitted by Atul Bhouraskar -official.academy - -// Yola : https://www.yola.com/ -// Submitted by Stefano Rivera -yolasite.com - -// Yombo : https://yombo.net -// Submitted by Mitch Schwenk -ybo.faith -yombo.me -homelink.one -ybo.party -ybo.review -ybo.science -ybo.trade - -// Yunohost : https://yunohost.org -// Submitted by Valentin Grimaud -ynh.fr -nohost.me -noho.st - -// ZaNiC : http://www.za.net/ -// Submitted by registry -za.net -za.org - -// ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com -// Submitted by Julian Alker -zap.cloud - -// Zine EOOD : https://zine.bg/ -// Submitted by Martin Angelov -bss.design - -// Zitcom A/S : https://www.zitcom.dk -// Submitted by Emil Stahl -basicserver.io -virtualserver.io -enterprisecloud.nu - -// ===END PRIVATE DOMAINS=== diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix.rb deleted file mode 100644 index bd131e3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix.rb +++ /dev/null @@ -1,177 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -require_relative "public_suffix/domain" -require_relative "public_suffix/version" -require_relative "public_suffix/errors" -require_relative "public_suffix/rule" -require_relative "public_suffix/list" - -# PublicSuffix is a Ruby domain name parser based on the Public Suffix List. -# -# The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative -# to provide an accurate list of domain name suffixes. -# -# The Public Suffix List is an initiative of the Mozilla Project, -# but is maintained as a community resource. It is available for use in any software, -# but was originally created to meet the needs of browser manufacturers. -module PublicSuffix - - DOT = "." - BANG = "!" - STAR = "*" - - # Parses +name+ and returns the {PublicSuffix::Domain} instance. - # - # @example Parse a valid domain - # PublicSuffix.parse("google.com") - # # => # - # - # @example Parse a valid subdomain - # PublicSuffix.parse("www.google.com") - # # => # - # - # @example Parse a fully qualified domain - # PublicSuffix.parse("google.com.") - # # => # - # - # @example Parse a fully qualified domain (subdomain) - # PublicSuffix.parse("www.google.com.") - # # => # - # - # @example Parse an invalid (unlisted) domain - # PublicSuffix.parse("x.yz") - # # => # - # - # @example Parse an invalid (unlisted) domain with strict checking (without applying the default * rule) - # PublicSuffix.parse("x.yz", default_rule: nil) - # # => PublicSuffix::DomainInvalid: `x.yz` is not a valid domain - # - # @example Parse an URL (not supported, only domains) - # PublicSuffix.parse("http://www.google.com") - # # => PublicSuffix::DomainInvalid: http://www.google.com is not expected to contain a scheme - # - # - # @param name [#to_s] The domain name or fully qualified domain name to parse. - # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} - # @param ignore_private [Boolean] - # @return [PublicSuffix::Domain] - # - # @raise [PublicSuffix::DomainInvalid] If domain is not a valid domain. - # @raise [PublicSuffix::DomainNotAllowed] If a rule for +domain+ is found, but the rule doesn't allow +domain+. - def self.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false) - what = normalize(name) - raise what if what.is_a?(DomainInvalid) - - rule = list.find(what, default: default_rule, ignore_private: ignore_private) - - # rubocop:disable Style/IfUnlessModifier - if rule.nil? - raise DomainInvalid, "`#{what}` is not a valid domain" - end - if rule.decompose(what).last.nil? - raise DomainNotAllowed, "`#{what}` is not allowed according to Registry policy" - end - - # rubocop:enable Style/IfUnlessModifier - - decompose(what, rule) - end - - # Checks whether +domain+ is assigned and allowed, without actually parsing it. - # - # This method doesn't care whether domain is a domain or subdomain. - # The validation is performed using the default {PublicSuffix::List}. - # - # @example Validate a valid domain - # PublicSuffix.valid?("example.com") - # # => true - # - # @example Validate a valid subdomain - # PublicSuffix.valid?("www.example.com") - # # => true - # - # @example Validate a not-listed domain - # PublicSuffix.valid?("example.tldnotlisted") - # # => true - # - # @example Validate a not-listed domain with strict checking (without applying the default * rule) - # PublicSuffix.valid?("example.tldnotlisted") - # # => true - # PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) - # # => false - # - # @example Validate a fully qualified domain - # PublicSuffix.valid?("google.com.") - # # => true - # PublicSuffix.valid?("www.google.com.") - # # => true - # - # @example Check an URL (which is not a valid domain) - # PublicSuffix.valid?("http://www.example.com") - # # => false - # - # - # @param name [#to_s] The domain name or fully qualified domain name to validate. - # @param ignore_private [Boolean] - # @return [Boolean] - def self.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false) - what = normalize(name) - return false if what.is_a?(DomainInvalid) - - rule = list.find(what, default: default_rule, ignore_private: ignore_private) - - !rule.nil? && !rule.decompose(what).last.nil? - end - - # Attempt to parse the name and returns the domain, if valid. - # - # This method doesn't raise. Instead, it returns nil if the domain is not valid for whatever reason. - # - # @param name [#to_s] The domain name or fully qualified domain name to parse. - # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} - # @param ignore_private [Boolean] - # @return [String] - def self.domain(name, **options) - parse(name, **options).domain - rescue PublicSuffix::Error - nil - end - - - # private - - def self.decompose(name, rule) - left, right = rule.decompose(name) - - parts = left.split(DOT) - # If we have 0 parts left, there is just a tld and no domain or subdomain - # If we have 1 part left, there is just a tld, domain and not subdomain - # If we have 2 parts left, the last part is the domain, the other parts (combined) are the subdomain - tld = right - sld = parts.empty? ? nil : parts.pop - trd = parts.empty? ? nil : parts.join(DOT) - - Domain.new(tld, sld, trd) - end - - # Pretend we know how to deal with user input. - def self.normalize(name) - name = name.to_s.dup - name.strip! - name.chomp!(DOT) - name.downcase! - - return DomainInvalid.new("Name is blank") if name.empty? - return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT) - return DomainInvalid.new(format("%s is not expected to contain a scheme", name)) if name.include?("://") - - name - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/domain.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/domain.rb deleted file mode 100644 index 54e05f9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/domain.rb +++ /dev/null @@ -1,235 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -module PublicSuffix - - # Domain represents a domain name, composed by a TLD, SLD and TRD. - class Domain - - # Splits a string into the labels, that is the dot-separated parts. - # - # The input is not validated, but it is assumed to be a valid domain name. - # - # @example - # - # name_to_labels('example.com') - # # => ['example', 'com'] - # - # name_to_labels('example.co.uk') - # # => ['example', 'co', 'uk'] - # - # @param name [String, #to_s] The domain name to split. - # @return [Array] - def self.name_to_labels(name) - name.to_s.split(DOT) - end - - - attr_reader :tld, :sld, :trd - - # Creates and returns a new {PublicSuffix::Domain} instance. - # - # @overload initialize(tld) - # Initializes with a +tld+. - # @param [String] tld The TLD (extension) - # @overload initialize(tld, sld) - # Initializes with a +tld+ and +sld+. - # @param [String] tld The TLD (extension) - # @param [String] sld The TRD (domain) - # @overload initialize(tld, sld, trd) - # Initializes with a +tld+, +sld+ and +trd+. - # @param [String] tld The TLD (extension) - # @param [String] sld The SLD (domain) - # @param [String] trd The TRD (subdomain) - # - # @yield [self] Yields on self. - # @yieldparam [PublicSuffix::Domain] self The newly creates instance - # - # @example Initialize with a TLD - # PublicSuffix::Domain.new("com") - # # => # - # - # @example Initialize with a TLD and SLD - # PublicSuffix::Domain.new("com", "example") - # # => # - # - # @example Initialize with a TLD, SLD and TRD - # PublicSuffix::Domain.new("com", "example", "wwww") - # # => # - # - def initialize(*args) - @tld, @sld, @trd = args - yield(self) if block_given? - end - - # Returns a string representation of this object. - # - # @return [String] - def to_s - name - end - - # Returns an array containing the domain parts. - # - # @return [Array] - # - # @example - # - # PublicSuffix::Domain.new("google.com").to_a - # # => [nil, "google", "com"] - # - # PublicSuffix::Domain.new("www.google.com").to_a - # # => [nil, "google", "com"] - # - def to_a - [@trd, @sld, @tld] - end - - # Returns the full domain name. - # - # @return [String] - # - # @example Gets the domain name of a domain - # PublicSuffix::Domain.new("com", "google").name - # # => "google.com" - # - # @example Gets the domain name of a subdomain - # PublicSuffix::Domain.new("com", "google", "www").name - # # => "www.google.com" - # - def name - [@trd, @sld, @tld].compact.join(DOT) - end - - # Returns a domain-like representation of this object - # if the object is a {#domain?}, nil otherwise. - # - # PublicSuffix::Domain.new("com").domain - # # => nil - # - # PublicSuffix::Domain.new("com", "google").domain - # # => "google.com" - # - # PublicSuffix::Domain.new("com", "google", "www").domain - # # => "www.google.com" - # - # This method doesn't validate the input. It handles the domain - # as a valid domain name and simply applies the necessary transformations. - # - # This method returns a FQD, not just the domain part. - # To get the domain part, use #sld (aka second level domain). - # - # PublicSuffix::Domain.new("com", "google", "www").domain - # # => "google.com" - # - # PublicSuffix::Domain.new("com", "google", "www").sld - # # => "google" - # - # @see #domain? - # @see #subdomain - # - # @return [String] - def domain - [@sld, @tld].join(DOT) if domain? - end - - # Returns a subdomain-like representation of this object - # if the object is a {#subdomain?}, nil otherwise. - # - # PublicSuffix::Domain.new("com").subdomain - # # => nil - # - # PublicSuffix::Domain.new("com", "google").subdomain - # # => nil - # - # PublicSuffix::Domain.new("com", "google", "www").subdomain - # # => "www.google.com" - # - # This method doesn't validate the input. It handles the domain - # as a valid domain name and simply applies the necessary transformations. - # - # This method returns a FQD, not just the subdomain part. - # To get the subdomain part, use #trd (aka third level domain). - # - # PublicSuffix::Domain.new("com", "google", "www").subdomain - # # => "www.google.com" - # - # PublicSuffix::Domain.new("com", "google", "www").trd - # # => "www" - # - # @see #subdomain? - # @see #domain - # - # @return [String] - def subdomain - [@trd, @sld, @tld].join(DOT) if subdomain? - end - - # Checks whether self looks like a domain. - # - # This method doesn't actually validate the domain. - # It only checks whether the instance contains - # a value for the {#tld} and {#sld} attributes. - # - # @example - # - # PublicSuffix::Domain.new("com").domain? - # # => false - # - # PublicSuffix::Domain.new("com", "google").domain? - # # => true - # - # PublicSuffix::Domain.new("com", "google", "www").domain? - # # => true - # - # # This is an invalid domain, but returns true - # # because this method doesn't validate the content. - # PublicSuffix::Domain.new("com", nil).domain? - # # => true - # - # @see #subdomain? - # - # @return [Boolean] - def domain? - !(@tld.nil? || @sld.nil?) - end - - # Checks whether self looks like a subdomain. - # - # This method doesn't actually validate the subdomain. - # It only checks whether the instance contains - # a value for the {#tld}, {#sld} and {#trd} attributes. - # If you also want to validate the domain, - # use {#valid_subdomain?} instead. - # - # @example - # - # PublicSuffix::Domain.new("com").subdomain? - # # => false - # - # PublicSuffix::Domain.new("com", "google").subdomain? - # # => false - # - # PublicSuffix::Domain.new("com", "google", "www").subdomain? - # # => true - # - # # This is an invalid domain, but returns true - # # because this method doesn't validate the content. - # PublicSuffix::Domain.new("com", "example", nil).subdomain? - # # => true - # - # @see #domain? - # - # @return [Boolean] - def subdomain? - !(@tld.nil? || @sld.nil? || @trd.nil?) - end - - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/errors.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/errors.rb deleted file mode 100644 index 40ee981..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/errors.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -module PublicSuffix - - class Error < StandardError - end - - # Raised when trying to parse an invalid name. - # A name is considered invalid when no rule is found in the definition list. - # - # @example - # - # PublicSuffix.parse("nic.test") - # # => PublicSuffix::DomainInvalid - # - # PublicSuffix.parse("http://www.nic.it") - # # => PublicSuffix::DomainInvalid - # - class DomainInvalid < Error - end - - # Raised when trying to parse a name that matches a suffix. - # - # @example - # - # PublicSuffix.parse("nic.do") - # # => PublicSuffix::DomainNotAllowed - # - # PublicSuffix.parse("www.nic.do") - # # => PublicSuffix::Domain - # - class DomainNotAllowed < DomainInvalid - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/list.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/list.rb deleted file mode 100644 index d90b723..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/list.rb +++ /dev/null @@ -1,247 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -module PublicSuffix - - # A {PublicSuffix::List} is a collection of one - # or more {PublicSuffix::Rule}. - # - # Given a {PublicSuffix::List}, - # you can add or remove {PublicSuffix::Rule}, - # iterate all items in the list or search for the first rule - # which matches a specific domain name. - # - # # Create a new list - # list = PublicSuffix::List.new - # - # # Push two rules to the list - # list << PublicSuffix::Rule.factory("it") - # list << PublicSuffix::Rule.factory("com") - # - # # Get the size of the list - # list.size - # # => 2 - # - # # Search for the rule matching given domain - # list.find("example.com") - # # => # - # list.find("example.org") - # # => nil - # - # You can create as many {PublicSuffix::List} you want. - # The {PublicSuffix::List.default} rule list is used - # to tokenize and validate a domain. - # - class List - - DEFAULT_LIST_PATH = File.expand_path("../../data/list.txt", __dir__) - - # Gets the default rule list. - # - # Initializes a new {PublicSuffix::List} parsing the content - # of {PublicSuffix::List.default_list_content}, if required. - # - # @return [PublicSuffix::List] - def self.default(**options) - @default ||= parse(File.read(DEFAULT_LIST_PATH), **options) - end - - # Sets the default rule list to +value+. - # - # @param value [PublicSuffix::List] the new list - # @return [PublicSuffix::List] - def self.default=(value) - @default = value - end - - # Parse given +input+ treating the content as Public Suffix List. - # - # See http://publicsuffix.org/format/ for more details about input format. - # - # @param input [#each_line] the list to parse - # @param private_domains [Boolean] whether to ignore the private domains section - # @return [PublicSuffix::List] - def self.parse(input, private_domains: true) - comment_token = "//" - private_token = "===BEGIN PRIVATE DOMAINS===" - section = nil # 1 == ICANN, 2 == PRIVATE - - new do |list| - input.each_line do |line| - line.strip! - case # rubocop:disable Style/EmptyCaseCondition - - # skip blank lines - when line.empty? - next - - # include private domains or stop scanner - when line.include?(private_token) - break if !private_domains - - section = 2 - - # skip comments - when line.start_with?(comment_token) # rubocop:disable Lint/DuplicateBranch - next - - else - list.add(Rule.factory(line, private: section == 2)) - - end - end - end - end - - - # Initializes an empty {PublicSuffix::List}. - # - # @yield [self] Yields on self. - # @yieldparam [PublicSuffix::List] self The newly created instance. - def initialize - @rules = {} - yield(self) if block_given? - end - - - # Checks whether two lists are equal. - # - # List one is equal to two, if two is an instance of - # {PublicSuffix::List} and each +PublicSuffix::Rule::*+ - # in list one is available in list two, in the same order. - # - # @param other [PublicSuffix::List] the List to compare - # @return [Boolean] - def ==(other) - return false unless other.is_a?(List) - - equal?(other) || @rules == other.rules - end - alias eql? == - - # Iterates each rule in the list. - def each(&block) - Enumerator.new do |y| - @rules.each do |key, node| - y << entry_to_rule(node, key) - end - end.each(&block) - end - - - # Adds the given object to the list and optionally refreshes the rule index. - # - # @param rule [PublicSuffix::Rule::*] the rule to add to the list - # @return [self] - def add(rule) - @rules[rule.value] = rule_to_entry(rule) - self - end - alias << add - - # Gets the number of rules in the list. - # - # @return [Integer] - def size - @rules.size - end - - # Checks whether the list is empty. - # - # @return [Boolean] - def empty? - @rules.empty? - end - - # Removes all rules. - # - # @return [self] - def clear - @rules.clear - self - end - - # Finds and returns the rule corresponding to the longest public suffix for the hostname. - # - # @param name [#to_s] the hostname - # @param default [PublicSuffix::Rule::*] the default rule to return in case no rule matches - # @return [PublicSuffix::Rule::*] - def find(name, default: default_rule, **options) - rule = select(name, **options).inject do |l, r| - return r if r.instance_of?(Rule::Exception) - - l.length > r.length ? l : r - end - rule || default - end - - # Selects all the rules matching given hostame. - # - # If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as - # private domain. Note that the rules will still be part of the loop. - # If you frequently need to access lists ignoring the private domains, - # you should create a list that doesn't include these domains setting the - # `private_domains: false` option when calling {.parse}. - # - # Note that this method is currently private, as you should not rely on it. Instead, - # the public interface is {#find}. The current internal algorithm allows to return all - # matching rules, but different data structures may not be able to do it, and instead would - # return only the match. For this reason, you should rely on {#find}. - # - # @param name [#to_s] the hostname - # @param ignore_private [Boolean] - # @return [Array] - def select(name, ignore_private: false) - name = name.to_s - - parts = name.split(DOT).reverse! - index = 0 - query = parts[index] - rules = [] - - loop do - match = @rules[query] - rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false) - - index += 1 - break if index >= parts.size - - query = parts[index] + DOT + query - end - - rules - end - private :select - - # Gets the default rule. - # - # @see PublicSuffix::Rule.default_rule - # - # @return [PublicSuffix::Rule::*] - def default_rule - PublicSuffix::Rule.default - end - - - protected - - attr_reader :rules - - - private - - def entry_to_rule(entry, value) - entry.type.new(value: value, length: entry.length, private: entry.private) - end - - def rule_to_entry(rule) - Rule::Entry.new(rule.class, rule.length, rule.private) - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/rule.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/rule.rb deleted file mode 100644 index 23696f3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/rule.rb +++ /dev/null @@ -1,350 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -module PublicSuffix - - # A Rule is a special object which holds a single definition - # of the Public Suffix List. - # - # There are 3 types of rules, each one represented by a specific - # subclass within the +PublicSuffix::Rule+ namespace. - # - # To create a new Rule, use the {PublicSuffix::Rule#factory} method. - # - # PublicSuffix::Rule.factory("ar") - # # => # - # - module Rule - - # @api internal - Entry = Struct.new(:type, :length, :private) # rubocop:disable Lint/StructNewOverride - - # = Abstract rule class - # - # This represent the base class for a Rule definition - # in the {Public Suffix List}[https://publicsuffix.org]. - # - # This is intended to be an Abstract class - # and you shouldn't create a direct instance. The only purpose - # of this class is to expose a common interface - # for all the available subclasses. - # - # * {PublicSuffix::Rule::Normal} - # * {PublicSuffix::Rule::Exception} - # * {PublicSuffix::Rule::Wildcard} - # - # ## Properties - # - # A rule is composed by 4 properties: - # - # value - A normalized version of the rule name. - # The normalization process depends on rule tpe. - # - # Here's an example - # - # PublicSuffix::Rule.factory("*.google.com") - # # - # - # ## Rule Creation - # - # The best way to create a new rule is passing the rule name - # to the PublicSuffix::Rule.factory method. - # - # PublicSuffix::Rule.factory("com") - # # => PublicSuffix::Rule::Normal - # - # PublicSuffix::Rule.factory("*.com") - # # => PublicSuffix::Rule::Wildcard - # - # This method will detect the rule type and create an instance - # from the proper rule class. - # - # ## Rule Usage - # - # A rule describes the composition of a domain name and explains how to tokenize - # the name into tld, sld and trd. - # - # To use a rule, you first need to be sure the name you want to tokenize - # can be handled by the current rule. - # You can use the #match? method. - # - # rule = PublicSuffix::Rule.factory("com") - # - # rule.match?("google.com") - # # => true - # - # rule.match?("google.com") - # # => false - # - # Rule order is significant. A name can match more than one rule. - # See the {Public Suffix Documentation}[http://publicsuffix.org/format/] - # to learn more about rule priority. - # - # When you have the right rule, you can use it to tokenize the domain name. - # - # rule = PublicSuffix::Rule.factory("com") - # - # rule.decompose("google.com") - # # => ["google", "com"] - # - # rule.decompose("www.google.com") - # # => ["www.google", "com"] - # - # @abstract - # - class Base - - # @return [String] the rule definition - attr_reader :value - - # @return [String] the length of the rule - attr_reader :length - - # @return [Boolean] true if the rule is a private domain - attr_reader :private - - - # Initializes a new rule from the content. - # - # @param content [String] the content of the rule - # @param private [Boolean] - def self.build(content, private: false) - new(value: content, private: private) - end - - # Initializes a new rule. - # - # @param value [String] - # @param private [Boolean] - def initialize(value:, length: nil, private: false) - @value = value.to_s - @length = length || (@value.count(DOT) + 1) - @private = private - end - - # Checks whether this rule is equal to other. - # - # @param other [PublicSuffix::Rule::*] The rule to compare - # @return [Boolean] true if this rule and other are instances of the same class - # and has the same value, false otherwise. - def ==(other) - equal?(other) || (self.class == other.class && value == other.value) - end - alias eql? == - - # Checks if this rule matches +name+. - # - # A domain name is said to match a rule if and only if - # all of the following conditions are met: - # - # - When the domain and rule are split into corresponding labels, - # that the domain contains as many or more labels than the rule. - # - Beginning with the right-most labels of both the domain and the rule, - # and continuing for all labels in the rule, one finds that for every pair, - # either they are identical, or that the label from the rule is "*". - # - # @see https://publicsuffix.org/list/ - # - # @example - # PublicSuffix::Rule.factory("com").match?("example.com") - # # => true - # PublicSuffix::Rule.factory("com").match?("example.net") - # # => false - # - # @param name [String] the domain name to check - # @return [Boolean] - def match?(name) - # NOTE: it works because of the assumption there are no - # rules like foo.*.com. If the assumption is incorrect, - # we need to properly walk the input and skip parts according - # to wildcard component. - diff = name.chomp(value) - diff.empty? || diff.end_with?(DOT) - end - - # @abstract - def parts - raise NotImplementedError - end - - # @abstract - # @param domain [#to_s] The domain name to decompose - # @return [Array] - def decompose(*) - raise NotImplementedError - end - - end - - # Normal represents a standard rule (e.g. com). - class Normal < Base - - # Gets the original rule definition. - # - # @return [String] The rule definition. - def rule - value - end - - # Decomposes the domain name according to rule properties. - # - # @param domain [#to_s] The domain name to decompose - # @return [Array] The array with [trd + sld, tld]. - def decompose(domain) - suffix = parts.join('\.') - matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) - matches ? matches[1..2] : [nil, nil] - end - - # dot-split rule value and returns all rule parts - # in the order they appear in the value. - # - # @return [Array] - def parts - @value.split(DOT) - end - - end - - # Wildcard represents a wildcard rule (e.g. *.co.uk). - class Wildcard < Base - - # Initializes a new rule from the content. - # - # @param content [String] the content of the rule - # @param private [Boolean] - def self.build(content, private: false) - new(value: content.to_s[2..], private: private) - end - - # Initializes a new rule. - # - # @param value [String] - # @param length [Integer] - # @param private [Boolean] - def initialize(value:, length: nil, private: false) - super - length or @length += 1 # * counts as 1 - end - - # Gets the original rule definition. - # - # @return [String] The rule definition. - def rule - value == "" ? STAR : STAR + DOT + value - end - - # Decomposes the domain name according to rule properties. - # - # @param domain [#to_s] The domain name to decompose - # @return [Array] The array with [trd + sld, tld]. - def decompose(domain) - suffix = ([".*?"] + parts).join('\.') - matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) - matches ? matches[1..2] : [nil, nil] - end - - # dot-split rule value and returns all rule parts - # in the order they appear in the value. - # - # @return [Array] - def parts - @value.split(DOT) - end - - end - - # Exception represents an exception rule (e.g. !parliament.uk). - class Exception < Base - - # Initializes a new rule from the content. - # - # @param content [#to_s] the content of the rule - # @param private [Boolean] - def self.build(content, private: false) - new(value: content.to_s[1..], private: private) - end - - # Gets the original rule definition. - # - # @return [String] The rule definition. - def rule - BANG + value - end - - # Decomposes the domain name according to rule properties. - # - # @param domain [#to_s] The domain name to decompose - # @return [Array] The array with [trd + sld, tld]. - def decompose(domain) - suffix = parts.join('\.') - matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) - matches ? matches[1..2] : [nil, nil] - end - - # dot-split rule value and returns all rule parts - # in the order they appear in the value. - # The leftmost label is not considered a label. - # - # See http://publicsuffix.org/format/: - # If the prevailing rule is a exception rule, - # modify it by removing the leftmost label. - # - # @return [Array] - def parts - @value.split(DOT)[1..] - end - - end - - - # Takes the +name+ of the rule, detects the specific rule class - # and creates a new instance of that class. - # The +name+ becomes the rule +value+. - # - # @example Creates a Normal rule - # PublicSuffix::Rule.factory("ar") - # # => # - # - # @example Creates a Wildcard rule - # PublicSuffix::Rule.factory("*.ar") - # # => # - # - # @example Creates an Exception rule - # PublicSuffix::Rule.factory("!congresodelalengua3.ar") - # # => # - # - # @param content [#to_s] the content of the rule - # @return [PublicSuffix::Rule::*] A rule instance. - def self.factory(content, private: false) - case content.to_s[0, 1] - when STAR - Wildcard - when BANG - Exception - else - Normal - end.build(content, private: private) - end - - # The default rule to use if no rule match. - # - # The default rule is "*". From https://publicsuffix.org/list/: - # - # > If no rules match, the prevailing rule is "*". - # - # @return [PublicSuffix::Rule::Wildcard] The default rule. - def self.default - factory(STAR) - end - - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/version.rb b/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/version.rb deleted file mode 100644 index 07611a8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/public_suffix-5.1.1/lib/public_suffix/version.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -# = Public Suffix -# -# Domain name parser based on the Public Suffix List. -# -# Copyright (c) 2009-2024 Simone Carletti - -module PublicSuffix - - # @return [String] the current library version - VERSION = "5.1.1" - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/History.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/History.rdoc deleted file mode 100644 index b8751f9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/History.rdoc +++ /dev/null @@ -1,2403 +0,0 @@ -=== 13.0.6 - -* Additional fix for #389 - Pull request #390 by hsbt - -=== 13.0.5 - -* Fixed the regression of #388 - Pull request #389 by hsbt - -=== 13.0.4 - -* Fix rake test loader swallowing useful error information. - Pull request #367 by deivid-rodriguez -* Add -C/--directory option the same as GNU make. - Pull request #376 by nobu - -=== 13.0.3 - -* Fix breaking change of execution order on TestTask. - Pull request #368 by ysakasin - -=== 13.0.2 - -==== Enhancements - -* Fix tests to work with current FileUtils - Pull Request #358 by jeremyevans -* Simplify default rake test loader - Pull Request #357 by deivid-rodriguez -* Update rdoc - Pull Request #366 by bahasalien -* Update broken links to rake articles from Avdi in README - Pull Request #360 by svl7 - -=== 13.0.1 - -==== Bug fixes - -* Fixed bug: Reenabled task raises previous exception on second invokation - Pull Request #271 by thorsteneckel -* Fix an incorrectly resolved arg pattern - Pull Request #327 by mjbellantoni - -=== 13.0.0 - -==== Enhancements - -* Follows recent changes on keyword arguments in ruby 2.7. - Pull Request #326 by nobu -* Make `PackageTask` be able to omit parent directory while packing files - Pull Request #310 by tonytonyjan -* Add order only dependency - Pull Request #269 by take-cheeze - -==== Compatibility changes - -* Drop old ruby versions(< 2.2) - -=== 12.3.3 - -==== Bug fixes - -* Use the application's name in error message if a task is not found. - Pull Request #303 by tmatilai - -==== Enhancements: - -* Use File.open explicitly. - -=== 12.3.2 - -==== Bug fixes - -* Fixed test fails caused by 2.6 warnings. - Pull Request #297 by hsbt - -==== Enhancements: - -* Rdoc improvements. - Pull Request #293 by colby-swandale -* Improve multitask performance. - Pull Request #273 by jsm -* Add alias `prereqs`. - Pull Request #268 by take-cheeze - -=== 12.3.1 - -==== Bug fixes - -* Support did_you_mean >= v1.2.0 which has a breaking change on formatters. - Pull request #262 by FUJI Goro. - -==== Enhancements: - -* Don't run task if it depends on already invoked but failed task. - Pull request #252 by Gonzalo Rodriguez. -* Make space trimming consistent for all task arguments. - Pull request #259 by Gonzalo Rodriguez. -* Removes duplicated inclusion of Rake::DSL in tests. - Pull request #254 by Gonzalo Rodriguez. -* Re-raise a LoadError that didn't come from require in the test loader. - Pull request #250 by Dylan Thacker-Smith. - -=== 12.3.0 - -==== Compatibility Changes - -* Bump `required_ruby_version` to Ruby 2.0.0. Rake has already - removed support for Ruby 1.9.x. - -==== Enhancements: - -* Support `test-bundled-gems` task on ruby core. - -=== 12.2.1 - -==== Bug fixes - -* Fixed to break Capistrano::Application on capistrano3. - -=== 12.2.0 - -==== Enhancements: - -* Make rake easier to use as a library - Pull request #211 by @drbrain -* Fix quadratic performance in FileTask#out_of_date? - Pull request #224 by @doudou -* Clarify output when printing nested exception traces - Pull request #232 by @urbanautomaton - -==== Bug fixes - -* Account for a file that match 2 or more patterns. - Pull request #231 by @styd - -=== 12.1.0 - -==== Enhancements: - -* Added did_you_mean feature for invalid rake task. - Pull request #221 by @xtina-starr -* Enabled to dependency chained by extensions. Pull request #39 by Petr Skocik. -* Make all of string literals to frozen objects on Ruby 2.4 or later. - -==== Bug fixes - -* Typo fixes in rakefile.rdoc. Pull request #180 by Yuta Kurotaki. -* Fix unexpected behavior of file task with dryrun option. - Pull request #183 by @aycabta. -* Make LoadError from running tests more obvious. Pull request #195 - by Eric Hodel. -* Fix unexpected TypeError with hash style option. Pull request #202 - by Kuniaki IGARASHI. - -=== 12.0.0 - -==== Compatibility Changes - -* Removed arguments on clear #157 by Jesse Bowes -* Removed `rake/contrib` packages. These are extracted to `rake-contrib` gem. -* Removed deprecated method named `last\_comment`. - -==== Enhancements: - -* Re-use trace option on `cleanup` task. #164 by Brian Henderson -* Actions adore keyword arguments #174 by Josh Cheek -* Rake::TaskArguments#key? alias of #has_key? #175 by Paul Annesley - -=== 11.3.0 / 2016-09-20 - -==== Enhancements: - -* Remove to reference `Fixnum` constant. Pull request #160 by nobu - -=== 11.2.2 / 2016-06-12 - -==== Bug fixes - -* Fix unexpected behavior with multiple dependencies on Rake::TestTask - -=== 11.2.1 / 2016-06-12 - -==== Bug fixes - -* Fix regression of dependencies handling on Rake::TestTask. Report #139 - -=== 11.2.0 / 2016-06-11 - -==== Bug fixes - -* Fix unexpected cut-out behavior on task description using triple dots - and exclamation. Report #106 from Stephan Kämper and Pull request #134 by Lee -* Fix empty argument assignment with `with_defaults` option. Pull request #135 - by bakunyo -* Ignore to use `hwprefs` on Darwin platform. Use sysctl now. Report #128 - -==== Enhancements - -* Spawn options for sh Pull equest #138 by Eric Hodel. -* Allow to specify dependencies(prerequisites) for Rake::TestTask - Pull request #117 by Tim Maslyuchenko -* Use Bundler task instead of hoe for gem release. -* Remove explicitly load to rubygems for Ruby 1.8. -* Unify to declare `Rake::VERSION`. -* Support xz format for PackageTask. - -=== 11.1.2 / 2016-03-28 - -==== Bug fixes - -* Remove `-W` option when Rake::TestTask#verbose enabled. It's misunderstanding - specification change with Rake 11. Partly revert #67 - -=== 11.1.1 / 2016-03-14 - -==== Bug fixes - -* Use `-W` instead of `--verbose` when Rake::TestTask#verbose enabled. - JRuby doesn't have `--verbose` option. - -=== 11.1.0 / 2016-03-11 - -==== Compatibility Changes - -* Revert to remove `last\_comment`. It will remove Rake 12. - -=== 11.0.1 / 2016-03-09 - -==== Bug fixes - -* Fixed packaging manifest. - -=== 11.0.0 / 2016-03-09 - -==== Bug fixes - -* Correctly handle bad encoding in exception messages. Pull request #113 - by Tomer Brisker -* Fix verbose option at TestTask. Pull request #67 by Mike Blumtritt - -==== Enhancements - -* Make FileList#exclude more analogous to FileList#include. -* Use IO.open instead of Open3.popen3 for CPU counter. -* Make Rake::Task#already_invoked publicly accessible. - Pull request #93 by Joe Rafaniello -* Lookup prerequisites with same name outside of scope instead of - matching self. Pull request #96 by Sandy Vanderbleek -* Make FileList#pathmap behave like String#pathmap. - Pull request #61 by Daniel Tamai -* Add fetch method to task arguments. - Pull request #12 by Chris Keathley -* Use ruby warnings by default. Pull request #97 by Harold Giménez - -==== Compatibility Changes - -* Removed to support Ruby 1.8.x -* Removed constant named `RAKEVERSION` -* Removed Rake::AltSystem -* Removed Rake::RubyForgePublisher -* Removed Rake::TaskManager#last\_comment. Use last\_description. -* Removed Rake::TaskLib#paste -* Removed Top-level SshDirPublisher, SshFreshDirPublisher, SshFilePublisher - and CompositePublisher from lib/rake/contrib/publisher.rb -* Removed "rake/runtest.rb" - -=== 10.5.0 / 2016-01-13 - -==== Enhancements - -* Removed monkey patching for Ruby 1.8. Pull request #46 by Pablo Herrero. -* Inheritance class of Rake::FileList returns always self class. - Pull request #74 by Thomas Scholz - -=== 10.4.2 / 2014-12-02 - -==== Bug fixes - -* Rake no longer edits ARGV. This allows you to re-exec rake from a rake - task. Pull requset #9 by Matt Palmer. -* Documented how Rake::DSL#desc handles sentences in task descriptions. - Issue #7 by Raza Sayed. -* Fixed test error on 1.9.3 with legacy RubyGems. Issue #8 by Matt Palmer. -* Deleted duplicated History entry. Pull request #10 by Yuji Yamamoto. - -=== 10.4.1 / 2014-12-01 - -==== Bug fixes - -* Reverted fix for #277 as it caused numerous issues for rake users. - rails/spring issue #366 by Gustavo Dutra. - -=== 10.4.0 / 2014-11-22 - -==== Enhancements - -* Upgraded to minitest 5. Pull request #292 by Teo Ljungberg. -* Added support for Pathname in rake tasks. Pull request #271 by Randy - Coulman. -* Rake now ignores falsy dependencies which allows for easier programmatic - creation of tasks. Pull request #273 by Manav. -* Rake no longer edits ARGV. This allows you to re-exec rake from a rake - task. Issue #277 by Matt Palmer. -* Etc.nprocessors is used for counting the number of CPUs. - -==== Bug fixes - -* Updated rake manpage. Issue #283 by Nathan Long, pull request #291 by - skittleys. -* Add Rake::LATE to allow rebuilding of files that depend on deleted files. - Bug #286, pull request #287 by David Grayson. -* Fix relinking of files when repackaging. Bug #276 by Muenze. -* Fixed some typos. Pull request #280 by Jed Northridge. -* Try counting CPUs via cpuinfo if host_os was not matched. Pull request - #282 by Edouard B. - -=== 10.3.2 / 2014-05-15 - -==== Bug fixes - -* Rake no longer infinitely loops when showing exception causes that refer to - each other. Bug #272 by Chris Bandy. -* Fixed documentation typos. Bug #275 by Jake Worth. - -=== 10.3.1 / 2014-04-17 - -==== Bug fixes - -* Really stop reporting an error when cleaning already-deleted files. Pull - request #269 by Randy Coulman -* Fixed infinite loop when cleaning already-deleted files on windows. - -=== 10.3 / 2014-04-15 - -==== Enhancements - -* Added --build-all option to rake which treats all file prerequisites as - out-of-date. Pull request #254 by Andrew Gilbert. -* Added Rake::NameSpace#scope. Issue #263 by Jon San Miguel. - -==== Bug fixes - -* Suppress org.jruby package files in rake error messages for JRuby users. - Issue #213 by Charles Nutter. -* Fixed typo, removed extra "h". Pull request #267 by Hsing-Hui Hsu. -* Rake no longer reports an error when cleaning already-deleted files. Pull - request #266 by Randy Coulman. -* Consume stderr while determining CPU count to avoid hang. Issue #268 by - Albert Sun. - -=== 10.2.2 / 2014-03-27 - -==== Bug fixes - -* Restored Ruby 1.8.7 compatibility - -=== 10.2.1 / 2014-03-25 - -==== Bug fixes - -* File tasks including a ':' are now top-level tasks again. Issue #262 by - Josh Holtrop. -* Use sysctl for CPU count for all BSDs. Pull request #261 by Joshua Stein. -* Fixed CPU detection for unknown platforms. - -=== 10.2.0 / 2014-03-24 - -==== Enhancements - -* Rake now requires Ruby 1.9 or newer. For me, this is a breaking change, but - it seems that Jim planned to release it with Rake 10.2. See also pull - request #247 by Philip Arndt. -* Rake now allows you to declare tasks under a namespace like: - - task 'a:b' do ... end - - Pull request #232 by Judson Lester. -* Task#source defaults to the first prerequisite in non-rule tasks. Pull - request #215 by Avdi Grimm. -* Rake now automatically rebuilds and reloads imported files. Pull request - #209 by Randy Coulman. -* The rake task arguments can contain escaped commas. Pull request #214 by - Filip Hrbek. -* Rake now prints the exception class on errors. Patch #251 by David Cornu. - -==== Bug fixes - -* Fixed typos. Pull request #256 by Valera Rozuvan, #250 via Jake Worth, #260 - by Zachary Scott. -* Fixed documentation for calling tasks with arguments. Pull request #235 by - John Varghese. -* Clarified `rake -f` usage message. Pull request #252 by Marco Pfatschbacher. -* Fixed a test failure on windows. Pull request #231 by Hiroshi Shirosaki. -* Fixed corrupted rake.1.gz. Pull request #225 by Michel Boaventura. -* Fixed bug in can\_detect\_signals? in test. Patch from #243 by Alexey - Borzenkov. - -=== 10.1.1 - -* Use http://github.com/jimweirich/rake instead of http://rake.rubyforge.org for - canonical project url. - -=== 10.1.0 - -==== Changes - -===== New Features - -* Add support for variable length task argument lists. If more actual - arguments are supplied than named arguments, then the extra - arguments values will be in args.extras. - -* Application name is not displayed in the help banner. (Previously - "rake" was hardcoded, now rake-based applications can display their - own names). - -===== Bug Fixes - -Bug fixes include: - -* Fix backtrace suppression issues. - -* Rules now explicit get task arguments passed to them. - -* Rename FileList#exclude? to FileList#exclude\_from\_list? to avoid - conflict with new Rails method. - -* Clean / Clobber tasks now report failure to remove files. - -* Plus heaps of internal code cleanup. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. -The following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Michael Nikitochkin (general code cleanup) -* Vipul A M (general code cleanup) -* Dennis Bell (variable length task argument lists) -* Jacob Swanner (rules arguments) -* Rafael Rosa Fu (documentation typo) -* Stuart Nelson (install.rb fixes) -* Lee Hambley (application name in help banner) - --- Jim Weirich - -=== 10.0.3 - - "Jim, when will Rake reach version 1.0?" - -Over the past several years I've been asked that question at -conferences, panels and over twitter. Due to historical reasons (or -maybe just plain laziness) Rake has (incorrectly) been treating the -second digit of the version as the major release number. So in my head -Rake was already at version 9. - -Well, it's time to fix things. This next version of Rake drops old, -crufty, backwards compatibility hacks such as top level constants, DSL -methods defined in Object and numerous other features that are just no -longer desired. It's also time to drop the leading zero from the -version number as well and call this new version of rake what it -really is: Version 10. - -So, welcome to Rake 10.0! - -Rake 10 is actually feature identical to the latest version of Rake 9 -(that would be the version spelled 0.9.3), *except* that Rake 10 drops -all the sundry deprecated features that have accumulated over the years. - -If your Rakefile is up to date and current with all the new features -of Rake 10, you are ready to go. If your Rakefile still uses a few -deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same -feature set. Just be aware that future features will be in Rake 10 -family line. - -==== Changes - -As mentioned above, there are no new features in Rake 10. However, -there are a number of features missing: - -* Classic namespaces are now gone. Rake is no longer able to reflect - the options settings in the global variables ($rakefile, $show\_tasks, - $show\_prereqs, $trace, $dryrun and $silent). The - --classic-namespace option is no longer supported. - -* Global constants are no longer supported. This includes - Task, FileTask, FileCreationTask and - RakeApp). The constant missing hook to warn about using - global rake constants has been removed. - -* The Rake DSL methods (task, file, directory, etc) are in their own - module (Rake::DSL). The stub versions of these methods (that printed - warnings) in Object have been removed. However, the DSL methods are - added to the top-level main object. Since main is - not in the inheritance tree, the presence of the DSL methods in main - should be low impact on other libraries. - - If you want to use the Rake DSL commands from your own code, just - include Rake::DSL into your own classes and modules. - -* The deprecated syntax for task arguments (the one using - :needs) has been removed. - -* The --reduce-compat flag has been removed (it's not needed - anymore). - -* The deprecated rake/sys.rb library has been removed. - -* The deprecated rake/rdoctask.rb library has been removed. - RDoc supplies its own rake task now. - -* The deprecated rake/gempackagetask.rb library has been - removed. Gem supplies its own package task now. - -There is one small behavioral change: - -* Non-file tasks now always report the current time as their time - stamp. This is different from the previous behavior where non-file - tasks reported current time only if there were no prerequisites, and - the max prerequisite timestamp otherwise. This lead to inconsistent - and surprising behavior when adding prerequisites to tasks that in - turn were prequisites to file tasks. The new behavior is more - consistent and predictable. - -==== Changes (from 0.9.3, 0.9.4, 0.9.5) - -Since Rake 10 includes the changes from the last version of Rake 9, -we'll repeat the changes for versions 0.9.3 through 0.9.5 here. - -===== New Features (in 0.9.3) - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes (in 0.9.3) - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - -===== Bug Fixes (in 0.9.4) - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -===== Bug Fixes (in 0.9.5) - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.2 - -==== Changes - -===== Bug Fixes - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.1 - -==== Changes - -===== Bug Fixes - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 10.0.0 - - "Jim, when will Rake reach version 1.0?" - -Over the past several years I've been asked that question at -conferences, panels and over twitter. Due to historical reasons (or -maybe just plain laziness) Rake has (incorrectly) been treating the -second digit of the version as the major release number. So in my head -Rake was already at version 9. - -Well, it's time to fix things. This next version of Rake drops old, -crufty, backwards compatibility hacks such as top level constants, DSL -methods defined in Object and numerous other features that are just no -longer desired. It's also time to drop the leading zero from the -version number as well and call this new version of rake what it -really is: Version 10. - -So, welcome to Rake 10.0! - -Rake 10 is actually feature identical to the latest version of Rake 9 -(that would be the version spelled 0.9.3), *except* that Rake 10 drops -all the sundry deprecated features that have accumulated over the years. - -If your Rakefile is up to date and current with all the new features -of Rake 10, you are ready to go. If your Rakefile still uses a few -deprecated feeatures, feel free to use Rake 9 (0.9.3) with the same -feature set. Just be aware that future features will be in Rake 10 -family line. - -==== Changes in 10.0 - -As mentioned above, there are no new features in Rake 10. However, -there are a number of features missing: - -* Classic namespaces are now gone. Rake is no longer able to reflect - the options settings in the global variables ($rakefile, $show\_tasks, - $show\_prereqs, $trace, $dryrun and $silent). The - --classic-namespace option is no longer supported. - -* Global constants are no longer supported. This includes - Task, FileTask, FileCreationTask and - RakeApp). The constant missing hook to warn about using - global rake constants has been removed. - -* The Rake DSL methods (task, file, directory, etc) are in their own - module (Rake::DSL). The stub versions of these methods (that printed - warnings) in Object have been removed. However, the DSL methods are - added to the top-level main object. Since main is - not in the inheritance tree, the presence of the DSL methods in main - should be low impact on other libraries. - - If you want to use the Rake DSL commands from your own code, just - include Rake::DSL into your own classes and modules. - -* The deprecated syntax for task arguments (the one using - :needs) has been removed. - -* The --reduce-compat flag has been removed (it's not needed - anymore). - -* The deprecated rake/sys.rb library has been removed. - -* The deprecated rake/rdoctask.rb library has been removed. - RDoc supplies its own rake task now. - -* The deprecated rake/gempackagetask.rb library has been - removed. Gem supplies its own package task now. - -There is one small behavioral change: - -* Non-file tasks now always report the current time as their time - stamp. This is different from the previous behavior where non-file - tasks reported current time only if there were no prerequisites, and - the max prerequisite timestamp otherwise. This lead to inconsistent - and surprising behavior when adding prerequisites to tasks that in - turn were prequisites to file tasks. The new behavior is more - consistent and predictable. - -==== Changes (from 0.9.3) - -Since Rake 10 includes the changes from the last version of Rake 9, -we'll repeat the changes for version 0.9.3 here. - -===== New Features - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - - -==== Thanks - -As usual, it was input from users that drove a lot of these changes. The -following people contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.6 - -Rake version 0.9.6 contains a number of fixes mainly for merging -Rake into the Ruby source tree and fixing tests. - -==== Changes - -===== Bug Fixes (0.9.6) - -* Better trace output when using a multi-threaded Rakefile. -* Arg parsing is now consistent for tasks and multitasks. -* Skip exit code test in versions of Ruby that don't support it well. - -Changes for better integration with the Ruby source tree: - -* Fix version literal for Ruby source tree build. -* Better loading of libraries for testing in Ruby build. -* Use the ruby version provided by Ruby's tests. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.5 - -Rake version 0.9.5 contains a number of bug fixes. - -==== Changes - -===== Bug Fixes (0.9.5) - -* --trace and --backtrace no longer swallow following task names. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.4 - -Rake version 0.9.4 contains a number of bug fixes. - -==== Changes - -===== Bug Fixes (0.9.4) - -* Exit status with failing tests is not correctly set to non-zero. - -* Simplified syntax for phony task (for older versions of RDoc). - -* Stand alone FileList usage gets glob function (without loading in - extra dependencies) - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== 0.9.3 - -Rake version 0.9.3 contains some new, backwards compatible features and -a number of bug fixes. - -==== Changes - -===== New Features - -* Multitask tasks now use a thread pool. Use -j to limit the number of - available threads. - -* Use -m to turn regular tasks into multitasks (use at your own risk). - -* You can now do "Rake.add_rakelib 'dir'" in your Rakefile to - programatically add rake task libraries. - -* You can specific backtrace suppression patterns (see - --suppress-backtrace) - -* Directory tasks can now take prerequisites and actions - -* Use --backtrace to request a full backtrace without the task trace. - -* You can say "--backtrace=stdout" and "--trace=stdout" to route trace - output to standard output rather than standard error. - -* Optional 'phony' target (enable with 'require 'rake/phony'") for - special purpose builds. - -* Task#clear now clears task comments as well as actions and - prerequisites. Task#clear_comment will specifically target comments. - -* The --all option will force -T and -D to consider all the tasks, - with and without descriptions. - -===== Bug Fixes - -* Semi-colons in windows rakefile paths now work. - -* Improved Control-C support when invoking multiple test suites. - -* egrep method now reads files in text mode (better support for - Windows) - -* Better deprecation line number reporting. - -* The -W option now works with all tasks, whether they have a - description or not. - -* File globs in rake should not be sorted alphabetically, independent - of file system and platform. - -* Numerous internal improvements. - -* Documentation typos and fixes. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Aaron Patterson -* Dylan Smith -* Jo Liss -* Jonas Pfenniger -* Kazuki Tsujimoto -* Michael Bishop -* Michael Elufimov -* NAKAMURA Usaku -* Ryan Davis -* Sam Grönblom -* Sam Phippen -* Sergio Wong -* Tay Ray Chuan -* grosser -* quix - -Also, many thanks to Eric Hodel for assisting with getting this release -out the door. - --- Jim Weirich - -=== Rake 0.9.2.2 - -Rake version 0.9.2.2 is mainly bug fixes. - -==== Changes - -* The rake test loader now removes arguments it has processed. Issue #51 -* Rake::TaskArguments now responds to #values\_at -* RakeFileUtils.verbose_flag = nil silences output the same as 0.8.7 -* Rake tests are now directory-independent -* Rake tests are no longer require flexmock -* Commands constant is no longer polluting top level namespace. -* Show only the interesting portion of the backtrace by default (James M. Lawrence). -* Added --reduce-compat option to remove backward compatible DSL hacks (James M. Lawrence). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.2 - -Rake version 0.9.2 has a few small fixes. See below for details. - -==== Changes - -* Support for Ruby 1.8.6 was fixed. -* Global DSL warnings now honor --no-deprecate - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.1 - -Rake version 0.9.1 has a number of bug fixes and enhancments (see -below for more details). Additionally, the internals have be slightly -restructured and improved. - -==== Changes - -Rake 0.9.1 adds back the global DSL methods, but with deprecation -messages. This allows Rake 0.9.1 to be used with older rakefiles with -warning messages. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - -=== 0.9.0 - -Rake version 0.9.0 has a number of bug fixes and enhancments (see -below for more details). Additionally, the internals have be slightly -restructured and improved. - -==== Changes - -===== New Features / Enhancements / Bug Fixes in Version 0.9.0 - -* Rake now warns when the deprecated :needs syntax used (and suggests - the proper syntax in the warning). - -* Moved Rake DSL commands to top level ruby object 'main'. Rake DSL - commands are no longer private methods in Object. (Suggested by - James M. Lawrence/quix) - -* Rake now uses case-insensitive comparisons to find the Rakefile on Windows. - Based on patch by Roger Pack. - -* Rake now requires (instead of loads) files in the test task. Patch by Cezary - Baginski. - -* Fixed typos. Patches by Sean Scot August Moon and R.T. Lechow. - -* Rake now prints the Rakefile directory only when it's different from the - current directory. Patch by Alex Chaffee. - -* Improved rakefile_location discovery on Windows. Patch by James Tucker. - -* Rake now recognizes "Windows Server" as a windows system. Patch by Matthias - Lüdtke - -* Rake::RDocTask is deprecated. Use RDoc::Task from RDoc 2.4.2+ (require - 'rdoc/task') - -* Rake::GemPackageTask is deprecated. Use Gem::PackageTask (require - 'rubygems/package\_task') - -* Rake now outputs various messages to $stderr instead of $stdout. - -* Rake no longer emits warnings for Config. Patch by Santiago Pastorino. - -* Removed Rake's DSL methods from the top level scope. If you need to - call 'task :xzy' in your code, include Rake::DSL into your class, or - put the code in a Rake::DSL.environment do ... end block. - -* Split rake.rb into individual files. - -* Support for the --where (-W) flag for showing where a task is defined. - -* Fixed quoting in test task. - (http://onestepback.org/redmine/issues/show/44, - http://www.pivotaltracker.com/story/show/1223138) - -* Fixed the silent option parsing problem. - (http://onestepback.org/redmine/issues/show/47) - -* Fixed :verbose=>false flag on sh and ruby commands. - -* Rake command line options may be given by default in a RAKEOPT - environment variable. - -* Errors in Rake will now display the task invocation chain in effect - at the time of the error. - -* Accepted change by warnickr to not expand test patterns in shell - (allowing more files in the test suite). - -* Fixed that file tasks did not perform prereq lookups in scope - (Redmine #57). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence (quix) -* Roger Pack -* Cezary Baginski -* Sean Scot August Moon -* R.T. Lechow -* Alex Chaffee -* James Tucker -* Matthias Lüdtke -* Santiago Pastorino - -Also, bit thanks to Eric Hodel for assisting with getting this release -out the door (where "assisting" includes, but is not by any means -limited to, "pushing" me to get it done). - --- Jim Weirich - - -=== 0.8.7 - -Rake version 0.8.5 introduced greatly improved support for executing -commands on Windows. The "sh" command now has the same semantics on -Windows that it has on Unix based platforms. - -Rake version 0.8.6 includes minor fixes the the RDoc generation. -Rake version 0.8.7 includes a minor fix for JRuby running on windows. - -==== Changes - -===== New Features / Enhancements in Version 0.8.5 - -* Improved implementation of the Rake system command for Windows. - (patch from James M. Lawrence/quix) - -* Support for Ruby 1.9's improved system command. (patch from James - M. Lawrence/quix) - -* Rake now includes the configured extension when invoking an - executable (Config::CONFIG['EXEEXT]) - -===== Bug Fixes in Version 0.8.5 - -* Environment variable keys are now correctly cased (it matters in - some implementations). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Charles Nutter - --- Jim Weirich - -=== 0.8.6 - -Rake version 0.8.5 introduced greatly improved support for executing -commands on Windows. The "sh" command now has the same semantics on -Windows that it has on Unix based platforms. - -Rake version 0.8.5 includes minor fixes the the RDoc generation. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena - --- Jim Weirich - -=== 0.8.5 - -Rake version 0.8.5 is a new release of Rake with greatly improved -support for executing commands on Windows. The "sh" command now has -the same semantics on Windows that it has on Unix based platforms. - -==== Changes - -===== New Features / Enhancements in Version 0.8.5 - -* Improved implementation of the Rake system command for Windows. - (patch from James M. Lawrence/quix) - -* Support for Ruby 1.9's improved system command. (patch from James - M. Lawrence/quix) - -* Rake now includes the configured extension when invoking an - executable (Config::CONFIG['EXEEXT]) - -===== Bug Fixes in Version 0.8.5 - -* Environment variable keys are now correctly cased (it matters in - some implementations). - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena - --- Jim Weirich - -=== 0.8.4 - -Rake version 0.8.4 is a bug-fix release of rake. - -NOTE: The version of Rake that comes with Ruby 1.9 has diverged - slightly from the core Rake code base. Rake 0.8.4 will work - with Ruby 1.9, but is not a strict upgrade for the Rake that - comes with Ruby 1.9. A (near) future release of Rake will unify - those two codebases. - -==== Letter Writing Campaign - -Thanks to Aaron Patterson (@tenderlove) and Eric Hodel (@drbrain) for -their encouraging support in organizing a letter writing campaign to -lobby for the "Warning Free" release of rake 0.8.4. A special callout -goes to Jonathan D. Lord, Sr (Dr. Wingnut) whose postcard was the -first to actually reach me. (see -http://tenderlovemaking.com/2009/02/26/we-need-a-new-version-of-rake/ -for details) - -==== Changes - -===== New Features / Enhancements in Version 0.8.4 - -* Case is preserved on rakefile names. (patch from James - M. Lawrence/quix) - -* Improved Rakefile case insensitivity testing (patch from Luis - Lavena). - -* Windows system dir search order is now: HOME, HOMEDRIVE + HOMEPATH, - APPDATA, USERPROFILE (patch from Luis Lavena) - -* MingGW is now recognized as a windows platform. (patch from Luis - Lavena) - -===== Bug Fixes in Version 0.8.4 - -* Removed reference to manage_gem to fix the warning produced by the - gem package task. - -* Fixed stray ARGV option problem that was interfering with - Test::Unit::Runner. (patch from Pivotal Labs) - -===== Infrastructure Improvements in Version 0.8.4 - -* Numerous fixes to the windows test suite (patch from Luis Lavena). - -* Improved Rakefile case insensitivity testing (patch from Luis - Lavena). - -* Better support for windows paths in the test task (patch from Simon - Chiang/bahuvrihi) - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* James M. Lawrence/quix -* Luis Lavena -* Pivotal Labs -* Simon Chiang/bahuvrihi - --- Jim Weirich - -=== 0.8.3 - -Rake version 0.8.3 is a bug-fix release of rake. - -==== Changes - -===== Bug Fixes in Version 0.8.3 - -* Enhanced the system directory detection in windows. We now check - HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch - supplied by James Tucker). Rake no long aborts if it can't find the - directory. - -* Added fix to handle ruby installations in directories with spaces in - their name. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Edwin Pratomo -* Gavin Stark -* Adam Q. Salter -* Adam Majer -* Emanuel Indermühle -* Ittay Dror -* Bheeshmar Redheendran (for spending an afternoon with me debugging - windows issues) - --- Jim Weirich - - -=== 0.8.2 - -Rake version 0.8.2 is a new release of rake that includes a number of -new features and numerous bug fixes. - -==== Changes - -===== New Features in Version 0.8.2 - -* Switched from getoptlong to optparse (patches supplied by Edwin - Pratomo). - -* The -T option will now attempt to dynamically sense the size of the - terminal. The -T output will only self-truncate if the output is a - tty. However, if RAKE_COLUMNS is explicitly set, it will be honored - in any case. (Patch provided by Gavin Stark). - -* The following public methods have been added to rake task objects: - - * task.clear -- Clear both the prerequisites and actions of the - target rake task. - * task.clear_prerequisites -- Clear all the existing prerequisites - from the target rake task. - * task.clear_actions -- Clear all the existing actions from the - target rake task. - * task.reenable -- Re-enable a task, allowing its actions to be - executed again if the task is invoked. - -* Changed RDoc test task to have no default template. This makes it - easier for the tempate to pick up the template from the environment. - -* Default values for task arguments can easily be specified with the - :with_defaults method. (Idea for default argument merging supplied - by (Adam Q. Salter) - -===== Bug Fixes in Version 0.8.2 - -* Fixed bug in package task so that it will include the subdir - directory in the package for testing. (Bug found by Adam Majer) - -* Fixed filename dependency order bug in test\_inspect\_pending and - test\_to\_s\_pending. (Bug found by Adam Majer) - -* Fixed check for file utils options to make them immune to the - symbol/string differences. (Patch supplied by Edwin Pratomo) - -* Fixed bug with rules involving multiple source, where only the first - dependency of a rule has any effect (Patch supplied by Emanuel - Indermühle) - -* FileList#clone and FileList#dup have better sematics w.r.t. taint - and freeze. - -* Changed from using Mutex to Monitor. Evidently Mutex causes thread - join errors when Ruby is compiled with -disable-pthreads. (Patch - supplied by Ittay Dror) - -* Fixed bug in makefile parser that had problems with extra spaces in - file task names. (Patch supplied by Ittay Dror) - -==== Other changes in Version 0.8.2 - -* Added ENV var to rake's own Rakefile to prevent OS X from including - extended attribute junk in the rake package tar file. (Bug found by - Adam Majer) - -* Added a performance patch for reading large makefile dependency - files. (Patch supplied by Ittay Dror) - -==== Task Argument Examples - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.2] - -And the string "0.8.2" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire rake + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -===== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, :first_name, :last_name - -The first argument is still the name of the task (:name in this case). -The next to argumements are the names of the parameters expected by -:name (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, :first_name, :last_name do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. Missing command line arguments are -given the nil value. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Edwin Pratomo -* Gavin Stark -* Adam Q. Salter -* Adam Majer -* Emanuel Indermühle -* Ittay Dror -* Bheeshmar Redheendran (for spending an afternoon with me debugging - windows issues) - --- Jim Weirich - -=== 0.8.0/0.8.1 - -Rake version 0.8.0 is a new release of rake that includes serveral new -features. - -==== Changes - -===== New Features in Version 0.8.0 - -* Tasks can now receive command line parameters. See the examples - below for more details. - -* Comments are limited to 80 columns on output, but full comments can - be seen by using the -D parameter. (feature suggested by Jamis - Buck). - -* Explicit exit(n) calls will now set the exit status to n. (patch - provided by Stephen Touset). - -* Rake is now compatible with Ruby 1.9. - -Version 0.8.1 is a minor update that includes additional Ruby 1.9 -compatibility fixes. - -==== Task Argument Examples - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.0] - -And the string "0.8.0" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire rake + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -===== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, :first_name, :last_name - -The first argument is still the name of the task (:name in this case). -The next to argumements are the names of the parameters expected by -:name (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, :first_name, :last_name do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. Missing command line arguments are -given the nil value. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - -* Jamis Buck (for comment formatting suggestions) -* Stephen Touset (for exit status patch). - --- Jim Weirich - - -=== 0.7.3 - -Rake version 0.7.3 is a minor release that includes some refactoring to better -support custom Rake applications. - -==== Changes - -===== New Features in Version 0.7.3 - -* Added the +init+ and +top_level+ methods to make the creation of custom Rake applications a bit easier. E.g. - - gem 'rake', ">= 0.7.3" - require 'rake' - - Rake.application.init('myrake') - - task :default do - something_interesting - end - - Rake.application.top_level - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. The -following people either contributed patches, made suggestions or made -otherwise helpful comments. Thanks to ... - --- Jim Weirich - - -=== 0.7.2 - - -Version 0.7.2 supplies a bug fix and a few minor enhancements. In -particular, the new version fixes an incompatibility with the soon to -be released Ruby 1.8.6. We strongly recommend upgrading to Rake 0.7.2 -in order to be compatible with the new version of Ruby. - -==== Changes - -===== Bug Fixes in 0.7.2 - -There are quite a number of bug fixes in the new 0.7.2 version of -Rake: - -* Removed dependency on internal fu_xxx functions from FileUtils. - -* Error messages are now send to stderr rather than stdout (from - Payton Quackenbush). - -* Better error handling on invalid command line arguments (from Payton - Quackenbush). - -* Fixed some bugs where the application object was going to the global - appliation instead of using its own data. - -* Fixed the method name leak from FileUtils (bug found by Glenn - Vanderburg). - -* Added test for noop, bad_option and verbose flags to sh command. - -* Added a description to the gem task in GemPackageTask. - -* Fixed a bug when rules have multiple prerequisites (patch by Joel - VanderWerf) - -* Added the handful of RakeFileUtils to the private method as well. - -===== New Features in 0.7.2 - -The following new features are available in Rake version 0.7.2: - -* Added square and curly bracket patterns to FileList#include (Tilman - Sauerbeck). - -* FileLists can now pass a block to FileList#exclude to exclude files - based on calculated values. - -* Added plain filename support to rule dependents (suggested by Nobu - Nakada). - -* Added pathmap support to rule dependents. In other words, if a - pathmap format (beginning with a '%') is given as a Rake rule - dependent, then the name of the depend will be the name of the - target with the pathmap format applied. - -* Added a 'tasks' method to a namespace to get a list of tasks - associated with the namespace. - -* Added tar_command and zip_command options to the Package task. - -* The clean task will no longer delete 'core' if it is a directory. - -===== Internal Rake Improvements - -The following changes will are mainly internal improvements and -refactorings and have little effect on the end user. But they may be -of interest to the general public. - -* Added rcov task and updated unit testing for better code coverage. - -* Added a 'shame' task to the Rakefile. - -* Added rake_extension to handle detection of extension collisions. - -* Added a protected 'require "rubygems"' to test/test_application to - unbreak cruisecontrol.rb. - -* Removed rake\_dup. Now we just simply rescue a bad dup. - -* Refactored the FileList reject logic to remove duplication. - -* Removed if \_\_FILE\_\_ at the end of the rake.rb file. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Payton Quackenbush -- For several error handling improvements. - -* Glenn Vanderburg -- For finding and fixing the method name leak from - FileUtils. - -* Joel VanderWerf -- for finding and fixing a bug in the handling of - multiple prerequisites. - -* Tilman Sauerbeck -- For some enhancing FileList to support more - advanced file globbing. - -* Nobu Nakada -- For suggesting plain file name support to rule dependents. - --- Jim Weirich - -=== 0.7.1 - -Version 0.7.1 supplies a bug fix and a few minor enhancements. - -==== Changes - -===== Bug Fixes in 0.7.1 - -* Changes in the exception reported for the FileUtils.ln caused - safe_ln to fail with a NotImplementedError. Rake 0.7.1 will now - catch that error or any StandardError and properly fall back to - using +cp+. - -===== New Features in 0.7.1 - -* You can filter the results of the --task option by supplying an - optional regular expression. This allows the user to easily find a - particular task name in a long list of possible names. - -* Transforming procs in a rule may now return a list of prerequisites. - This allows more flexible rule formation. - -* FileList and String now support a +pathmap+ melthod that makes the - transforming paths a bit easier. See the API docs for +pathmap+ for - details. - -* The -f option without a value will disable the search for a - Rakefile. This allows the Rakefile to be defined entirely in a - library (and loaded with the -r option). The current working - directory is not changed when this is done. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* James Britt and Assaph Mehr for reporting and helping to debug the - safe_ln issue. - --- Jim Weirich - - -=== 0.7.0 - -These changes for Rake have been brewing for a long time. Here they -are, I hope you enjoy them. - -==== Changes - -===== New Features - -* Name space support for task names (see below). -* Prerequisites can be executed in parallel (see below). -* Added safe_ln support for openAFS (via Ludvig Omholt). -* RDoc defaults to internal (in-process) invocation. The old behavior - is still available by setting the +external+ flag to true. -* Rakefiles are now loaded with the expanded path to prevent - accidental pollution from the Ruby load path. -* Task objects my now be used in prerequisite lists directly. -* Task objects (in addition to task names) may now be included in the - prerequisite list of a task. -* Internals cleanup and refactoring. - -===== Bug Fixes - -* Compatibility fixes for Ruby 1.8.4 FileUtils changes. - -===== Namespaces - -Tasks can now be nested inside their own namespaces. Tasks within one -namespace will not accidentally interfer with tasks named in a different -namespace. - -For example: - - namespace "main" do - task :build do - # Build the main program - end - end - - namespace "samples" do - task :build do - # Build the sample programs - end - end - - task :build_all => ["main:build", "samples:build"] - -Even though both tasks are named :build, they are separate tasks in -their own namespaces. The :build_all task (defined in the toplevel -namespace) references both build tasks in its prerequisites. - -You may invoke each of the individual build tasks with the following -commands: - - rake main:build - rake samples:build - -Or invoke both via the :build_all command: - - rake build_all - -Namespaces may be nested arbitrarily. Since the name of file tasks -correspond to the name of a file in the external file system, -FileTasks are not affected by the namespaces. - -See the Rakefile format documentation (in the Rake API documents) for -more information. - -===== Parallel Tasks - -Sometimes you have several tasks that can be executed in parallel. By -specifying these tasks as prerequisites to a +multitask+ task. - -In the following example the tasks copy\_src, copy\_doc and copy\_bin -will all execute in parallel in their own thread. - - multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do - puts "All Copies Complete" - end - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Doug Young (inspiration for the parallel task) -* David Heinemeier Hansson (for --trace message enhancement and for - pushing for namespace support). -* Ludvig Omholt (for the openAFS fix) - --- Jim Weirich - -=== 0.6.1 - -* Rebuilt 0.6.0 gem without signing. - -=== 0.6.0 - -Its time for some long requested enhancements and lots of bug fixes -... And a whole new web page. - -==== New Web Page - -The primary documentation for rake has moved from the RubyForge based -wiki to its own Hieraki based web site. Constant spam on the wiki -made it a difficult to keep clean. The new site will be easier to -update and organize. - -Check out the new documentation at: http://docs.rubyrake.org - -We will be adding new documentation to the site as time goes on. - -In addition to the new docs page, make sure you check out Martin -Fowlers article on rake at http://martinfowler.com/articles/rake.html - -==== Changes - -===== New Features - -* Multiple prerequisites on Rake rules now allowed. However, keep the - following in mind: - - 1. All the prerequisites of a rule must be available before a rule - is triggered, where "enabled" means (a) an existing file, (b) a - defined rule, or (c) another rule which also must be - trigger-able. - 2. Rules are checked in order of definition, so it is important to - order your rules properly. If a file can be created by two - different rules, put the more specific rule first (otherwise the - more general rule will trigger first and the specific one will - never be triggered). - 3. The source method now returns the name of the first - prerequisite listed in the rule. sources returns the - names of all the rule prerequisites, ordered as they are defined - in the rule. If the task has other prerequisites not defined in - the rule (but defined in an explicit task definition), then they - will _not_ be included in the sources list. - -* FileLists may now use the egrep command. This popular enhancement - is now a core part of the FileList object. If you want to get a - list of all your to-dos, fixmes and TBD comments, add the following - to your Rakefile. - - desc "Look for TODO and FIXME tags in the code" - task :todo do - FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ - end - -* The investigation method was added to task object to dump - out some important values. This makes it a bit easier to debug Rake - tasks. - - For example, if you are having problems with a particular task, just - print it out: - - task :huh do - puts Rake::Task['huh'].investigation - end - -* The Rake::TestTask class now supports a "ruby\_opts" option to pass - arbitrary ruby options to a test subprocess. - -===== Some Incompatibilities - -* When using the ruby command to start a Ruby subprocess, the - Ruby interpreter that is currently running rake is used by default. - This makes it easier to use rake in an environment with multiple - ruby installation. (Previously, the first ruby command found in the - PATH was used). - - If you wish to chose a different Ruby interpreter, you can - explicitly choose the interpreter via the sh command. - -* The major rake classes (Task, FileTask, FileCreationTask, RakeApp) - have been moved out of the toplevel scope and are now accessible as - Rake::Task, Rake::FileTask, Rake::FileCreationTask and - Rake::Application. If your Rakefile - directly references any one of these tasks, you may: - - 1. Update your Rakefile to use the new classnames - 2. Use the --classic-namespace option on the rake command to get the - old behavior, - 3. Add require 'rake/classic_namespace' to the - Rakefile to get the old behavior. - - rake will print a rather annoying warning whenever a - deprecated class name is referenced without enabling classic - namespace. - -===== Bug Fixes - -* Several unit tests and functional tests were fixed to run better - under windows. - -* Directory tasks are now a specialized version of a File task. A - directory task will only be triggered if it doesn't exist. It will - not be triggered if it is out of date w.r.t. any of its - prerequisites. - -* Fixed a bug in the Rake::GemPackageTask class so that the gem now - properly contains the platform name. - -* Fixed a bug where a prerequisite on a file task would cause - an exception if the prerequisite did not exist. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -The following people either contributed patches, made suggestions or -made otherwise helpful comments. Thanks to ... - -* Greg Fast (better ruby_opt test options) -* Kelly Felkins (requested by better namespace support) -* Martin Fowler (suggested Task.investigation) -* Stuart Jansen (send initial patch for multiple prerequisites). -* Masao Mutch (better support for non-ruby Gem platforms) -* Philipp Neubeck (patch for file task exception fix) - --- Jim Weirich - -=== 0.5.4 - -Time for some minor bug fixes and small enhancements - -==== Changes - -Here are the changes for version 0.5.4 ... - -* Added double quotes to the test runner. This allows the location of - the tests (and runner) to be in a directory path that contains - spaces (e.g. "C:/Program Files/ruby/bin"). -* Added .svn to default ignore list. Now subversion project metadata - is automatically ignored by Rake's FileList. -* Updated FileList#include to support nested arrays and filelists. - FileLists are flat lists of file names. Using a FileList in an - include will flatten out the nested file names. - -== Thanks - -As usual, it was input from users that drove a alot of these changes. -Thanks to ... - -* Tilman Sauerbeck for the nested FileList suggestion. -* Josh Knowles for pointing out the spaces in directory name problem. - --- Jim Weirich - -=== 0.5.3 - -Although it has only been two weeks since the last release, we have -enough updates to the Rake program to make it time for another -release. - -==== Changes - -Here are the changes for version 0.5.3 ... - -* FileLists have been extensively changed so that they mimic the - behavior of real arrays even more closely. In particular, - operations on FileLists that return a new collection (e.g. collect, - reject) will now return a FileList rather than an array. In - addition, several places where FileLists were not properly expanded - before use have been fixed. -* A method (+ext+) to simplify the handling of file extensions was - added to String and to Array. -* The 'testrb' script in test/unit tends to silently swallow syntax - errors in test suites. Because of that, the default test loader is - now a rake-provided script. You can still use 'testrb' by setting - the loader flag in the test task to :testrb. (See the API documents - for TestTask for all the loader flag values). -* FileUtil methods (e.g. cp, mv, install) are now declared to be - private. This will cut down on the interference with user defined - methods of the same name. -* Fixed the verbose flag in the TestTask so that the test code is - controlled by the flag. Also shortened up some failure messages. - (Thanks to Tobias Luetke for the suggestion). -* Rules will now properly detect a task that can generate a source - file. Previously rules would only consider source files that were - already present. -* Added an +import+ command that allows Rake to dynamically import - dependendencies into a running Rake session. The +import+ command - can run tasks to update the dependency file before loading them. - Dependency files can be in rake or make format, allowing rake to - work with tools designed to generate dependencies for make. - -==== Thanks - -As usual, it was input from users that drove a alot of these changes. -Thanks to ... - -* Brian Gernhardt for the rules fix (especially for the patience to - explain the problem to me until I got what he was talking about). -* Stefan Lang for pointing out problems in the dark corners of the - FileList implementation. -* Alexey Verkhovsky pointing out the silently swallows syntax errors - in tests. -* Tobias Luetke for beautifying the test task output. -* Sam Roberts for some of the ideas behind dependency loading. - --- Jim Weirich - - -=== 0.5.0 - -It has been a long time in coming, but we finally have a new version -of Rake available. - -==== Changes - -* Fixed documentation that was lacking the Rake module name (Tilman - Sauerbeck). -* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). -* Recursive rules are now supported (Tilman Sauerbeck). -* Added warning option for the Test Task (requested by Eric Hodel). -* The jamis rdoc template is only used if it exists. -* Added fix for Ruby 1.8.2 test/unit and rails problem. -* Added contributed rake man file (Jani Monoses). -* Added Brian Candler's fix for problems in --trace and --dry-run - mode. - -==== Thanks - -Lots of people provided input to this release. Thanks to Tilman -Sauerbeck for numerous patches, documentation fixes and suggestions. -And for also pushing me to get this release out. Also, thanks to -Brian Candler for the finding and fixing --trace/dry-run fix. That -was an obscure bug. Also to Eric Hodel for some good suggestions. - --- Jim Weirich - -=== 0.4.15 - -==== Changes - -Version 0.4.15 is a bug fix update for the Ruby 1.8.2 compatibility -changes. This release includes: - -* Fixed a bug that prevented the TESTOPTS flag from working with the - revised for 1.8.2 test task. -* Updated the docs on --trace to indicate that it also enables a full - backtrace on errors. -* Several fixes for new warnings generated. - -==== Mini-Roadmap - -I will continue to issue Rake updates in the 0.4.xx series as new -Ruby-1.8.2 issues become manifest. Once the codebase stabilizes, I -will release a 0.5.0 version incorporating all the changes. If you -are not using Ruby-1.8.2 and wish to avoid version churn, I recommend -staying with a release prior to Rake-0.4.14. - -=== 0.4.14 - -Version 0.4.14 is a compatibility fix to allow Rake's test task to -work under Ruby 1.8.2. A change in the Test::Unit autorun feature -prevented Rake from running any tests. This release fixes the -problem. - -Rake 0.4.14 is the recommended release for anyone using Ruby 1.8.2. - -=== 0.4.13 - -* Fixed the dry-run flag so it is operating again. -* Multiple arguments to sh and ruby commands will not be interpreted - by the shell (patch provided by Jonathan Paisley). - -=== 0.4.12 - -* Added --silent (-s) to suppress the (in directory) rake message. - -=== 0.4.11 - -* Changed the "don't know how to rake" message (finally) -* Changes references to a literal "Rakefile" to reference the global - variable $rakefile (which contains the actual name of the rakefile). - -=== 0.4.10 - -* Added block support to the "sh" command, allowing users to take - special actions on the result of the system call. E.g. - - sh "shell_command" do |ok, res| - puts "Program returned #{res.exitstatus}" if ! ok - end - -=== 0.4.9 - -* Switched to Jamis Buck's RDoc template. -* Removed autorequire from Rake's gem spec. This prevents the Rake - libraries from loading while using rails. - -=== 0.4.8 - -* Added support for .rb versions of Rakefile. -* Removed \\\n's from test task. -* Fixed Ruby 1.9 compatibility issue with FileList. - -=== 0.4.7 - -* Fixed problem in FileList that caused Ruby 1.9 to go into infinite - recursion. Since to_a was removed from Object, it does not need to - added back into the list of methods to rewrite in FileList. (Thanks - to Kent Sibilev for pointing this out). - -=== 0.4.6 -* Removed test version of ln in FileUtils that prevented safe_ln from - using ln. - -=== 0.4.5 -* Upgraded comments in TestTask. -* FileList to_s and inspect now automatically resolve pending changes. -* FileList#exclude properly returns the FileList. - -=== 0.4.4 -* Fixed initialization problem with @comment. -* Now using multi -r technique in TestTask. Switch Rakefile back to - using the built-in test task macros because the rake runtime is no - longer needed. -* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task - macros. -* Allow a +test_files+ attribute in test tasks. This allows more - flexibility in specifying test files. - -=== 0.4.3 -* Fixed Comment leakage. - -=== 0.4.2 -* Added safe_ln that falls back to a copy if a file link is not supported. -* Package builder now uses safe\_ln. - -=== 0.4.1 -* Task comments are now additive, combined with "/". -* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0) - -=== 0.4.0 -* FileList now uses deferred loading. The file system is not searched - until the first call that needs the file names. -* VAR=VALUE options are now accepted on the command line and are - treated like environment variables. The values may be tested in a - Rakefile by referencing ENV['VAR']. -* File.mtime is now used (instead of File.new().mtime). - -=== 0.3.2.x - -* Removed some hidden dependencies on rubygems. Tests now will test - gems only if they are installed. -* Removed Sys from some example files. I believe that is that last - reference to Sys outside of the contrib area. -* Updated all copyright notices to include 2004. - -=== 0.3.2 - -* GEM Installation now works with the application stub. - -=== 0.3.1 - -* FileLists now automatically ignore CVS, .bak, ! -* GEM Installation now works. - -=== 0.3.0 - -Promoted 0.2.10. - -=== 0.2.10 -General - -* Added title to Rake's rdocs -* Contrib packages are no longer included in the documentation. - -RDoc Issues - -* Removed default for the '--main' option -* Fixed rendering of the rdoc options -* Fixed clean/clobber confusion with rerdoc -* 'title' attribute added - -Package Task Library Issues - -* Version (or explicit :noversion) is required. -* +package_file+ attribute is now writable - -FileList Issues - -* Dropped bang version of exclude. Now using ant-like include/exclude semantics. -* Enabled the "yield self" idiom in FileList#initialize. - -=== 0.2.9 - -This version contains numerous changes as the RubyConf.new(2003) -presentation was being prepared. The changes include: - -* The monolithic rubyapp task library is in the process of being - dropped in favor of lighter weight task libraries. - -=== 0.2.7 - -* Added "desc" for task descriptions. -* -T will now display tasks with descriptions. -* -P will display tasks and prerequisites. -* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys - is still supported in the contrib area. - -=== 0.2.6 - -* Moved to RubyForge - -=== 0.2.5 - -* Switched to standard ruby app builder. -* Added no_match option to file matcher. - -=== 0.2.4 - -* Fixed indir, which neglected to actually change directories. - -=== 0.2.3 - -* Added rake module for a help target -* Added 'for\_files' to Sys -* Added a $rakefile constant -* Added test for selecting proper rule with multiple targets. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/MIT-LICENSE b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/MIT-LICENSE deleted file mode 100644 index 4292f3b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) Jim Weirich - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/README.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/README.rdoc deleted file mode 100644 index 3fc72db..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/README.rdoc +++ /dev/null @@ -1,155 +0,0 @@ -= RAKE -- Ruby Make - -home :: https://github.com/ruby/rake -bugs :: https://github.com/ruby/rake/issues -docs :: https://ruby.github.io/rake - -== Description - -Rake is a Make-like program implemented in Ruby. Tasks and dependencies are -specified in standard Ruby syntax. - -Rake has the following features: - -* Rakefiles (rake's version of Makefiles) are completely defined in - standard Ruby syntax. No XML files to edit. No quirky Makefile - syntax to worry about (is that a tab or a space?) - -* Users can specify tasks with prerequisites. - -* Rake supports rule patterns to synthesize implicit tasks. - -* Flexible FileLists that act like arrays but know about manipulating - file names and paths. - -* A library of prepackaged tasks to make building rakefiles easier. For example, - tasks for building tarballs. (Formerly - tasks for building RDoc, Gems, and publishing to FTP were included in rake but they're now - available in RDoc, RubyGems, and rake-contrib respectively.) - -* Supports parallel execution of tasks. - -== Installation - -=== Gem Installation - -Download and install rake with the following. - - gem install rake - -== Usage - -=== Simple Example - -First, you must write a "Rakefile" file which contains the build rules. Here's -a simple example: - - task default: %w[test] - - task :test do - ruby "test/unittest.rb" - end - -This Rakefile has two tasks: - -* A task named "test", which -- upon invocation -- will run a unit test file - in Ruby. -* A task named "default". This task does nothing by itself, but it has exactly - one dependency, namely the "test" task. Invoking the "default" task will - cause Rake to invoke the "test" task as well. - -Running the "rake" command without any options will cause it to run the -"default" task in the Rakefile: - - % ls - Rakefile test/ - % rake - (in /home/some_user/Projects/rake) - ruby test/unittest.rb - ....unit test output here... - -Type "rake --help" for all available options. - -== Resources - -=== Rake Information - -* {Rake command-line}[link:doc/command_line_usage.rdoc] -* {Writing Rakefiles}[link:doc/rakefile.rdoc] -* The original {Rake announcement}[link:doc/rational.rdoc] -* Rake {glossary}[link:doc/glossary.rdoc] - -=== Presentations and Articles about Rake - -* Avdi Grimm's rake series: - 1. {Rake Basics}[https://avdi.codes/rake-part-1-basics/] - 2. {Rake File Lists}[https://avdi.codes/rake-part-2-file-lists-2/] - 3. {Rake Rules}[https://avdi.codes/rake-part-3-rules/] - 4. {Rake Pathmap}[https://avdi.codes/rake-part-4-pathmap/] - 5. {File Operations}[https://avdi.codes/rake-part-5-file-operations/] - 6. {Clean and Clobber}[https://avdi.codes/rake-part-6-clean-and-clobber/] - 7. {MultiTask}[https://avdi.codes/rake-part-7-multitask/] -* {Jim Weirich's 2003 RubyConf presentation}[https://web.archive.org/web/20140221123354/http://onestepback.org/articles/buildingwithrake/] -* Martin Fowler's article on Rake: https://martinfowler.com/articles/rake.html - -== Other Make Re-envisionings ... - -Rake is a late entry in the make replacement field. Here are links to -other projects with similar (and not so similar) goals. - -* https://directory.fsf.org/wiki/Bras -- Bras, one of earliest - implementations of "make in a scripting language". -* http://www.a-a-p.org -- Make in Python -* https://ant.apache.org -- The Ant project -* https://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System -* https://www.rubydoc.info/gems/rant/0.5.7/frames -- Rant, another Ruby make tool. - -== Credits - -[Jim Weirich] Who originally created Rake. - -[Ryan Dlugosz] For the initial conversation that sparked Rake. - -[Nobuyoshi Nakada ] For the initial patch for rule support. - -[Tilman Sauerbeck ] For the recursive rule patch. - -[Eric Hodel] For aid in maintaining rake. - -[Hiroshi SHIBATA] Maintainer of Rake 10 and later - -== License - -Rake is available under an MIT-style license. - -:include: MIT-LICENSE - ---- - -= Other stuff - -Author:: Jim Weirich -Requires:: Ruby 2.0.0 or later -License:: Copyright Jim Weirich. - Released under an MIT-style license. See the MIT-LICENSE - file included in the distribution. - -== Warranty - -This software is provided "as is" and without any express or implied -warranties, including, without limitation, the implied warranties of -merchantability and fitness for a particular purpose. - -== Historical - -Rake was originally created by Jim Weirich, who unfortunately passed away in -February 2014. This repository was originally hosted at -{github.com/jimweirich/rake}[https://github.com/jimweirich/rake/], however -with his passing, has been moved to {ruby/rake}[https://github.com/ruby/rake]. - -You can view Jim's last commit here: -https://github.com/jimweirich/rake/tree/336559f28f55bce418e2ebcc0a57548dcbac4025 - -You can {read more about Jim}[https://en.wikipedia.org/wiki/Jim_Weirich] at Wikipedia. - -Thank you for this great tool, Jim. We'll remember you. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/command_line_usage.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/command_line_usage.rdoc deleted file mode 100644 index 105d6c8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/command_line_usage.rdoc +++ /dev/null @@ -1,158 +0,0 @@ -= Rake Command Line Usage - -Rake is invoked from the command line using: - - % rake [options ...] [VAR=VALUE ...] [targets ...] - -Options are: - -[name=value] - Set the environment variable name to value - during the execution of the rake command. You can access - the value by using ENV['name']. - -[--all (-A)] - Used in combination with the -T and -D options, will force - those options to show all the tasks, even the ones without comments. - -[--backtrace{=_output_} (-n)] - Enable a full backtrace (i.e. like --trace, but without the task - tracing details). The _output_ parameter is optional, but if - specified it controls where the backtrace output is sent. If - _output_ is stdout, then backtrace output is directed to - standard output. If _output_ is stderr, or if it is - missing, then the backtrace output is sent to standard error. - -[--comments] - Used in combination with the -W options to force the output to - contain commented options only. This is the reverse of - --all. - -[--describe _pattern_ (-D)] - Describe the tasks (matching optional PATTERN), then exit. - -[--dry-run (-n)] - Do a dry run. Print the tasks invoked and executed, but do not - actually execute any of the actions. - -[--execute _code_ (-e)] - Execute some Ruby code and exit. - -[--execute-print _code_ (-p)] - Execute some Ruby code, print the result, and exit. - -[--execute-continue _code_ (-E)] - Execute some Ruby code, then continue with normal task processing. - -[--help (-H)] - Display some help text and exit. - -[--jobs _number_ (-j)] - - Specifies the maximum number of concurrent threads allowed. Rake - will allocate threads as needed up to this maximum number. - - If omitted, Rake will attempt to estimate the number of CPUs on - the system and add 4 to that number. - - The concurrent threads are used to execute the multitask - prerequisites. Also see the -m option which turns all - tasks into multitasks. - - Sample values: - (no -j) : Allow up to (# of CPUs + 4) number of threads - --jobs : Allow unlimited number of threads - --jobs=1 : Allow only one thread (the main thread) - --jobs=16 : Allow up to 16 concurrent threads - -[--job-stats _level_] - - Display job statistics at the completion of the run. By default, - this will display the requested number of active threads (from the - -j options) and the maximum number of threads in play at any given - time. - - If the optional _level_ is history, then a complete trace - of task history will be displayed on standard output. - -[--libdir _directory_ (-I)] - Add _directory_ to the list of directories searched for require. - -[--multitask (-m)] - Treat all tasks as multitasks. ('make/drake' semantics) - -[--nosearch (-N)] - Do not search for a Rakefile in parent directories. - -[--prereqs (-P)] - Display a list of all tasks and their immediate prerequisites. - -[--quiet (-q)] - Do not echo commands from FileUtils. - -[--rakefile _filename_ (-f)] - Use _filename_ as the name of the rakefile. The default rakefile - names are +rakefile+ and +Rakefile+ (with +rakefile+ taking - precedence). If the rakefile is not found in the current - directory, +rake+ will search parent directories for a match. The - directory where the Rakefile is found will become the current - directory for the actions executed in the Rakefile. - -[--rakelibdir _rakelibdir_ (-R)] - Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') - -[--require _name_ (-r)] - Require _name_ before executing the Rakefile. - -[--rules] - Trace the rules resolution. - -[--silent (-s)] - Like --quiet, but also suppresses the 'in directory' announcement. - -[--suppress-backtrace _pattern_ ] - Line matching the regular expression _pattern_ will be removed - from the backtrace output. Note that the --backtrace option is the - full backtrace without these lines suppressed. - -[--system (-g)] - Use the system wide (global) rakefiles. The project Rakefile is - ignored. By default, the system wide rakefiles are used only if no - project Rakefile is found. On Unix-like system, the system wide - rake files are located in $HOME/.rake. On a windows system they - are stored in $APPDATA/Rake. - -[--no-system (-G)] - Use the project level Rakefile, ignoring the system-wide (global) - rakefiles. - -[--tasks pattern (-T)] - Display a list of the major tasks and their comments. Comments - are defined using the "desc" command. If a pattern is given, then - only tasks matching the pattern are displayed. - -[--trace{=_output_} (-t)] - Turn on invoke/execute tracing. Also enable full backtrace on - errors. The _output_ parameter is optional, but if specified it - controls where the trace output is sent. If _output_ is - stdout, then trace output is directed to standard output. - If _output_ is stderr, or if it is missing, then trace - output is sent to standard error. - -[--verbose (-v)] - Echo the Sys commands to standard output. - -[--version (-V)] - Display the program version and exit. - -[--where pattern (-W)] - Display tasks that match pattern and the file and line - number where the task is defined. By default this option will - display all tasks, not just the tasks that have descriptions. - -[--no-deprecation-warnings (-X)] - Do not display the deprecation warnings. - -In addition, any command line option of the form -VAR=VALUE will be added to the environment hash -ENV and may be tested in the Rakefile. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile1 b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile1 deleted file mode 100644 index 39f8bcc..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile1 +++ /dev/null @@ -1,38 +0,0 @@ -# Example Rakefile -*- ruby -*- - -task :default => [:main] - -file "a.o" => ["a.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -file "b.o" => ["b.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -file "main.o" => ["main.c"] do |t| - src = t.name.sub(/\.o$/, '.c') - sh "gcc #{src} -c -o #{t.name}" -end - -OBJFILES = ["a.o", "b.o", "main.o"] -task :obj => OBJFILES - -file "main" => OBJFILES do |t| - sh "gcc -o #{t.name} main.o a.o b.o" -end - -task :clean do - rm_f FileList['*.o'] - Dir['*~'].each { |fn| rm_f fn } -end - -task :clobber => [:clean] do - rm_f "main" -end - -task :run => ["main"] do - sh "./main" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile2 b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile2 deleted file mode 100644 index 35310ec..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/Rakefile2 +++ /dev/null @@ -1,35 +0,0 @@ -# Example Rakefile -*- ruby -*- -# Using the power of Ruby - -task :default => [:main] - -def ext(fn, newext) - fn.sub(/\.[^.]+$/, newext) -end - -SRCFILES = Dir['*.c'] -OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") } - -OBJFILES.each do |objfile| - srcfile = ext(objfile, ".c") - file objfile => [srcfile] do |t| - sh "gcc #{srcfile} -c -o #{t.name}" - end -end - -file "main" => OBJFILES do |t| - sh "gcc -o #{t.name} main.o a.o b.o" -end - -task :clean do - rm_f FileList['*.o'] - Dir['*~'].each { |fn| rm_f fn } -end - -task :clobber => [:clean] do - rm_f "main" -end - -task :run => ["main"] do - sh "./main" -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/a.c b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/a.c deleted file mode 100644 index 620e6f8..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/a.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void a() -{ - printf ("In function a\n"); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/b.c b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/b.c deleted file mode 100644 index 9b24aa1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/b.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -void b() -{ - printf ("In function b\n"); -} diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/main.c b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/main.c deleted file mode 100644 index a04558a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/example/main.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -extern void a(); -extern void b(); - -int main () -{ - a(); - b(); - return 0; -} diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/glossary.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/glossary.rdoc deleted file mode 100644 index 9d592b0..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/glossary.rdoc +++ /dev/null @@ -1,42 +0,0 @@ -= Glossary - -action :: - Code to be executed in order to perform a task. Actions in a Rakefile are - specified in a code block. (Usually delimited by +do+/+end+ pairs.) - -execute :: - When a task is executed, all of its actions are performed in the order they - were defined. Note that, unlike invoke, execute always - executes the actions (without invoking or executing the prerequisites). - -file task (Rake::FileTask) :: - A file task is a task whose purpose is to create a file (which has the same - name as the task). When invoked, a file task will only execute if one or - more of the following conditions are true. - - 1. The associated file does not exist. - 2. A prerequisite has a later time stamp than the existing file. - - Because normal Tasks always have the current time as timestamp, a FileTask - that has a normal Task prerequisite will always execute. - -invoke :: - When a task is invoked, first we check to see if it has been invoked before. - If it has been, then nothing else is done. If this is the first time it has - been invoked, then we invoke each of its prerequisites. Finally, we check - to see if we need to execute the actions of this task by calling - Rake::Task#needed?. If the task is needed, we execute its actions. - - NOTE: Prerequisites are still invoked even if the task is not needed. - -prerequisites :: - Every task has a (possibly empty) set of prerequisites. A prerequisite P to - Task T is itself a task that must be invoked before Task T. - -rule :: - A rule is a recipe for synthesizing a task when no task is explicitly - defined. Rules generally synthesize file tasks. - -task (Rake::Task) :: - The basic unit of work in a Rakefile. A task has a name, a set of - prerequisites, and a list of actions to be performed. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/jamis.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/jamis.rb deleted file mode 100644 index 531aa75..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/jamis.rb +++ /dev/null @@ -1,592 +0,0 @@ -# frozen_string_literal: true -module RDoc -module Page - -FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" - -STYLE = < pre { - padding: 0.5em; - border: 1px dotted black; - background: #FFE; -} - -CSS - -XHTML_PREAMBLE = %{ - -} - -HEADER = XHTML_PREAMBLE + < - - %title% - - - - - - - -ENDHEADER - -FILE_PAGE = < - - - - -
File
%short_name%
- - - - - - - - - -
Path:%full_path% -IF:cvsurl -  (CVS) -ENDIF:cvsurl -
Modified:%dtm_modified%
-
- -
-HTML - -################################################################### - -CLASS_PAGE = < - %classmod%
%full_name% - - - - - - -IF:parent - - - - -ENDIF:parent -
In: -START:infiles -HREF:full_path_url:full_path: -IF:cvsurl - (CVS) -ENDIF:cvsurl -END:infiles -
Parent: -IF:par_url - -ENDIF:par_url -%parent% -IF:par_url - -ENDIF:par_url -
- - - -HTML - -################################################################### - -METHOD_LIST = < -IF:diagram -
- %diagram% -
-ENDIF:diagram - -IF:description -
%description%
-ENDIF:description - -IF:requires -
Required Files
-
    -START:requires -
  • HREF:aref:name:
  • -END:requires -
-ENDIF:requires - -IF:toc -
Contents
- -ENDIF:toc - -IF:methods -
Methods
-
    -START:methods -
  • HREF:aref:name:
  • -END:methods -
-ENDIF:methods - -IF:includes -
Included Modules
-
    -START:includes -
  • HREF:aref:name:
  • -END:includes -
-ENDIF:includes - -START:sections -IF:sectitle - -IF:seccomment -
-%seccomment% -
-ENDIF:seccomment -ENDIF:sectitle - -IF:classlist -
Classes and Modules
- %classlist% -ENDIF:classlist - -IF:constants -
Constants
- -START:constants - - - - - -IF:desc - - - - -ENDIF:desc -END:constants -
%name%=%value%
 %desc%
-ENDIF:constants - -IF:attributes -
Attributes
- -START:attributes - - - - - -END:attributes -
-IF:rw -[%rw%] -ENDIF:rw - %name%%a_desc%
-ENDIF:attributes - -IF:method_list -START:method_list -IF:methods -
%type% %category% methods
-START:methods -
-
-IF:callseq - %callseq% -ENDIF:callseq -IFNOT:callseq - %name%%params% -ENDIF:callseq -IF:codeurl -[ source ] -ENDIF:codeurl -
-IF:m_desc -
- %m_desc% -
-ENDIF:m_desc -IF:aka -
- This method is also aliased as -START:aka - %name% -END:aka -
-ENDIF:aka -IF:sourcecode -
- -
-
-%sourcecode%
-
-
-
-ENDIF:sourcecode -
-END:methods -ENDIF:methods -END:method_list -ENDIF:method_list -END:sections - -HTML - -FOOTER = < - -ENDFOOTER - -BODY = HEADER + < - -
- #{METHOD_LIST} -
- - #{FOOTER} -ENDBODY - -########################## Source code ########################## - -SRC_PAGE = XHTML_PREAMBLE + < -%title% - - - - -
%code%
- - -HTML - -########################## Index ################################ - -FR_INDEX_BODY = < - - - - - - - -
-START:entries -%name%
-END:entries -
- -HTML - -CLASS_INDEX = FILE_INDEX -METHOD_INDEX = FILE_INDEX - -INDEX = XHTML_PREAMBLE + < - - %title% - - - - - - - - - -IF:inline_source - -ENDIF:inline_source -IFNOT:inline_source - - - - -ENDIF:inline_source - - <body bgcolor="white"> - Click <a href="html/index.html">here</a> for a non-frames - version of this page. - </body> - - - - -HTML - -end -end - - diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/proto_rake.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/proto_rake.rdoc deleted file mode 100644 index a9e33d1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/proto_rake.rdoc +++ /dev/null @@ -1,127 +0,0 @@ -= Original Prototype Rake - -This is the original 100 line prototype rake program. - ---- - #!/usr/bin/env ruby - - require 'ftools' - - class Task - TASKS = Hash.new - - attr_reader :prerequisites - - def initialize(task_name) - @name = task_name - @prerequisites = [] - @actions = [] - end - - def enhance(deps=nil, &block) - @prerequisites |= deps if deps - @actions << block if block_given? - self - end - - def name - @name.to_s - end - - def invoke - @prerequisites.each { |n| Task[n].invoke } - execute if needed? - end - - def execute - return if @triggered - @triggered = true - @actions.collect { |act| result = act.call(self) }.last - end - - def needed? - true - end - - def timestamp - Time.now - end - - class << self - def [](task_name) - TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}" - end - - def define_task(args, &block) - case args - when Hash - fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1 - fail "No Task Name Given" if args.size < 1 - task_name = args.keys[0] - deps = args[task_name] - else - task_name = args - deps = [] - end - deps = deps.collect {|d| intern(d) } - get(task_name).enhance(deps, &block) - end - - def get(task_name) - name = intern(task_name) - TASKS[name] ||= self.new(name) - end - - def intern(task_name) - (Symbol === task_name) ? task_name : task_name.intern - end - end - end - - class FileTask < Task - def needed? - return true unless File.exist?(name) - latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max - return false if latest_prereq.nil? - timestamp < latest_prereq - end - - def timestamp - File.new(name.to_s).mtime - end - end - - def task(args, &block) - Task.define_task(args, &block) - end - - def file(args, &block) - FileTask.define_task(args, &block) - end - - def sys(cmd) - puts cmd - system(cmd) or fail "Command Failed: [#{cmd}]" - end - - def rake - begin - here = Dir.pwd - while ! File.exist?("Rakefile") - Dir.chdir("..") - fail "No Rakefile found" if Dir.pwd == here - here = Dir.pwd - end - puts "(in #{Dir.pwd})" - load "./Rakefile" - ARGV.push("default") if ARGV.size == 0 - ARGV.each { |task_name| Task[task_name].invoke } - rescue Exception => ex - puts "rake aborted ... #{ex.message}" - puts ex.backtrace.find {|str| str =~ /Rakefile/ } || "" - end - end - - if __FILE__ == $0 then - rake - end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rake.1 b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rake.1 deleted file mode 100644 index c6bfa25..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rake.1 +++ /dev/null @@ -1,156 +0,0 @@ -.Dd June 12, 2016 -.Dt RAKE 1 -.Os rake 11.2.2 -.Sh NAME -.Nm rake -.Nd make-like build utility for Ruby -.Sh SYNOPSIS -.Nm -.Op Fl f Ar rakefile -.Op Ar options -.Ar targets ... -.Sh DESCRIPTION -.Nm -is a -.Xr make 1 Ns -like -build utility for Ruby. -Tasks and dependencies are specified in standard Ruby syntax. -.Sh OPTIONS -.Bl -tag -width Ds -.It Fl m , Fl -multitask -Treat all tasks as multitasks. -.It Fl B , Fl -build-all -Build all prerequisites, including those which are up\-to\-date. -.It Fl j , Fl -jobs Ar num_jobs -Specifies the maximum number of tasks to execute in parallel (default is number of CPU cores + 4). -.El -.Ss Modules -.Bl -tag -width Ds -.It Fl I , Fl -libdir Ar libdir -Include -.Ar libdir -in the search path for required modules. -.It Fl r , Fl -require Ar module -Require -.Ar module -before executing -.Pa rakefile . -.El -.Ss Rakefile location -.Bl -tag -width Ds -.It Fl f , Fl -rakefile Ar filename -Use -.Ar filename -as the rakefile to search for. -.It Fl N , Fl -no-search , Fl -nosearch -Do not search parent directories for the Rakefile. -.It Fl G , Fl -no-system , Fl -nosystem -Use standard project Rakefile search paths, ignore system wide rakefiles. -.It Fl R , Fl -rakelib Ar rakelibdir , Fl -rakelibdir Ar rakelibdir -Auto-import any .rake files in -.Ar rakelibdir -(default is -.Sq rakelib ) -.It Fl g , Fl -system -Use system-wide (global) rakefiles (usually -.Pa ~/.rake/*.rake ) . -.El -.Ss Debugging -.Bl -tag -width Ds -.It Fl -backtrace Ns = Ns Ar out -Enable full backtrace. -.Ar out -can be -.Dv stderr -(default) or -.Dv stdout . -.It Fl t , Fl -trace Ns = Ns Ar out -Turn on invoke/execute tracing, enable full backtrace. -.Ar out -can be -.Dv stderr -(default) or -.Dv stdout . -.It Fl -suppress-backtrace Ar pattern -Suppress backtrace lines matching regexp -.Ar pattern . -Ignored if -.Fl -trace -is on. -.It Fl -rules -Trace the rules resolution. -.It Fl n , Fl -dry-run -Do a dry run without executing actions. -.It Fl T , Fl -tasks Op Ar pattern -Display the tasks (matching optional -.Ar pattern ) -with descriptions, then exit. -.It Fl D , Fl -describe Op Ar pattern -Describe the tasks (matching optional -.Ar pattern ) , -then exit. -.It Fl W , Fl -where Op Ar pattern -Describe the tasks (matching optional -.Ar pattern ) , -then exit. -.It Fl P , Fl -prereqs -Display the tasks and dependencies, then exit. -.It Fl e , Fl -execute Ar code -Execute some Ruby code and exit. -.It Fl p , Fl -execute-print Ar code -Execute some Ruby code, print the result, then exit. -.It Fl E , Fl -execute-continue Ar code -Execute some Ruby code, then continue with normal task processing. -.El -.Ss Information -.Bl -tag -width Ds -.It Fl v , Fl -verbose -Log message to standard output. -.It Fl q , Fl -quiet -Do not log messages to standard output. -.It Fl s , Fl -silent -Like -.Fl -quiet , -but also suppresses the -.Sq in directory -announcement. -.It Fl X , Fl -no-deprecation-warnings -Disable the deprecation warnings. -.It Fl -comments -Show commented tasks only -.It Fl A , Fl -all -Show all tasks, even uncommented ones (in combination with -.Fl T -or -.Fl D ) -.It Fl -job-stats Op Ar level -Display job statistics. -If -.Ar level -is -.Sq history , -displays a complete job list. -.It Fl V , Fl -version -Display the program version. -.It Fl h , Fl H , Fl -help -Display a help message. -.El -.Sh SEE ALSO -The complete documentation for -.Nm rake -has been installed at -.Pa /usr/share/doc/rake-doc/html/index.html . -It is also available online at -.Lk https://ruby.github.io/rake . -.Sh AUTHORS -.An -nosplit -.Nm -was written by -.An Jim Weirich Aq Mt jim@weirichhouse.org . -.Pp -This manual was created by -.An Caitlin Matos Aq Mt caitlin.matos@zoho.com -for the Debian project (but may be used by others). -It was inspired by the manual by -.An Jani Monoses Aq Mt jani@iv.ro -for the Ubuntu project. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rakefile.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rakefile.rdoc deleted file mode 100644 index 4014306..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rakefile.rdoc +++ /dev/null @@ -1,622 +0,0 @@ -= Rakefile Format - -First of all, there is no special format for a Rakefile. A Rakefile -contains executable Ruby code. Anything legal in a ruby script is -allowed in a Rakefile. - -Now that we understand there is no special syntax in a Rakefile, there -are some conventions that are used in a Rakefile that are a little -unusual in a typical Ruby program. Since a Rakefile is tailored to -specifying tasks and actions, the idioms used in a Rakefile are -designed to support that. - -So, what goes into a Rakefile? - -== Tasks - -Tasks are the main unit of work in a Rakefile. Tasks have a name -(usually given as a symbol or a string), a list of prerequisites (more -symbols or strings) and a list of actions (given as a block). - -=== Simple Tasks - -A task is declared by using the +task+ method. +task+ takes a single -parameter that is the name of the task. - - task :name - -=== Tasks with Prerequisites - -Any prerequisites are given as a list (enclosed in square brackets) -following the name and an arrow (=>). - - task name: [:prereq1, :prereq2] - -*NOTE:* Although this syntax looks a little funky, it is legal -Ruby. We are constructing a hash where the key is :name and the value -for that key is the list of prerequisites. It is equivalent to the -following ... - - hash = Hash.new - hash[:name] = [:prereq1, :prereq2] - task(hash) - -You can also use strings for task names and prerequisites, rake doesn't care. -This is the same task definition: - - task 'name' => %w[prereq1 prereq2] - -As is this: - - task name: %w[prereq1 prereq2] - -We'll prefer this style for regular tasks with prerequisites throughout the -rest of the document. Using an array of strings for the prerequisites means -you will need to make fewer changes if you need to move tasks into namespaces -or perform other refactorings. - -=== Tasks with Actions - -Actions are defined by passing a block to the +task+ method. Any Ruby -code can be placed in the block. The block may reference the task -object via the block parameter. - - task name: [:prereq1, :prereq2] do |t| - # actions (may reference t) - end - -=== Multiple Definitions - -A task may be specified more than once. Each specification adds its -prerequisites and actions to the existing definition. This allows one -part of a rakefile to specify the actions and a different rakefile -(perhaps separately generated) to specify the dependencies. - -For example, the following is equivalent to the single task -specification given above. - - task :name - task name: :prereq1 - task name: %w[prereq2] - task :name do |t| - # actions - end - -== File Tasks - -Some tasks are designed to create a file from one or more other files. -Tasks that generate these files may be skipped if the file already -exists. File tasks are used to specify file creation tasks. - -File tasks are declared using the +file+ method (instead of the +task+ -method). In addition, file tasks are usually named with a string -rather than a symbol. - -The following file task creates a executable program (named +prog+) -given two object files named +a.o+ and +b.o+. The tasks -for creating +a.o+ and +b.o+ are not shown. - - file "prog" => ["a.o", "b.o"] do |t| - sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" - end - -== Directory Tasks - -It is common to need to create directories upon demand. The -+directory+ convenience method is a short-hand for creating a FileTask -that creates the directory. For example, the following declaration -... - - directory "testdata/examples/doc" - -is equivalent to ... - - file "testdata" do |t| mkdir t.name end - file "testdata/examples" => ["testdata"] do |t| mkdir t.name end - file "testdata/examples/doc" => ["testdata/examples"] do |t| mkdir t.name end - -The +directory+ method does not accept prerequisites or actions, but -both prerequisites and actions can be added later. For example ... - - directory "testdata" - file "testdata" => ["otherdata"] - file "testdata" do - cp Dir["standard_data/*.data"], "testdata" - end - -== Tasks with Parallel Prerequisites - -Rake allows parallel execution of prerequisites using the following syntax: - - multitask copy_files: %w[copy_src copy_doc copy_bin] do - puts "All Copies Complete" - end - -In this example, +copy_files+ is a normal rake task. Its actions are -executed whenever all of its prerequisites are done. The big -difference is that the prerequisites (+copy_src+, +copy_bin+ and -+copy_doc+) are executed in parallel. Each of the prerequisites are -run in their own Ruby thread, possibly allowing faster overall runtime. - -=== Secondary Prerequisites - -If any of the primary prerequisites of a multitask have common secondary -prerequisites, all of the primary/parallel prerequisites will wait -until the common prerequisites have been run. - -For example, if the copy_xxx tasks have the -following prerequisites: - - task copy_src: :prep_for_copy - task copy_bin: :prep_for_copy - task copy_doc: :prep_for_copy - -Then the +prep_for_copy+ task is run before starting all the copies in -parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, -and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is -run only once, even though it is referenced in multiple threads. - -=== Thread Safety - -The Rake internal data structures are thread-safe with respect -to the multitask parallel execution, so there is no need for the user -to do extra synchronization for Rake's benefit. However, if there are -user data structures shared between the parallel prerequisites, the -user must do whatever is necessary to prevent race conditions. - -== Tasks with Arguments - -Prior to version 0.8.0, rake was only able to handle command line -arguments of the form NAME=VALUE that were passed into Rake via the -ENV hash. Many folks had asked for some kind of simple command line -arguments, perhaps using "--" to separate regular task names from -argument values on the command line. The problem is that there was no -easy way to associate positional arguments on the command line with -different tasks. Suppose both tasks :a and :b expect a command line -argument: does the first value go with :a? What if :b is run first? -Should it then get the first command line argument. - -Rake 0.8.0 solves this problem by explicitly passing values directly -to the tasks that need them. For example, if I had a release task -that required a version number, I could say: - - rake release[0.8.2] - -And the string "0.8.2" will be passed to the :release task. Multiple -arguments can be passed by separating them with a comma, for example: - - rake name[john,doe] - -Just a few words of caution. The rake task name and its arguments -need to be a single command line argument to rake. This generally -means no spaces. If spaces are needed, then the entire name + -argument string should be quoted. Something like this: - - rake "name[billy bob, smith]" - -(Quoting rules vary between operating systems and shells, so make sure -you consult the proper docs for your OS/shell). - -=== Tasks that Expect Parameters - -Parameters are only given to tasks that are setup to expect them. In -order to handle named parameters, the task declaration syntax for -tasks has been extended slightly. - -For example, a task that needs a first name and last name might be -declared as: - - task :name, [:first_name, :last_name] - -The first argument is still the name of the task (:name in this case). -The next two arguments are the names of the parameters expected by -:name in an array (:first_name and :last_name in the example). - -To access the values of the parameters, the block defining the task -behaviour can now accept a second parameter: - - task :name, [:first_name, :last_name] do |t, args| - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -The first argument of the block "t" is always bound to the current -task object. The second argument "args" is an open-struct like object -that allows access to the task arguments. Extra command line -arguments to a task are ignored. - -If you wish to specify default values for the arguments, you can use -the with_defaults method in the task body. Here is the above example -where we specify default values for the first and last names: - - task :name, [:first_name, :last_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Tasks that Expect Parameters and Have Prerequisites - -Tasks that use parameters have a slightly different format for -prerequisites. Use the arrow notation to indicate the prerequisites -for tasks with arguments. For example: - - task :name, [:first_name, :last_name] => [:pre_name] do |t, args| - args.with_defaults(:first_name => "John", :last_name => "Dough") - puts "First name is #{args.first_name}" - puts "Last name is #{args.last_name}" - end - -=== Tasks that take Variable-length Parameters - -Tasks that need to handle a list of values as a parameter can use the -extras method of the args variable. This allows for tasks that can -loop over a variable number of values, and its compatible with named -parameters as well: - - task :email, [:message] do |t, args| - mail = Mail.new(args.message) - recipients = args.extras - recipients.each do |target| - mail.send_to(target) - end - end - -There is also the convenience method to_a that returns all parameters -in the sequential order they were given, including those associated -with named parameters. - -=== Deprecated Task Parameters Format - -There is an older format for declaring task parameters that omitted -the task argument array and used the :needs keyword to introduce the -dependencies. That format is still supported for compatibility, but -is not recommended for use. The older format may be dropped in future -versions of rake. - -== Accessing Task Programmatically - -Sometimes it is useful to manipulate tasks programmatically in a -Rakefile. To find a task object use Rake::Task.[]. - -=== Programmatic Task Example - -For example, the following Rakefile defines two tasks. The :doit task -simply prints a simple "DONE" message. The :dont class will lookup -the doit class and remove (clear) all of its prerequisites and -actions. - - task :doit do - puts "DONE" - end - - task :dont do - Rake::Task[:doit].clear - end - -Running this example: - - $ rake doit - (in /Users/jim/working/git/rake/x) - DONE - $ rake dont doit - (in /Users/jim/working/git/rake/x) - $ - -The ability to programmatically manipulate tasks gives rake very -powerful meta-programming capabilities w.r.t. task execution, but -should be used with caution. - -== Rules - -When a file is named as a prerequisite, but does not have a file task -defined for it, Rake will attempt to synthesize a task by looking at a -list of rules supplied in the Rakefile. - -Suppose we were trying to invoke task "mycode.o", but no task is -defined for it. But the rakefile has a rule that look like this ... - - rule '.o' => ['.c'] do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -This rule will synthesize any task that ends in ".o". It has a -prerequisite a source file with an extension of ".c" must exist. If -Rake is able to find a file named "mycode.c", it will automatically -create a task that builds "mycode.o" from "mycode.c". - -If the file "mycode.c" does not exist, rake will attempt -to recursively synthesize a rule for it. - -When a task is synthesized from a rule, the +source+ attribute of the -task is set to the matching source file. This allows us to write -rules with actions that reference the source file. - -=== Advanced Rules - -Any regular expression may be used as the rule pattern. Additionally, -a proc may be used to calculate the name of the source file. This -allows for complex patterns and sources. - -The following rule is equivalent to the example above. - - rule( /\.o$/ => [ - proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } - ]) do |t| - sh "cc #{t.source} -c -o #{t.name}" - end - -*NOTE:* Because of a _quirk_ in Ruby syntax, parenthesis are -required on *rule* when the first argument is a regular expression. - -The following rule might be used for Java files ... - - rule '.class' => [ - proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } - ] do |t| - java_compile(t.source, t.name) - end - -*NOTE:* +java_compile+ is a hypothetical method that invokes the -java compiler. - -== Importing Dependencies - -Any ruby file (including other rakefiles) can be included with a -standard Ruby +require+ command. The rules and declarations in the -required file are just added to the definitions already accumulated. - -Because the files are loaded _before_ the rake targets are evaluated, -the loaded files must be "ready to go" when the rake command is -invoked. This makes generated dependency files difficult to use. By -the time rake gets around to updating the dependencies file, it is too -late to load it. - -The +import+ command addresses this by specifying a file to be loaded -_after_ the main rakefile is loaded, but _before_ any targets on the -command line are invoked. In addition, if the file name matches an -explicit task, that task is invoked before loading the file. This -allows dependency files to be generated and used in a single rake -command invocation. - -Example: - - require 'rake/loaders/makefile' - - file ".depends.mf" => [SRC_LIST] do |t| - sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" - end - - import ".depends.mf" - -If ".depends" does not exist, or is out of date w.r.t. the source -files, a new ".depends" file is generated using +makedepend+ before -loading. - -== Comments - -Standard Ruby comments (beginning with "#") can be used anywhere it is -legal in Ruby source code, including comments for tasks and rules. -However, if you wish a task to be described using the "-T" switch, -then you need to use the +desc+ command to describe the task. - -Example: - - desc "Create a distribution package" - task package: %w[ ... ] do ... end - -The "-T" switch (or "--tasks" if you like to spell things out) will -display a list of tasks that have a description. If you use +desc+ to -describe your major tasks, you have a semi-automatic way of generating -a summary of your Rake file. - - $ rake -T - (in /home/.../rake) - rake clean # Remove any temporary products. - rake clobber # Remove any generated file. - rake clobber_rdoc # Remove rdoc products - rake contrib_test # Run tests for contrib_test - rake default # Default Task - rake install # Install the application - rake lines # Count lines in the main rake file - rake rdoc # Build the rdoc HTML Files - rake rerdoc # Force a rebuild of the RDOC files - rake test # Run tests - rake testall # Run all test targets - -Only tasks with descriptions will be displayed with the "-T" switch. -Use "-P" (or "--prereqs") to get a list of all tasks and their -prerequisites. - -== Namespaces - -As projects grow (and along with it, the number of tasks), it is -common for task names to begin to clash. For example, if you might -have a main program and a set of sample programs built by a single -Rakefile. By placing the tasks related to the main program in one -namespace, and the tasks for building the sample programs in a -different namespace, the task names will not interfere with each other. - -For example: - - namespace "main" do - task :build do - # Build the main program - end - end - - namespace "samples" do - task :build do - # Build the sample programs - end - end - - task build: %w[main:build samples:build] - -Referencing a task in a separate namespace can be achieved by -prefixing the task name with the namespace and a colon -(e.g. "main:build" refers to the :build task in the +main+ namespace). -Nested namespaces are supported. - -Note that the name given in the +task+ command is always the unadorned -task name without any namespace prefixes. The +task+ command always -defines a task in the current namespace. - -=== FileTasks - -File task names are not scoped by the namespace command. Since the -name of a file task is the name of an actual file in the file system, -it makes little sense to include file task names in name space. -Directory tasks (created by the +directory+ command) are a type of -file task and are also not affected by namespaces. - -=== Name Resolution - -When looking up a task name, rake will start with the current -namespace and attempt to find the name there. If it fails to find a -name in the current namespace, it will search the parent namespaces -until a match is found (or an error occurs if there is no match). - -The "rake" namespace is a special implicit namespace that refers to -the toplevel names. - -If a task name begins with a "^" character, the name resolution will -start in the parent namespace. Multiple "^" characters are allowed. - -Here is an example file with multiple :run tasks and how various names -resolve in different locations. - - task :run - - namespace "one" do - task :run - - namespace "two" do - task :run - - # :run => "one:two:run" - # "two:run" => "one:two:run" - # "one:two:run" => "one:two:run" - # "one:run" => "one:run" - # "^run" => "one:run" - # "^^run" => "rake:run" (the top level task) - # "rake:run" => "rake:run" (the top level task) - end - - # :run => "one:run" - # "two:run" => "one:two:run" - # "^run" => "rake:run" - end - - # :run => "rake:run" - # "one:run" => "one:run" - # "one:two:run" => "one:two:run" - -== FileLists - -FileLists are the way Rake manages lists of files. You can treat a -FileList as an array of strings for the most part, but FileLists -support some additional operations. - -=== Creating a FileList - -Creating a file list is easy. Just give it the list of file names: - - fl = FileList['file1.rb', file2.rb'] - -Or give it a glob pattern: - - fl = FileList['*.rb'] - -== Odds and Ends - -=== do/end versus { } - -Blocks may be specified with either a +do+/+end+ pair, or with curly -braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the -actions for tasks and rules. Because the rakefile idiom tends to -leave off parentheses on the task/file/rule methods, unusual -ambiguities can arise when using curly braces. - -For example, suppose that the method +object_files+ returns a list of -object files in a project. Now we use +object_files+ as the -prerequisites in a rule specified with actions in curly braces. - - # DON'T DO THIS! - file "prog" => object_files { - # Actions are expected here (but it doesn't work)! - } - -Because curly braces have a higher precedence than +do+/+end+, the -block is associated with the +object_files+ method rather than the -+file+ method. - -This is the proper way to specify the task ... - - # THIS IS FINE - file "prog" => object_files do - # Actions go here - end - -== Rakefile Path - -When issuing the +rake+ command in a terminal, Rake will look -for a Rakefile in the current directory. If a Rakefile is not found, -it will search parent directories until one is found. - -For example, if a Rakefile resides in the +project/+ directory, -moving deeper into the project's directory tree will not have an adverse -effect on rake tasks: - - $ pwd - /home/user/project - - $ cd lib/foo/bar - $ pwd - /home/user/project/lib/foo/bar - - $ rake run_pwd - /home/user/project - -As far as rake is concerned, all tasks are run from the directory in -which the Rakefile resides. - -=== Multiple Rake Files - -Not all tasks need to be included in a single Rakefile. Additional -rake files (with the file extension "+.rake+") may be placed in -+rakelib+ directory located at the top level of a project (i.e. -the same directory that contains the main +Rakefile+). - -Also, rails projects may include additional rake files in the -+lib/tasks+ directory. - -=== Clean and Clobber Tasks - -Through require 'rake/clean' Rake provides +clean+ and +clobber+ -tasks: - -+clean+ :: - Clean up the project by deleting scratch files and backup files. Add files - to the +CLEAN+ FileList to have the +clean+ target handle them. - -+clobber+ :: - Clobber all generated and non-source files in a project. The task depends - on +clean+, so all the +CLEAN+ files will be deleted as well as files in the - +CLOBBER+ FileList. The intent of this task is to return a project to its - pristine, just unpacked state. - -You can add file names or glob patterns to both the +CLEAN+ and +CLOBBER+ -lists. - -=== Phony Task - -The phony task can be used as a dependency to allow file-based tasks to use -non-file-based-tasks as prerequisites without forcing them to rebuild. You -can require 'rake/phony' to add the +phony+ task. - ----- - -== See - -* README.rdoc -- Main documentation for Rake. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rational.rdoc b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rational.rdoc deleted file mode 100644 index 0e1c338..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/doc/rational.rdoc +++ /dev/null @@ -1,151 +0,0 @@ -= Why rake? - -Ok, let me state from the beginning that I never intended to write this -code. I'm not convinced it is useful, and I'm not convinced anyone -would even be interested in it. All I can say is that Why's onion truck -must by been passing through the Ohio valley. - -What am I talking about? ... A Ruby version of Make. - -See, I can sense you cringing already, and I agree. The world certainly -doesn't need yet another reworking of the "make" program. I mean, we -already have "ant". Isn't that enough? - -It started yesterday. I was helping a coworker fix a problem in one of -the Makefiles we use in our project. Not a particularly tough problem, -but during the course of the conversation I began lamenting some of the -shortcomings of make. In particular, in one of my makefiles I wanted to -determine the name of a file dynamically and had to resort to some -simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you -could just use Ruby inside a Makefile" I said. - -My coworker (a recent convert to Ruby) agreed, but wondered what it -would look like. So I sketched the following on the whiteboard... - - "What if you could specify the make tasks in Ruby, like this ..." - - task "build" do - java_compile(...args, etc ...) - end - - "The task function would register "build" as a target to be made, - and the block would be the action executed whenever the build - system determined that it was time to do the build target." - -We agreed that would be cool, but writing make from scratch would be WAY -too much work. And that was the end of that! - -... Except I couldn't get the thought out of my head. What exactly -would be needed to make the about syntax work as a make file? Hmmm, you -would need to register the tasks, you need some way of specifying -dependencies between tasks, and some way of kicking off the process. -Hey! What if we did ... and fifteen minutes later I had a working -prototype of Ruby make, complete with dependencies and actions. - -I showed the code to my coworker and we had a good laugh. It was just -about a page worth of code that reproduced an amazing amount of the -functionality of make. We were both truly stunned with the power of -Ruby. - -But it didn't do everything make did. In particular, it didn't have -timestamp based file dependencies (where a file is rebuilt if any of its -prerequisite files have a later timestamp). Obviously THAT would be a -pain to add and so Ruby Make would remain an interesting experiment. - -... Except as I walked back to my desk, I started thinking about what -file based dependencies would really need. Rats! I was hooked again, -and by adding a new class and two new methods, file/timestamp -dependencies were implemented. - -Ok, now I was really hooked. Last night (during CSI!) I massaged the -code and cleaned it up a bit. The result is a bare-bones replacement -for make in exactly 100 lines of code. - -For the curious, you can see it at ... -* doc/proto_rake.rdoc - -Oh, about the name. When I wrote the example Ruby Make task on my -whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... -Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves -and Rake would clean them up ... or something like that. Anyways, the -name stuck. - -Some quick examples ... - -A simple task to delete backup files ... - - task :clean do - Dir['*~'].each {|fn| rm fn rescue nil} - end - -Note that task names are symbols (they are slightly easier to type -than quoted strings ... but you may use quoted string if you would -rather). Rake makes the methods of the FileUtils module directly -available, so we take advantage of the rm command. Also note -the use of "rescue nil" to trap and ignore errors in the rm -command. - -To run it, just type "rake clean". Rake will automatically find a -Rakefile in the current directory (or above!) and will invoke the -targets named on the command line. If there are no targets explicitly -named, rake will invoke the task "default". - -Here's another task with dependencies ... - - task :clobber => [:clean] do - rm_r "tempdir" - end - -Task :clobber depends upon task :clean, so :clean will be run before -:clobber is executed. - -Files are specified by using the "file" command. It is similar to the -task command, except that the task name represents a file, and the task -will be run only if the file doesn't exist, or if its modification time -is earlier than any of its prerequisites. - -Here is a file based dependency that will compile "hello.cc" to -"hello.o". - - file "hello.cc" - file "hello.o" => ["hello.cc"] do |t| - srcfile = t.name.sub(/\.o$/, ".cc") - sh %{g++ #{srcfile} -c -o #{t.name}} - end - -I normally specify file tasks with string (rather than symbols). Some -file names can't be represented by symbols. Plus it makes the -distinction between them more clear to the casual reader. - -Currently writing a task for each and every file in the project would be -tedious at best. I envision a set of libraries to make this job -easier. For instance, perhaps something like this ... - - require 'rake/ctools' - Dir['*.c'].each do |fn| - c_source_file(fn) - end - -where "c_source_file" will create all the tasks need to compile all the -C source files in a directory. Any number of useful libraries could be -created for rake. - -That's it. There's no documentation (other than whats in this -message). Does this sound interesting to anyone? If so, I'll continue -to clean it up and write it up and publish it on RAA. Otherwise, I'll -leave it as an interesting exercise and a tribute to the power of Ruby. - -Why /might/ rake be interesting to Ruby programmers. I don't know, -perhaps ... - -* No weird make syntax (only weird Ruby syntax :-) -* No need to edit or read XML (a la ant) -* Platform independent build scripts. -* Will run anywhere Ruby exists, so no need to have "make" installed. - If you stay away from the "sys" command and use things like - 'ftools', you can have a perfectly platform independent - build script. Also rake is only 100 lines of code, so it can - easily be packaged along with the rest of your code. - -So ... Sorry for the long rambling message. Like I said, I never -intended to write this code at all. diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/exe/rake b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/exe/rake deleted file mode 100755 index a00975f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/exe/rake +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby - -#-- -# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -#++ - -require "rake" - -Rake.application.run diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake.rb deleted file mode 100644 index 0f3d6a3..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true -#-- -# Copyright 2003-2010 by Jim Weirich (jim.weirich@gmail.com) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -#++ - -module Rake; end - -require "rake/version" - -require "rbconfig" -require "fileutils" -require "singleton" -require "monitor" -require "optparse" - -require "rake/ext/string" - -require "rake/win32" - -require "rake/linked_list" -require "rake/cpu_counter" -require "rake/scope" -require "rake/task_argument_error" -require "rake/rule_recursion_overflow_error" -require "rake/rake_module" -require "rake/trace_output" -require "rake/pseudo_status" -require "rake/task_arguments" -require "rake/invocation_chain" -require "rake/task" -require "rake/file_task" -require "rake/file_creation_task" -require "rake/multi_task" -require "rake/dsl_definition" -require "rake/file_utils_ext" -require "rake/file_list" -require "rake/default_loader" -require "rake/early_time" -require "rake/late_time" -require "rake/name_space" -require "rake/task_manager" -require "rake/application" -require "rake/backtrace" - -$trace = false - -# :stopdoc: -# -# Some top level Constants. - -FileList = Rake::FileList -RakeFileUtils = Rake::FileUtilsExt diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/application.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/application.rb deleted file mode 100644 index 2ea8c78..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/application.rb +++ /dev/null @@ -1,861 +0,0 @@ -# frozen_string_literal: true -require "optparse" - -require "rake/task_manager" -require "rake/file_list" -require "rake/thread_pool" -require "rake/thread_history_display" -require "rake/trace_output" -require "rake/win32" - -module Rake - - CommandLineOptionError = Class.new(StandardError) - - ## - # Rake main application object. When invoking +rake+ from the - # command line, a Rake::Application object is created and run. - - class Application - include TaskManager - include TraceOutput - - # The name of the application (typically 'rake') - attr_reader :name - - # The original directory where rake was invoked. - attr_reader :original_dir - - # Name of the actual rakefile used. - attr_reader :rakefile - - # Number of columns on the terminal - attr_accessor :terminal_columns - - # List of the top level task names (task names from the command line). - attr_reader :top_level_tasks - - # Override the detected TTY output state (mostly for testing) - attr_writer :tty_output - - DEFAULT_RAKEFILES = [ - "rakefile", - "Rakefile", - "rakefile.rb", - "Rakefile.rb" - ].freeze - - # Initialize a Rake::Application object. - def initialize - super - @name = "rake" - @rakefiles = DEFAULT_RAKEFILES.dup - @rakefile = nil - @pending_imports = [] - @imported = [] - @loaders = {} - @default_loader = Rake::DefaultLoader.new - @original_dir = Dir.pwd - @top_level_tasks = [] - add_loader("rb", DefaultLoader.new) - add_loader("rf", DefaultLoader.new) - add_loader("rake", DefaultLoader.new) - @tty_output = STDOUT.tty? - @terminal_columns = ENV["RAKE_COLUMNS"].to_i - - set_default_options - end - - # Run the Rake application. The run method performs the following - # three steps: - # - # * Initialize the command line options (+init+). - # * Define the tasks (+load_rakefile+). - # * Run the top level tasks (+top_level+). - # - # If you wish to build a custom rake command, you should call - # +init+ on your application. Then define any tasks. Finally, - # call +top_level+ to run your top level tasks. - def run(argv = ARGV) - standard_exception_handling do - init "rake", argv - load_rakefile - top_level - end - end - - # Initialize the command line parameters and app name. - def init(app_name="rake", argv = ARGV) - standard_exception_handling do - @name = app_name - begin - args = handle_options argv - rescue ArgumentError - # Backward compatibility for capistrano - args = handle_options - end - load_debug_at_stop_feature - collect_command_line_tasks(args) - end - end - - def load_debug_at_stop_feature - return unless ENV["RAKE_DEBUG"] - require "debug/session" - DEBUGGER__::start no_sigint_hook: true, nonstop: true - Rake::Task.prepend Module.new { - def execute(*) - exception = DEBUGGER__::SESSION.capture_exception_frames(/(exe|bin|lib)\/rake/) do - super - end - - if exception - STDERR.puts exception.message - DEBUGGER__::SESSION.enter_postmortem_session exception - raise exception - end - end - } - rescue LoadError - end - private :load_debug_at_stop_feature - - # Find the rakefile and then load it and any pending imports. - def load_rakefile - standard_exception_handling do - raw_load_rakefile - end - end - - # Run the top level tasks of a Rake application. - def top_level - run_with_threads do - if options.show_tasks - display_tasks_and_comments - elsif options.show_prereqs - display_prerequisites - else - top_level_tasks.each { |task_name| invoke_task(task_name) } - end - end - end - - # Run the given block with the thread startup and shutdown. - def run_with_threads - thread_pool.gather_history if options.job_stats == :history - - yield - - thread_pool.join if defined?(@thread_pool) - if options.job_stats - stats = thread_pool.statistics - puts "Maximum active threads: #{stats[:max_active_threads]} + main" - puts "Total threads in play: #{stats[:total_threads_in_play]} + main" - end - ThreadHistoryDisplay.new(thread_pool.history).show if - options.job_stats == :history - end - - # Add a loader to handle imported files ending in the extension - # +ext+. - def add_loader(ext, loader) - ext = ".#{ext}" unless ext =~ /^\./ - @loaders[ext] = loader - end - - # Application options from the command line - def options - @options ||= Struct.new( - :always_multitask, :backtrace, :build_all, :dryrun, - :ignore_deprecate, :ignore_system, :job_stats, :load_system, - :nosearch, :rakelib, :show_all_tasks, :show_prereqs, - :show_task_pattern, :show_tasks, :silent, :suppress_backtrace_pattern, - :thread_pool_size, :trace, :trace_output, :trace_rules - ).new - end - - # Return the thread pool used for multithreaded processing. - def thread_pool # :nodoc: - @thread_pool ||= ThreadPool.new(options.thread_pool_size || Rake.suggested_thread_count-1) - end - - # internal ---------------------------------------------------------------- - - # Invokes a task with arguments that are extracted from +task_string+ - def invoke_task(task_string) # :nodoc: - name, args = parse_task_string(task_string) - t = self[name] - t.invoke(*args) - end - - def parse_task_string(string) # :nodoc: - /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s - - name = $1 - remaining_args = $2 - - return string, [] unless name - return name, [] if remaining_args.empty? - - args = [] - - begin - /\s*((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args - - remaining_args = $2 - args << $1.gsub(/\\(.)/, '\1') - end while remaining_args - - return name, args - end - - # Provide standard exception handling for the given block. - def standard_exception_handling # :nodoc: - yield - rescue SystemExit - # Exit silently with current status - raise - rescue OptionParser::InvalidOption => ex - $stderr.puts ex.message - exit(false) - rescue Exception => ex - # Exit with error message - display_error_message(ex) - exit_because_of_exception(ex) - end - - # Exit the program because of an unhandled exception. - # (may be overridden by subclasses) - def exit_because_of_exception(ex) # :nodoc: - exit(false) - end - - # Display the error message that caused the exception. - def display_error_message(ex) # :nodoc: - trace "#{name} aborted!" - display_exception_details(ex) - trace "Tasks: #{ex.chain}" if has_chain?(ex) - trace "(See full trace by running task with --trace)" unless - options.backtrace - end - - def display_exception_details(ex) # :nodoc: - display_exception_details_seen << ex - - display_exception_message_details(ex) - display_exception_backtrace(ex) if ex.backtrace - display_cause_details(ex.cause) if has_cause?(ex) - end - - def display_cause_details(ex) # :nodoc: - return if display_exception_details_seen.include? ex - - trace "\nCaused by:" - display_exception_details(ex) - end - - def display_exception_details_seen # :nodoc: - Thread.current[:rake_display_exception_details_seen] ||= [] - end - - def has_cause?(ex) # :nodoc: - ex.respond_to?(:cause) && ex.cause - end - - def display_exception_message_details(ex) # :nodoc: - if ex.instance_of?(RuntimeError) - trace ex.message - elsif ex.respond_to?(:detailed_message) - trace "#{ex.class.name}: #{ex.detailed_message(highlight: false)}" - else - trace "#{ex.class.name}: #{ex.message}" - end - end - - def display_exception_backtrace(ex) # :nodoc: - if options.backtrace - trace ex.backtrace.join("\n") - else - trace Backtrace.collapse(ex.backtrace).join("\n") - end - end - - # Warn about deprecated usage. - # - # Example: - # Rake.application.deprecate("import", "Rake.import", caller.first) - # - def deprecate(old_usage, new_usage, call_site) # :nodoc: - unless options.ignore_deprecate - $stderr.puts "WARNING: '#{old_usage}' is deprecated. " + - "Please use '#{new_usage}' instead.\n" + - " at #{call_site}" - end - end - - # Does the exception have a task invocation chain? - def has_chain?(exception) # :nodoc: - exception.respond_to?(:chain) && exception.chain - end - private :has_chain? - - # True if one of the files in RAKEFILES is in the current directory. - # If a match is found, it is copied into @rakefile. - def have_rakefile # :nodoc: - @rakefiles.each do |fn| - if File.exist?(fn) - others = FileList.glob(fn, File::FNM_CASEFOLD) - return others.size == 1 ? others.first : fn - elsif fn == "" - return fn - end - end - return nil - end - - # True if we are outputting to TTY, false otherwise - def tty_output? # :nodoc: - @tty_output - end - - # We will truncate output if we are outputting to a TTY or if we've been - # given an explicit column width to honor - def truncate_output? # :nodoc: - tty_output? || @terminal_columns.nonzero? - end - - # Display the tasks and comments. - def display_tasks_and_comments # :nodoc: - displayable_tasks = tasks.select { |t| - (options.show_all_tasks || t.comment) && - t.name =~ options.show_task_pattern - } - case options.show_tasks - when :tasks - width = displayable_tasks.map { |t| t.name_with_args.length }.max || 10 - if truncate_output? - max_column = terminal_width - name.size - width - 7 - else - max_column = nil - end - - displayable_tasks.each do |t| - printf("#{name} %-#{width}s # %s\n", - t.name_with_args, - max_column ? truncate(t.comment, max_column) : t.comment) - end - when :describe - displayable_tasks.each do |t| - puts "#{name} #{t.name_with_args}" - comment = t.full_comment || "" - comment.split("\n").each do |line| - puts " #{line}" - end - puts - end - when :lines - displayable_tasks.each do |t| - t.locations.each do |loc| - printf "#{name} %-30s %s\n", t.name_with_args, loc - end - end - else - fail "Unknown show task mode: '#{options.show_tasks}'" - end - end - - def terminal_width # :nodoc: - if @terminal_columns.nonzero? - result = @terminal_columns - else - result = unix? ? dynamic_width : 80 - end - (result < 10) ? 80 : result - rescue - 80 - end - - # Calculate the dynamic width of the - def dynamic_width # :nodoc: - @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) - end - - def dynamic_width_stty # :nodoc: - %x{stty size 2>/dev/null}.split[1].to_i - end - - def dynamic_width_tput # :nodoc: - %x{tput cols 2>/dev/null}.to_i - end - - def unix? # :nodoc: - RbConfig::CONFIG["host_os"] =~ - /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i - end - - def windows? # :nodoc: - Win32.windows? - end - - def truncate(string, width) # :nodoc: - if string.nil? - "" - elsif string.length <= width - string - else - (string[0, width - 3] || "") + "..." - end - end - - # Display the tasks and prerequisites - def display_prerequisites # :nodoc: - tasks.each do |t| - puts "#{name} #{t.name}" - t.prerequisites.each { |pre| puts " #{pre}" } - end - end - - def trace(*strings) # :nodoc: - options.trace_output ||= $stderr - trace_on(options.trace_output, *strings) - end - - def sort_options(options) # :nodoc: - options.sort_by { |opt| - opt.select { |o| o.is_a?(String) && o =~ /^-/ }.map(&:downcase).sort.reverse - } - end - private :sort_options - - # A list of all the standard options used in rake, suitable for - # passing to OptionParser. - def standard_rake_options # :nodoc: - sort_options( - [ - ["--all", "-A", - "Show all tasks, even uncommented ones (in combination with -T or -D)", - lambda { |value| - options.show_all_tasks = value - } - ], - ["--backtrace=[OUT]", - "Enable full backtrace. OUT can be stderr (default) or stdout.", - lambda { |value| - options.backtrace = true - select_trace_output(options, "backtrace", value) - } - ], - ["--build-all", "-B", - "Build all prerequisites, including those which are up-to-date.", - lambda { |value| - options.build_all = true - } - ], - ["--comments", - "Show commented tasks only", - lambda { |value| - options.show_all_tasks = !value - } - ], - ["--describe", "-D [PATTERN]", - "Describe the tasks (matching optional PATTERN), then exit.", - lambda { |value| - select_tasks_to_show(options, :describe, value) - } - ], - ["--directory", "-C [DIRECTORY]", - "Change to DIRECTORY before doing anything.", - lambda { |value| - Dir.chdir value - @original_dir = Dir.pwd - } - ], - ["--dry-run", "-n", - "Do a dry run without executing actions.", - lambda { |value| - Rake.verbose(true) - Rake.nowrite(true) - options.dryrun = true - options.trace = true - } - ], - ["--execute", "-e CODE", - "Execute some Ruby code and exit.", - lambda { |value| - eval(value) - exit - } - ], - ["--execute-print", "-p CODE", - "Execute some Ruby code, print the result, then exit.", - lambda { |value| - puts eval(value) - exit - } - ], - ["--execute-continue", "-E CODE", - "Execute some Ruby code, " + - "then continue with normal task processing.", - lambda { |value| eval(value) } - ], - ["--jobs", "-j [NUMBER]", - "Specifies the maximum number of tasks to execute in parallel. " + - "(default is number of CPU cores + 4)", - lambda { |value| - if value.nil? || value == "" - value = Float::INFINITY - elsif value =~ /^\d+$/ - value = value.to_i - else - value = Rake.suggested_thread_count - end - value = 1 if value < 1 - options.thread_pool_size = value - 1 - } - ], - ["--job-stats [LEVEL]", - "Display job statistics. " + - "LEVEL=history displays a complete job list", - lambda { |value| - if value =~ /^history/i - options.job_stats = :history - else - options.job_stats = true - end - } - ], - ["--libdir", "-I LIBDIR", - "Include LIBDIR in the search path for required modules.", - lambda { |value| $:.push(value) } - ], - ["--multitask", "-m", - "Treat all tasks as multitasks.", - lambda { |value| options.always_multitask = true } - ], - ["--no-search", "--nosearch", - "-N", "Do not search parent directories for the Rakefile.", - lambda { |value| options.nosearch = true } - ], - ["--prereqs", "-P", - "Display the tasks and dependencies, then exit.", - lambda { |value| options.show_prereqs = true } - ], - ["--quiet", "-q", - "Do not log messages to standard output.", - lambda { |value| Rake.verbose(false) } - ], - ["--rakefile", "-f [FILENAME]", - "Use FILENAME as the rakefile to search for.", - lambda { |value| - value ||= "" - @rakefiles.clear - @rakefiles << value - } - ], - ["--rakelibdir", "--rakelib", "-R RAKELIBDIR", - "Auto-import any .rake files in RAKELIBDIR. " + - "(default is 'rakelib')", - lambda { |value| - options.rakelib = value.split(File::PATH_SEPARATOR) - } - ], - ["--require", "-r MODULE", - "Require MODULE before executing rakefile.", - lambda { |value| - begin - require value - rescue LoadError => ex - begin - rake_require value - rescue LoadError - raise ex - end - end - } - ], - ["--rules", - "Trace the rules resolution.", - lambda { |value| options.trace_rules = true } - ], - ["--silent", "-s", - "Like --quiet, but also suppresses the " + - "'in directory' announcement.", - lambda { |value| - Rake.verbose(false) - options.silent = true - } - ], - ["--suppress-backtrace PATTERN", - "Suppress backtrace lines matching regexp PATTERN. " + - "Ignored if --trace is on.", - lambda { |value| - options.suppress_backtrace_pattern = Regexp.new(value) - } - ], - ["--system", "-g", - "Using system wide (global) rakefiles " + - "(usually '~/.rake/*.rake').", - lambda { |value| options.load_system = true } - ], - ["--no-system", "--nosystem", "-G", - "Use standard project Rakefile search paths, " + - "ignore system wide rakefiles.", - lambda { |value| options.ignore_system = true } - ], - ["--tasks", "-T [PATTERN]", - "Display the tasks (matching optional PATTERN) " + - "with descriptions, then exit. " + - "-AT combination displays all the tasks, including those without descriptions.", - lambda { |value| - select_tasks_to_show(options, :tasks, value) - } - ], - ["--trace=[OUT]", "-t", - "Turn on invoke/execute tracing, enable full backtrace. " + - "OUT can be stderr (default) or stdout.", - lambda { |value| - options.trace = true - options.backtrace = true - select_trace_output(options, "trace", value) - Rake.verbose(true) - } - ], - ["--verbose", "-v", - "Log message to standard output.", - lambda { |value| Rake.verbose(true) } - ], - ["--version", "-V", - "Display the program version.", - lambda { |value| - puts "rake, version #{Rake::VERSION}" - exit - } - ], - ["--where", "-W [PATTERN]", - "Describe the tasks (matching optional PATTERN), then exit.", - lambda { |value| - select_tasks_to_show(options, :lines, value) - options.show_all_tasks = true - } - ], - ["--no-deprecation-warnings", "-X", - "Disable the deprecation warnings.", - lambda { |value| - options.ignore_deprecate = true - } - ], - ]) - end - - def select_tasks_to_show(options, show_tasks, value) # :nodoc: - options.show_tasks = show_tasks - options.show_task_pattern = Regexp.new(value || "") - Rake::TaskManager.record_task_metadata = true - end - private :select_tasks_to_show - - def select_trace_output(options, trace_option, value) # :nodoc: - value = value.strip unless value.nil? - case value - when "stdout" - options.trace_output = $stdout - when "stderr", nil - options.trace_output = $stderr - else - fail CommandLineOptionError, - "Unrecognized --#{trace_option} option '#{value}'" - end - end - private :select_trace_output - - # Read and handle the command line options. Returns the command line - # arguments that we didn't understand, which should (in theory) be just - # task names and env vars. - def handle_options(argv) # :nodoc: - set_default_options - - OptionParser.new do |opts| - opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." - opts.separator "" - opts.separator "Options are ..." - - opts.on_tail("-h", "--help", "-H", "Display this help message.") do - puts opts - exit - end - - standard_rake_options.each { |args| opts.on(*args) } - opts.environment("RAKEOPT") - end.parse(argv) - end - - # Similar to the regular Ruby +require+ command, but will check - # for *.rake files in addition to *.rb files. - def rake_require(file_name, paths=$LOAD_PATH, loaded=$") # :nodoc: - fn = file_name + ".rake" - return false if loaded.include?(fn) - paths.each do |path| - full_path = File.join(path, fn) - if File.exist?(full_path) - Rake.load_rakefile(full_path) - loaded << fn - return true - end - end - fail LoadError, "Can't find #{file_name}" - end - - def find_rakefile_location # :nodoc: - here = Dir.pwd - until (fn = have_rakefile) - Dir.chdir("..") - return nil if Dir.pwd == here || options.nosearch - here = Dir.pwd - end - [fn, here] - ensure - Dir.chdir(Rake.original_dir) - end - - def print_rakefile_directory(location) # :nodoc: - $stderr.puts "(in #{Dir.pwd})" unless - options.silent or original_dir == location - end - - def raw_load_rakefile # :nodoc: - rakefile, location = find_rakefile_location - if (!options.ignore_system) && - (options.load_system || rakefile.nil?) && - system_dir && File.directory?(system_dir) - print_rakefile_directory(location) - glob("#{system_dir}/*.rake") do |name| - add_import name - end - else - fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if - rakefile.nil? - @rakefile = rakefile - Dir.chdir(location) - print_rakefile_directory(location) - Rake.load_rakefile(File.expand_path(@rakefile)) if - @rakefile && @rakefile != "" - options.rakelib.each do |rlib| - glob("#{rlib}/*.rake") do |name| - add_import name - end - end - end - load_imports - end - - def glob(path, &block) # :nodoc: - FileList.glob(path.tr("\\", "/")).each(&block) - end - private :glob - - # The directory path containing the system wide rakefiles. - def system_dir # :nodoc: - @system_dir ||= - begin - if ENV["RAKE_SYSTEM"] - ENV["RAKE_SYSTEM"] - else - standard_system_dir - end - end - end - - # The standard directory containing system wide rake files. - if Win32.windows? - def standard_system_dir #:nodoc: - Win32.win32_system_dir - end - else - def standard_system_dir #:nodoc: - File.join(File.expand_path("~"), ".rake") - end - end - private :standard_system_dir - - # Collect the list of tasks on the command line. If no tasks are - # given, return a list containing only the default task. - # Environmental assignments are processed at this time as well. - # - # `args` is the list of arguments to peruse to get the list of tasks. - # It should be the command line that was given to rake, less any - # recognised command-line options, which OptionParser.parse will - # have taken care of already. - def collect_command_line_tasks(args) # :nodoc: - @top_level_tasks = [] - args.each do |arg| - if arg =~ /^(\w+)=(.*)$/m - ENV[$1] = $2 - else - @top_level_tasks << arg unless arg =~ /^-/ - end - end - @top_level_tasks.push(default_task_name) if @top_level_tasks.empty? - end - - # Default task name ("default"). - # (May be overridden by subclasses) - def default_task_name # :nodoc: - "default" - end - - # Add a file to the list of files to be imported. - def add_import(fn) # :nodoc: - @pending_imports << fn - end - - # Load the pending list of imported files. - def load_imports # :nodoc: - while fn = @pending_imports.shift - next if @imported.member?(fn) - fn_task = lookup(fn) and fn_task.invoke - ext = File.extname(fn) - loader = @loaders[ext] || @default_loader - loader.load(fn) - if fn_task = lookup(fn) and fn_task.needed? - fn_task.reenable - fn_task.invoke - loader.load(fn) - end - @imported << fn - end - end - - def rakefile_location(backtrace=caller) # :nodoc: - backtrace.map { |t| t[/([^:]+):/, 1] } - - re = /^#{@rakefile}$/ - re = /#{re.source}/i if windows? - - backtrace.find { |str| str =~ re } || "" - end - - def set_default_options # :nodoc: - options.always_multitask = false - options.backtrace = false - options.build_all = false - options.dryrun = false - options.ignore_deprecate = false - options.ignore_system = false - options.job_stats = false - options.load_system = false - options.nosearch = false - options.rakelib = %w[rakelib] - options.show_all_tasks = false - options.show_prereqs = false - options.show_task_pattern = nil - options.show_tasks = nil - options.silent = false - options.suppress_backtrace_pattern = nil - options.thread_pool_size = Rake.suggested_thread_count - options.trace = false - options.trace_output = $stderr - options.trace_rules = false - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/backtrace.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/backtrace.rb deleted file mode 100644 index c87f2f9..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/backtrace.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -module Rake - module Backtrace # :nodoc: all - SYS_KEYS = RbConfig::CONFIG.keys.grep(/(?:[a-z]prefix|libdir)\z/) - SYS_PATHS = RbConfig::CONFIG.values_at(*SYS_KEYS).uniq + - [ File.join(File.dirname(__FILE__), "..") ] - - SUPPRESSED_PATHS = SYS_PATHS. - map { |s| s.tr("\\", "/") }. - map { |f| File.expand_path(f) }. - reject { |s| s.nil? || s =~ /^ *$/ } - SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|") - SUPPRESSED_PATHS_RE << "|^" - SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if - Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == "jruby" - - SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i - - def self.collapse(backtrace) - pattern = Rake.application.options.suppress_backtrace_pattern || - SUPPRESS_PATTERN - backtrace.reject { |elem| elem =~ pattern } - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/clean.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/clean.rb deleted file mode 100644 index b52e832..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/clean.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true -# The 'rake/clean' file defines two file lists (CLEAN and CLOBBER) and -# two rake tasks (:clean and :clobber). -# -# [:clean] Clean up the project by deleting scratch files and backup -# files. Add files to the CLEAN file list to have the :clean -# target handle them. -# -# [:clobber] Clobber all generated and non-source files in a project. -# The task depends on :clean, so all the clean files will -# be deleted as well as files in the CLOBBER file list. -# The intent of this task is to return a project to its -# pristine, just unpacked state. - -require "rake" - -# :stopdoc: - -module Rake - module Cleaner - extend FileUtils - - module_function - - def cleanup_files(file_names) - file_names.each do |file_name| - cleanup(file_name) - end - end - - def cleanup(file_name, **opts) - begin - opts = { verbose: Rake.application.options.trace }.merge(opts) - rm_r file_name, **opts - rescue StandardError => ex - puts "Failed to remove #{file_name}: #{ex}" unless file_already_gone?(file_name) - end - end - - def file_already_gone?(file_name) - return false if File.exist?(file_name) - - path = file_name - prev = nil - - while path = File.dirname(path) - return false if cant_be_deleted?(path) - break if [prev, "."].include?(path) - prev = path - end - true - end - private_class_method :file_already_gone? - - def cant_be_deleted?(path_name) - File.exist?(path_name) && - (!File.readable?(path_name) || !File.executable?(path_name)) - end - private_class_method :cant_be_deleted? - end -end - -CLEAN = ::Rake::FileList["**/*~", "**/*.bak", "**/core"] -CLEAN.clear_exclude.exclude { |fn| - fn.pathmap("%f").downcase == "core" && File.directory?(fn) -} - -desc "Remove any temporary products." -task :clean do - Rake::Cleaner.cleanup_files(CLEAN) -end - -CLOBBER = ::Rake::FileList.new - -desc "Remove any generated files." -task clobber: [:clean] do - Rake::Cleaner.cleanup_files(CLOBBER) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cloneable.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cloneable.rb deleted file mode 100644 index eddb77e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cloneable.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -module Rake - ## - # Mixin for creating easily cloned objects. - - module Cloneable # :nodoc: - # The hook that is invoked by 'clone' and 'dup' methods. - def initialize_copy(source) - super - source.instance_variables.each do |var| - src_value = source.instance_variable_get(var) - value = src_value.clone rescue src_value - instance_variable_set(var, value) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cpu_counter.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cpu_counter.rb deleted file mode 100644 index 564a628..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/cpu_counter.rb +++ /dev/null @@ -1,107 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Based on a script at: - # http://stackoverflow.com/questions/891537/ruby-detect-number-of-cpus-installed - class CpuCounter # :nodoc: all - def self.count - new.count_with_default - end - - def count_with_default(default=4) - count || default - rescue StandardError - default - end - - begin - require "etc" - rescue LoadError - else - if Etc.respond_to?(:nprocessors) - def count - return Etc.nprocessors - end - end - end - end -end - -unless Rake::CpuCounter.method_defined?(:count) - Rake::CpuCounter.class_eval <<-'end;', __FILE__, __LINE__+1 - require 'rbconfig' - - def count - if RUBY_PLATFORM == 'java' - count_via_java_runtime - else - case RbConfig::CONFIG['host_os'] - when /linux/ - count_via_cpuinfo - when /darwin|bsd/ - count_via_sysctl - when /mswin|mingw/ - count_via_win32 - else - # Try everything - count_via_win32 || - count_via_sysctl || - count_via_cpuinfo - end - end - end - - def count_via_java_runtime - Java::Java.lang.Runtime.getRuntime.availableProcessors - rescue StandardError - nil - end - - def count_via_win32 - require 'win32ole' - wmi = WIN32OLE.connect("winmgmts://") - cpu = wmi.ExecQuery("select NumberOfCores from Win32_Processor") # TODO count hyper-threaded in this - cpu.to_enum.first.NumberOfCores - rescue StandardError, LoadError - nil - end - - def count_via_cpuinfo - open('/proc/cpuinfo') { |f| f.readlines }.grep(/processor/).size - rescue StandardError - nil - end - - def count_via_sysctl - run 'sysctl', '-n', 'hw.ncpu' - end - - def run(command, *args) - cmd = resolve_command(command) - if cmd - IO.popen [cmd, *args] do |io| - io.read.to_i - end - else - nil - end - end - - def resolve_command(command) - look_for_command("/usr/sbin", command) || - look_for_command("/sbin", command) || - in_path_command(command) - end - - def look_for_command(dir, command) - path = File.join(dir, command) - File.exist?(path) ? path : nil - end - - def in_path_command(command) - IO.popen ['which', command] do |io| - io.eof? ? nil : command - end - end - end; -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/default_loader.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/default_loader.rb deleted file mode 100644 index d3b4650..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/default_loader.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Default Rakefile loader used by +import+. - class DefaultLoader - - ## - # Loads a rakefile into the current application from +fn+ - - def load(fn) - Rake.load_rakefile(File.expand_path(fn)) - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/dsl_definition.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/dsl_definition.rb deleted file mode 100644 index 6bd660c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/dsl_definition.rb +++ /dev/null @@ -1,196 +0,0 @@ -# frozen_string_literal: true -# Rake DSL functions. -require "rake/file_utils_ext" - -module Rake - - ## - # DSL is a module that provides #task, #desc, #namespace, etc. Use this - # when you'd like to use rake outside the top level scope. - # - # For a Rakefile you run from the command line this module is automatically - # included. - - module DSL - - #-- - # Include the FileUtils file manipulation functions in the top - # level module, but mark them private so that they don't - # unintentionally define methods on other objects. - #++ - - include FileUtilsExt - private(*FileUtils.instance_methods(false)) - private(*FileUtilsExt.instance_methods(false)) - - private - - # :call-seq: - # task(task_name) - # task(task_name: dependencies) - # task(task_name, arguments => dependencies) - # - # Declare a basic task. The +task_name+ is always the first argument. If - # the task name contains a ":" it is defined in that namespace. - # - # The +dependencies+ may be a single task name or an Array of task names. - # The +argument+ (a single name) or +arguments+ (an Array of names) define - # the arguments provided to the task. - # - # The task, argument and dependency names may be either symbols or - # strings. - # - # A task with a single dependency: - # - # task clobber: %w[clean] do - # rm_rf "html" - # end - # - # A task with an argument and a dependency: - # - # task :package, [:version] => :test do |t, args| - # # ... - # end - # - # To invoke this task from the command line: - # - # $ rake package[1.2.3] - # - def task(*args, &block) # :doc: - Rake::Task.define_task(*args, &block) - end - - # Declare a file task. - # - # Example: - # file "config.cfg" => ["config.template"] do - # open("config.cfg", "w") do |outfile| - # open("config.template") do |infile| - # while line = infile.gets - # outfile.puts line - # end - # end - # end - # end - # - def file(*args, &block) # :doc: - Rake::FileTask.define_task(*args, &block) - end - - # Declare a file creation task. - # (Mainly used for the directory command). - def file_create(*args, &block) - Rake::FileCreationTask.define_task(*args, &block) - end - - # Declare a set of files tasks to create the given directories on - # demand. - # - # Example: - # directory "testdata/doc" - # - def directory(*args, &block) # :doc: - args = args.flat_map { |arg| arg.is_a?(FileList) ? arg.to_a.flatten : arg } - result = file_create(*args, &block) - dir, _ = *Rake.application.resolve_args(args) - dir = Rake.from_pathname(dir) - Rake.each_dir_parent(dir) do |d| - file_create d do |t| - mkdir_p t.name unless File.exist?(t.name) - end - end - result - end - - # Declare a task that performs its prerequisites in - # parallel. Multitasks does *not* guarantee that its prerequisites - # will execute in any given order (which is obvious when you think - # about it) - # - # Example: - # multitask deploy: %w[deploy_gem deploy_rdoc] - # - def multitask(*args, &block) # :doc: - Rake::MultiTask.define_task(*args, &block) - end - - # Create a new rake namespace and use it for evaluating the given - # block. Returns a NameSpace object that can be used to lookup - # tasks defined in the namespace. - # - # Example: - # - # ns = namespace "nested" do - # # the "nested:run" task - # task :run - # end - # task_run = ns[:run] # find :run in the given namespace. - # - # Tasks can also be defined in a namespace by using a ":" in the task - # name: - # - # task "nested:test" do - # # ... - # end - # - def namespace(name=nil, &block) # :doc: - name = name.to_s if name.kind_of?(Symbol) - name = name.to_str if name.respond_to?(:to_str) - unless name.kind_of?(String) || name.nil? - raise ArgumentError, "Expected a String or Symbol for a namespace name" - end - Rake.application.in_namespace(name, &block) - end - - # Declare a rule for auto-tasks. - # - # Example: - # rule '.o' => '.c' do |t| - # sh 'cc', '-c', '-o', t.name, t.source - # end - # - def rule(*args, &block) # :doc: - Rake::Task.create_rule(*args, &block) - end - - # Describes the next rake task. Duplicate descriptions are discarded. - # Descriptions are shown with rake -T (up to the first - # sentence) and rake -D (the entire description). - # - # Example: - # desc "Run the Unit Tests" - # task test: [:build] do - # # ... run tests - # end - # - def desc(description) # :doc: - Rake.application.last_description = description - end - - # Import the partial Rakefiles +fn+. Imported files are loaded - # _after_ the current file is completely loaded. This allows the - # import statement to appear anywhere in the importing file, and yet - # allowing the imported files to depend on objects defined in the - # importing file. - # - # A common use of the import statement is to include files - # containing dependency declarations. - # - # See also the --rakelibdir command line option. - # - # Example: - # import ".depend", "my_rules" - # - def import(*fns) # :doc: - fns.each do |fn| - Rake.application.add_import(fn) - end - end - end - extend FileUtilsExt -end - -# Extend the main object with the DSL commands. This allows top-level -# calls to task, etc. to work from a Rakefile without polluting the -# object inheritance tree. -self.extend Rake::DSL diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/early_time.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/early_time.rb deleted file mode 100644 index 80cc6bf..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/early_time.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -module Rake - - # EarlyTime is a fake timestamp that occurs _before_ any other time value. - class EarlyTime - include Comparable - include Singleton - - ## - # The EarlyTime always comes before +other+! - - def <=>(other) - -1 - end - - def to_s # :nodoc: - "" - end - end - - EARLY = EarlyTime.instance -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/core.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/core.rb deleted file mode 100644 index 226f212..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/core.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -class Module - # Check for an existing method in the current class before extending. If - # the method already exists, then a warning is printed and the extension is - # not added. Otherwise the block is yielded and any definitions in the - # block will take effect. - # - # Usage: - # - # class String - # rake_extension("xyz") do - # def xyz - # ... - # end - # end - # end - # - def rake_extension(method) # :nodoc: - if method_defined?(method) - $stderr.puts "WARNING: Possible conflict with Rake extension: " + - "#{self}##{method} already exists" - else - yield - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/string.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/string.rb deleted file mode 100644 index c70236a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/ext/string.rb +++ /dev/null @@ -1,176 +0,0 @@ -# frozen_string_literal: true -require "rake/ext/core" - -class String - - rake_extension("ext") do - # Replace the file extension with +newext+. If there is no extension on - # the string, append the new extension to the end. If the new extension - # is not given, or is the empty string, remove any existing extension. - # - # +ext+ is a user added method for the String class. - # - # This String extension comes from Rake - def ext(newext="") - return self.dup if [".", ".."].include? self - if newext != "" - newext = "." + newext unless newext =~ /^\./ - end - self.chomp(File.extname(self)) << newext - end - end - - rake_extension("pathmap") do - # Explode a path into individual components. Used by +pathmap+. - # - # This String extension comes from Rake - def pathmap_explode - head, tail = File.split(self) - return [self] if head == self - return [tail] if head == "." || tail == "/" - return [head, tail] if head == "/" - return head.pathmap_explode + [tail] - end - protected :pathmap_explode - - # Extract a partial path from the path. Include +n+ directories from the - # front end (left hand side) if +n+ is positive. Include |+n+| - # directories from the back end (right hand side) if +n+ is negative. - # - # This String extension comes from Rake - def pathmap_partial(n) - dirs = File.dirname(self).pathmap_explode - partial_dirs = - if n > 0 - dirs[0...n] - elsif n < 0 - dirs.reverse[0...-n].reverse - else - "." - end - File.join(partial_dirs) - end - protected :pathmap_partial - - # Perform the pathmap replacement operations on the given path. The - # patterns take the form 'pat1,rep1;pat2,rep2...'. - # - # This String extension comes from Rake - def pathmap_replace(patterns, &block) - result = self - patterns.split(";").each do |pair| - pattern, replacement = pair.split(",") - pattern = Regexp.new(pattern) - if replacement == "*" && block_given? - result = result.sub(pattern, &block) - elsif replacement - result = result.sub(pattern, replacement) - else - result = result.sub(pattern, "") - end - end - result - end - protected :pathmap_replace - - # Map the path according to the given specification. The specification - # controls the details of the mapping. The following special patterns are - # recognized: - # - # %p :: The complete path. - # %f :: The base file name of the path, with its file extension, - # but without any directories. - # %n :: The file name of the path without its file extension. - # %d :: The directory list of the path. - # %x :: The file extension of the path. An empty string if there - # is no extension. - # %X :: Everything *but* the file extension. - # %s :: The alternate file separator if defined, otherwise use # - # the standard file separator. - # %% :: A percent sign. - # - # The %d specifier can also have a numeric prefix (e.g. '%2d'). - # If the number is positive, only return (up to) +n+ directories in the - # path, starting from the left hand side. If +n+ is negative, return (up - # to) +n+ directories from the right hand side of the path. - # - # Examples: - # - # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' - # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' - # - # Also the %d, %p, %f, %n, - # %x, and %X operators can take a pattern/replacement - # argument to perform simple string substitutions on a particular part of - # the path. The pattern and replacement are separated by a comma and are - # enclosed by curly braces. The replacement spec comes after the % - # character but before the operator letter. (e.g. "%{old,new}d"). - # Multiple replacement specs should be separated by semi-colons (e.g. - # "%{old,new;src,bin}d"). - # - # Regular expressions may be used for the pattern, and back refs may be - # used in the replacement text. Curly braces, commas and semi-colons are - # excluded from both the pattern and replacement text (let's keep parsing - # reasonable). - # - # For example: - # - # "src/org/onestepback/proj/A.java".pathmap("%{^src,class}X.class") - # - # returns: - # - # "class/org/onestepback/proj/A.class" - # - # If the replacement text is '*', then a block may be provided to perform - # some arbitrary calculation for the replacement. - # - # For example: - # - # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext| - # ext.downcase - # } - # - # Returns: - # - # "/path/to/file.txt" - # - # This String extension comes from Rake - def pathmap(spec=nil, &block) - return self if spec.nil? - result = "".dup - spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| - case frag - when "%f" - result << File.basename(self) - when "%n" - result << File.basename(self).ext - when "%d" - result << File.dirname(self) - when "%x" - result << File.extname(self) - when "%X" - result << self.ext - when "%p" - result << self - when "%s" - result << (File::ALT_SEPARATOR || File::SEPARATOR) - when "%-" - # do nothing - when "%%" - result << "%" - when /%(-?\d+)d/ - result << pathmap_partial($1.to_i) - when /^%\{([^}]*)\}(\d*[dpfnxX])/ - patterns, operator = $1, $2 - result << pathmap("%" + operator).pathmap_replace(patterns, &block) - when /^%/ - fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" - else - result << frag - end - end - result - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_creation_task.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_creation_task.rb deleted file mode 100644 index 5a4c684..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_creation_task.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -require "rake/file_task" -require "rake/early_time" - -module Rake - - # A FileCreationTask is a file task that when used as a dependency will be - # needed if and only if the file has not been created. Once created, it is - # not re-triggered if any of its dependencies are newer, nor does trigger - # any rebuilds of tasks that depend on it whenever it is updated. - # - class FileCreationTask < FileTask - # Is this file task needed? Yes if it doesn't exist. - def needed? - !File.exist?(name) - end - - # Time stamp for file creation task. This time stamp is earlier - # than any other time stamp. - def timestamp - Rake::EARLY - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_list.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_list.rb deleted file mode 100644 index 22c339f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_list.rb +++ /dev/null @@ -1,435 +0,0 @@ -# frozen_string_literal: true -require "rake/cloneable" -require "rake/file_utils_ext" -require "rake/ext/string" - -module Rake - - ## - # A FileList is essentially an array with a few helper methods defined to - # make file manipulation a bit easier. - # - # FileLists are lazy. When given a list of glob patterns for possible files - # to be included in the file list, instead of searching the file structures - # to find the files, a FileList holds the pattern for latter use. - # - # This allows us to define a number of FileList to match any number of - # files, but only search out the actual files when then FileList itself is - # actually used. The key is that the first time an element of the - # FileList/Array is requested, the pending patterns are resolved into a real - # list of file names. - # - class FileList - - include Cloneable - - # == Method Delegation - # - # The lazy evaluation magic of FileLists happens by implementing all the - # array specific methods to call +resolve+ before delegating the heavy - # lifting to an embedded array object (@items). - # - # In addition, there are two kinds of delegation calls. The regular kind - # delegates to the @items array and returns the result directly. Well, - # almost directly. It checks if the returned value is the @items object - # itself, and if so will return the FileList object instead. - # - # The second kind of delegation call is used in methods that normally - # return a new Array object. We want to capture the return value of these - # methods and wrap them in a new FileList object. We enumerate these - # methods in the +SPECIAL_RETURN+ list below. - - # List of array methods (that are not in +Object+) that need to be - # delegated. - ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map(&:to_s) - - # List of additional methods that must be delegated. - MUST_DEFINE = %w[inspect <=>] - - # List of methods that should not be delegated here (we define special - # versions of them explicitly below). - MUST_NOT_DEFINE = %w[to_a to_ary partition * <<] - - # List of delegated methods that return new array values which need - # wrapping. - SPECIAL_RETURN = %w[ - map collect sort sort_by select find_all reject grep - compact flatten uniq values_at - + - & | - ] - - DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).map(&:to_s).sort.uniq - - # Now do the delegation. - DELEGATING_METHODS.each do |sym| - if SPECIAL_RETURN.include?(sym) - ln = __LINE__ + 1 - class_eval %{ - def #{sym}(*args, &block) - resolve - result = @items.send(:#{sym}, *args, &block) - self.class.new.import(result) - end - }, __FILE__, ln - else - ln = __LINE__ + 1 - class_eval %{ - def #{sym}(*args, &block) - resolve - result = @items.send(:#{sym}, *args, &block) - result.object_id == @items.object_id ? self : result - end - }, __FILE__, ln - end - end - - GLOB_PATTERN = %r{[*?\[\{]} - - # Create a file list from the globbable patterns given. If you wish to - # perform multiple includes or excludes at object build time, use the - # "yield self" pattern. - # - # Example: - # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') - # - # pkg_files = FileList.new('lib/**/*') do |fl| - # fl.exclude(/\bCVS\b/) - # end - # - def initialize(*patterns) - @pending_add = [] - @pending = false - @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup - @exclude_procs = DEFAULT_IGNORE_PROCS.dup - @items = [] - patterns.each { |pattern| include(pattern) } - yield self if block_given? - end - - # Add file names defined by glob patterns to the file list. If an array - # is given, add each element of the array. - # - # Example: - # file_list.include("*.java", "*.cfg") - # file_list.include %w( math.c lib.h *.o ) - # - def include(*filenames) - # TODO: check for pending - filenames.each do |fn| - if fn.respond_to? :to_ary - include(*fn.to_ary) - else - @pending_add << Rake.from_pathname(fn) - end - end - @pending = true - self - end - alias :add :include - - # Register a list of file name patterns that should be excluded from the - # list. Patterns may be regular expressions, glob patterns or regular - # strings. In addition, a block given to exclude will remove entries that - # return true when given to the block. - # - # Note that glob patterns are expanded against the file system. If a file - # is explicitly added to a file list, but does not exist in the file - # system, then an glob pattern in the exclude list will not exclude the - # file. - # - # Examples: - # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] - # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c'] - # - # If "a.c" is a file, then ... - # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c'] - # - # If "a.c" is not a file, then ... - # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c'] - # - def exclude(*patterns, &block) - patterns.each do |pat| - if pat.respond_to? :to_ary - exclude(*pat.to_ary) - else - @exclude_patterns << Rake.from_pathname(pat) - end - end - @exclude_procs << block if block_given? - resolve_exclude unless @pending - self - end - - # Clear all the exclude patterns so that we exclude nothing. - def clear_exclude - @exclude_patterns = [] - @exclude_procs = [] - self - end - - # A FileList is equal through array equality. - def ==(array) - to_ary == array - end - - # Return the internal array object. - def to_a - resolve - @items - end - - # Return the internal array object. - def to_ary - to_a - end - - # Lie about our class. - def is_a?(klass) - klass == Array || super(klass) - end - alias kind_of? is_a? - - # Redefine * to return either a string or a new file list. - def *(other) - result = @items * other - case result - when Array - self.class.new.import(result) - else - result - end - end - - def <<(obj) - resolve - @items << Rake.from_pathname(obj) - self - end - - # Resolve all the pending adds now. - def resolve - if @pending - @pending = false - @pending_add.each do |fn| resolve_add(fn) end - @pending_add = [] - resolve_exclude - end - self - end - - def resolve_add(fn) # :nodoc: - case fn - when GLOB_PATTERN - add_matching(fn) - else - self << fn - end - end - private :resolve_add - - def resolve_exclude # :nodoc: - reject! { |fn| excluded_from_list?(fn) } - self - end - private :resolve_exclude - - # Return a new FileList with the results of running +sub+ against each - # element of the original list. - # - # Example: - # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] - # - def sub(pat, rep) - inject(self.class.new) { |res, fn| res << fn.sub(pat, rep) } - end - - # Return a new FileList with the results of running +gsub+ against each - # element of the original list. - # - # Example: - # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") - # => ['lib\\test\\file', 'x\\y'] - # - def gsub(pat, rep) - inject(self.class.new) { |res, fn| res << fn.gsub(pat, rep) } - end - - # Same as +sub+ except that the original file list is modified. - def sub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } - self - end - - # Same as +gsub+ except that the original file list is modified. - def gsub!(pat, rep) - each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } - self - end - - # Apply the pathmap spec to each of the included file names, returning a - # new file list with the modified paths. (See String#pathmap for - # details.) - def pathmap(spec=nil, &block) - collect { |fn| fn.pathmap(spec, &block) } - end - - # Return a new FileList with String#ext method applied to - # each member of the array. - # - # This method is a shortcut for: - # - # array.collect { |item| item.ext(newext) } - # - # +ext+ is a user added method for the Array class. - def ext(newext="") - collect { |fn| fn.ext(newext) } - end - - # Grep each of the files in the filelist using the given pattern. If a - # block is given, call the block on each matching line, passing the file - # name, line number, and the matching line of text. If no block is given, - # a standard emacs style file:linenumber:line message will be printed to - # standard out. Returns the number of matched items. - def egrep(pattern, *options) - matched = 0 - each do |fn| - begin - File.open(fn, "r", *options) do |inf| - count = 0 - inf.each do |line| - count += 1 - if pattern.match(line) - matched += 1 - if block_given? - yield fn, count, line - else - puts "#{fn}:#{count}:#{line}" - end - end - end - end - rescue StandardError => ex - $stderr.puts "Error while processing '#{fn}': #{ex}" - end - end - matched - end - - # Return a new file list that only contains file names from the current - # file list that exist on the file system. - def existing - select { |fn| File.exist?(fn) }.uniq - end - - # Modify the current file list so that it contains only file name that - # exist on the file system. - def existing! - resolve - @items = @items.select { |fn| File.exist?(fn) }.uniq - self - end - - # FileList version of partition. Needed because the nested arrays should - # be FileLists in this version. - def partition(&block) # :nodoc: - resolve - result = @items.partition(&block) - [ - self.class.new.import(result[0]), - self.class.new.import(result[1]), - ] - end - - # Convert a FileList to a string by joining all elements with a space. - def to_s - resolve - self.join(" ") - end - - # Add matching glob patterns. - def add_matching(pattern) - self.class.glob(pattern).each do |fn| - self << fn unless excluded_from_list?(fn) - end - end - private :add_matching - - # Should the given file name be excluded from the list? - # - # NOTE: This method was formerly named "exclude?", but Rails - # introduced an exclude? method as an array method and setup a - # conflict with file list. We renamed the method to avoid - # confusion. If you were using "FileList#exclude?" in your user - # code, you will need to update. - def excluded_from_list?(fn) - return true if @exclude_patterns.any? do |pat| - case pat - when Regexp - fn =~ pat - when GLOB_PATTERN - flags = File::FNM_PATHNAME - # Ruby <= 1.9.3 does not support File::FNM_EXTGLOB - flags |= File::FNM_EXTGLOB if defined? File::FNM_EXTGLOB - File.fnmatch?(pat, fn, flags) - else - fn == pat - end - end - @exclude_procs.any? { |p| p.call(fn) } - end - - DEFAULT_IGNORE_PATTERNS = [ - /(^|[\/\\])CVS([\/\\]|$)/, - /(^|[\/\\])\.svn([\/\\]|$)/, - /\.bak$/, - /~$/ - ] - DEFAULT_IGNORE_PROCS = [ - proc { |fn| fn =~ /(^|[\/\\])core$/ && !File.directory?(fn) } - ] - - def import(array) # :nodoc: - @items = array - self - end - - class << self - # Create a new file list including the files listed. Similar to: - # - # FileList.new(*args) - def [](*args) - new(*args) - end - - # Get a sorted list of files matching the pattern. This method - # should be preferred to Dir[pattern] and Dir.glob(pattern) because - # the files returned are guaranteed to be sorted. - def glob(pattern, *args) - Dir.glob(pattern, *args).sort - end - end - end -end - -module Rake - class << self - - # Yield each file or directory component. - def each_dir_parent(dir) # :nodoc: - old_length = nil - while dir != "." && dir.length != old_length - yield(dir) - old_length = dir.length - dir = File.dirname(dir) - end - end - - # Convert Pathname and Pathname-like objects to strings; - # leave everything else alone - def from_pathname(path) # :nodoc: - path = path.to_path if path.respond_to?(:to_path) - path = path.to_str if path.respond_to?(:to_str) - path - end - end -end # module Rake diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_task.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_task.rb deleted file mode 100644 index c36b496..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_task.rb +++ /dev/null @@ -1,58 +0,0 @@ -# frozen_string_literal: true -require "rake/task" -require "rake/early_time" - -module Rake - - # A FileTask is a task that includes time based dependencies. If any of a - # FileTask's prerequisites have a timestamp that is later than the file - # represented by this task, then the file must be rebuilt (using the - # supplied actions). - # - class FileTask < Task - - # Is this file task needed? Yes if it doesn't exist, or if its time stamp - # is out of date. - def needed? - begin - out_of_date?(File.mtime(name)) || @application.options.build_all - rescue Errno::ENOENT - true - end - end - - # Time stamp for file task. - def timestamp - begin - File.mtime(name) - rescue Errno::ENOENT - Rake::LATE - end - end - - private - - # Are there any prerequisites with a later time than the given time stamp? - def out_of_date?(stamp) - all_prerequisite_tasks.any? { |prereq| - prereq_task = application[prereq, @scope] - if prereq_task.instance_of?(Rake::FileTask) - prereq_task.timestamp > stamp || @application.options.build_all - else - prereq_task.timestamp > stamp - end - } - end - - # ---------------------------------------------------------------- - # Task class methods. - # - class << self - # Apply the scope to the task name according to the rules for this kind - # of task. File based tasks ignore the scope when creating the name. - def scope_name(scope, task_name) - Rake.from_pathname(task_name) - end - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils.rb deleted file mode 100644 index 1510d95..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils.rb +++ /dev/null @@ -1,132 +0,0 @@ -# frozen_string_literal: true -require "rbconfig" -require "fileutils" - -#-- -# This a FileUtils extension that defines several additional commands to be -# added to the FileUtils utility functions. -module FileUtils - # Path to the currently running Ruby program - RUBY = ENV["RUBY"] || File.join( - RbConfig::CONFIG["bindir"], - RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]). - sub(/.*\s.*/m, '"\&"') - - # Run the system command +cmd+. If multiple arguments are given the command - # is run directly (without the shell, same semantics as Kernel::exec and - # Kernel::system). - # - # It is recommended you use the multiple argument form over interpolating - # user input for both usability and security reasons. With the multiple - # argument form you can easily process files with spaces or other shell - # reserved characters in them. With the multiple argument form your rake - # tasks are not vulnerable to users providing an argument like - # ; rm # -rf /. - # - # If a block is given, upon command completion the block is called with an - # OK flag (true on a zero exit status) and a Process::Status object. - # Without a block a RuntimeError is raised when the command exits non-zero. - # - # Examples: - # - # sh 'ls -ltr' - # - # sh 'ls', 'file with spaces' - # - # # check exit status after command runs - # sh %{grep pattern file} do |ok, res| - # if !ok - # puts "pattern not found (status = #{res.exitstatus})" - # end - # end - # - def sh(*cmd, &block) - options = (Hash === cmd.last) ? cmd.pop : {} - shell_runner = block_given? ? block : create_shell_runner(cmd) - - set_verbose_option(options) - verbose = options.delete :verbose - noop = options.delete(:noop) || Rake::FileUtilsExt.nowrite_flag - - Rake.rake_output_message sh_show_command cmd if verbose - - unless noop - res = (Hash === cmd.last) ? system(*cmd) : system(*cmd, options) - status = $? - status = Rake::PseudoStatus.new(1) if !res && status.nil? - shell_runner.call(res, status) - end - end - - def create_shell_runner(cmd) # :nodoc: - show_command = sh_show_command cmd - lambda do |ok, status| - ok or - fail "Command failed with status (#{status.exitstatus}): " + - "[#{show_command}]" - end - end - private :create_shell_runner - - def sh_show_command(cmd) # :nodoc: - cmd = cmd.dup - - if Hash === cmd.first - env = cmd.first - env = env.map { |name, value| "#{name}=#{value}" }.join " " - cmd[0] = env - end - - cmd.join " " - end - private :sh_show_command - - def set_verbose_option(options) # :nodoc: - unless options.key? :verbose - options[:verbose] = - (Rake::FileUtilsExt.verbose_flag == Rake::FileUtilsExt::DEFAULT) || - Rake::FileUtilsExt.verbose_flag - end - end - private :set_verbose_option - - # Run a Ruby interpreter with the given arguments. - # - # Example: - # ruby %{-pe '$_.upcase!' 1 - sh(RUBY, *args, **options, &block) - else - sh("#{RUBY} #{args.first}", **options, &block) - end - end - - LN_SUPPORTED = [true] - - # Attempt to do a normal file link, but fall back to a copy if the link - # fails. - def safe_ln(*args, **options) - if LN_SUPPORTED[0] - begin - return options.empty? ? ln(*args) : ln(*args, **options) - rescue StandardError, NotImplementedError - LN_SUPPORTED[0] = false - end - end - options.empty? ? cp(*args) : cp(*args, **options) - end - - # Split a file path into individual directory names. - # - # Example: - # split_all("a/b/c") => ['a', 'b', 'c'] - # - def split_all(path) - head, tail = File.split(path) - return [tail] if head == "." || tail == "/" - return [head, tail] if head == "/" - return split_all(head) + [tail] - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils_ext.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils_ext.rb deleted file mode 100644 index e91ad59..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/file_utils_ext.rb +++ /dev/null @@ -1,134 +0,0 @@ -# frozen_string_literal: true -require "rake/file_utils" - -module Rake - # - # FileUtilsExt provides a custom version of the FileUtils methods - # that respond to the verbose and nowrite - # commands. - # - module FileUtilsExt - include FileUtils - - class << self - attr_accessor :verbose_flag, :nowrite_flag - end - - DEFAULT = Object.new - - FileUtilsExt.verbose_flag = DEFAULT - FileUtilsExt.nowrite_flag = false - - FileUtils.commands.each do |name| - opts = FileUtils.options_of name - default_options = [] - if opts.include?("verbose") - default_options << "verbose: FileUtilsExt.verbose_flag" - end - if opts.include?("noop") - default_options << "noop: FileUtilsExt.nowrite_flag" - end - - next if default_options.empty? - module_eval(<<-EOS, __FILE__, __LINE__ + 1) - def #{name}(*args, **options, &block) - super(*args, - #{default_options.join(', ')}, - **options, &block) - end - EOS - end - - # Get/set the verbose flag controlling output from the FileUtils - # utilities. If verbose is true, then the utility method is - # echoed to standard output. - # - # Examples: - # verbose # return the current value of the - # # verbose flag - # verbose(v) # set the verbose flag to _v_. - # verbose(v) { code } # Execute code with the verbose flag set - # # temporarily to _v_. Return to the - # # original value when code is done. - def verbose(value=nil) - oldvalue = FileUtilsExt.verbose_flag - FileUtilsExt.verbose_flag = value unless value.nil? - if block_given? - begin - yield - ensure - FileUtilsExt.verbose_flag = oldvalue - end - end - FileUtilsExt.verbose_flag - end - - # Get/set the nowrite flag controlling output from the FileUtils - # utilities. If verbose is true, then the utility method is - # echoed to standard output. - # - # Examples: - # nowrite # return the current value of the - # # nowrite flag - # nowrite(v) # set the nowrite flag to _v_. - # nowrite(v) { code } # Execute code with the nowrite flag set - # # temporarily to _v_. Return to the - # # original value when code is done. - def nowrite(value=nil) - oldvalue = FileUtilsExt.nowrite_flag - FileUtilsExt.nowrite_flag = value unless value.nil? - if block_given? - begin - yield - ensure - FileUtilsExt.nowrite_flag = oldvalue - end - end - oldvalue - end - - # Use this function to prevent potentially destructive ruby code - # from running when the :nowrite flag is set. - # - # Example: - # - # when_writing("Building Project") do - # project.build - # end - # - # The following code will build the project under normal - # conditions. If the nowrite(true) flag is set, then the example - # will print: - # - # DRYRUN: Building Project - # - # instead of actually building the project. - # - def when_writing(msg=nil) - if FileUtilsExt.nowrite_flag - $stderr.puts "DRYRUN: #{msg}" if msg - else - yield - end - end - - # Send the message to the default rake output (which is $stderr). - def rake_output_message(message) - $stderr.puts(message) - end - - # Check that the options do not contain options not listed in - # +optdecl+. An ArgumentError exception is thrown if non-declared - # options are found. - def rake_check_options(options, *optdecl) - h = options.dup - optdecl.each do |name| - h.delete name - end - raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless - h.empty? - end - - extend self - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_chain.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_chain.rb deleted file mode 100644 index 44a9954..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_chain.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true -module Rake - - # InvocationChain tracks the chain of task invocations to detect - # circular dependencies. - class InvocationChain < LinkedList - - # Is the invocation already in the chain? - def member?(invocation) - head == invocation || tail.member?(invocation) - end - - # Append an invocation to the chain of invocations. It is an error - # if the invocation already listed. - def append(invocation) - if member?(invocation) - fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}" - end - conj(invocation) - end - - # Convert to string, ie: TOP => invocation => invocation - def to_s - "#{prefix}#{head}" - end - - # Class level append. - def self.append(invocation, chain) - chain.append(invocation) - end - - private - - def prefix - "#{tail} => " - end - - # Null object for an empty chain. - class EmptyInvocationChain < LinkedList::EmptyLinkedList - @parent = InvocationChain - - def member?(obj) - false - end - - def append(invocation) - conj(invocation) - end - - def to_s - "TOP" - end - end - - EMPTY = EmptyInvocationChain.new - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_exception_mixin.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_exception_mixin.rb deleted file mode 100644 index b0d307a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/invocation_exception_mixin.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -module Rake - module InvocationExceptionMixin - # Return the invocation chain (list of Rake tasks) that were in - # effect when this exception was detected by rake. May be null if - # no tasks were active. - def chain - @rake_invocation_chain ||= nil - end - - # Set the invocation chain in effect when this exception was - # detected. - def chain=(value) - @rake_invocation_chain = value - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/late_time.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/late_time.rb deleted file mode 100644 index 8fe0249..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/late_time.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -module Rake - # LateTime is a fake timestamp that occurs _after_ any other time value. - class LateTime - include Comparable - include Singleton - - def <=>(other) - 1 - end - - def to_s - "" - end - end - - LATE = LateTime.instance -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/linked_list.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/linked_list.rb deleted file mode 100644 index 11fa46f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/linked_list.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Polylithic linked list structure used to implement several data - # structures in Rake. - class LinkedList - include Enumerable - attr_reader :head, :tail - - # Polymorphically add a new element to the head of a list. The - # type of head node will be the same list type as the tail. - def conj(item) - self.class.cons(item, self) - end - - # Is the list empty? - # .make guards against a list being empty making any instantiated LinkedList - # object not empty by default - # You should consider overriding this method if you implement your own .make method - def empty? - false - end - - # Lists are structurally equivalent. - def ==(other) - current = self - while !current.empty? && !other.empty? - return false if current.head != other.head - current = current.tail - other = other.tail - end - current.empty? && other.empty? - end - - # Convert to string: LL(item, item...) - def to_s - items = map(&:to_s).join(", ") - "LL(#{items})" - end - - # Same as +to_s+, but with inspected items. - def inspect - items = map(&:inspect).join(", ") - "LL(#{items})" - end - - # For each item in the list. - def each - current = self - while !current.empty? - yield(current.head) - current = current.tail - end - self - end - - # Make a list out of the given arguments. This method is - # polymorphic - def self.make(*args) - # return an EmptyLinkedList if there are no arguments - return empty if !args || args.empty? - - # build a LinkedList by starting at the tail and iterating - # through each argument - # inject takes an EmptyLinkedList to start - args.reverse.inject(empty) do |list, item| - list = cons(item, list) - list # return the newly created list for each item in the block - end - end - - # Cons a new head onto the tail list. - def self.cons(head, tail) - new(head, tail) - end - - # The standard empty list class for the given LinkedList class. - def self.empty - self::EMPTY - end - - protected - - def initialize(head, tail=EMPTY) - @head = head - @tail = tail - end - - # Represent an empty list, using the Null Object Pattern. - # - # When inheriting from the LinkedList class, you should implement - # a type specific Empty class as well. Make sure you set the class - # instance variable @parent to the associated list class (this - # allows conj, cons and make to work polymorphically). - class EmptyLinkedList < LinkedList - @parent = LinkedList - - def initialize - end - - def empty? - true - end - - def self.cons(head, tail) - @parent.cons(head, tail) - end - end - - EMPTY = EmptyLinkedList.new - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/loaders/makefile.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/loaders/makefile.rb deleted file mode 100644 index 46f4bea..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/loaders/makefile.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Makefile loader to be used with the import file loader. Use this to - # import dependencies from make dependency tools: - # - # require 'rake/loaders/makefile' - # - # file ".depends.mf" => [SRC_LIST] do |t| - # sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" - # end - # - # import ".depends.mf" - # - # See {Importing Dependencies}[link:doc/rakefile_rdoc.html#label-Importing+Dependencies] - # for further details. - - class MakefileLoader - include Rake::DSL - - SPACE_MARK = "\0" # :nodoc: - - # Load the makefile dependencies in +fn+. - def load(fn) # :nodoc: - lines = File.read fn - lines.gsub!(/\\ /, SPACE_MARK) - lines.gsub!(/#[^\n]*\n/m, "") - lines.gsub!(/\\\n/, " ") - lines.each_line do |line| - process_line(line) - end - end - - private - - # Process one logical line of makefile data. - def process_line(line) # :nodoc: - file_tasks, args = line.split(":", 2) - return if args.nil? - dependents = args.split.map { |d| respace(d) } - file_tasks.scan(/\S+/) do |file_task| - file_task = respace(file_task) - file file_task => dependents - end - end - - def respace(str) # :nodoc: - str.tr SPACE_MARK, " " - end - end - - # Install the handler - Rake.application.add_loader("mf", MakefileLoader.new) -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/multi_task.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/multi_task.rb deleted file mode 100644 index 3ae363c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/multi_task.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Same as a regular task, but the immediate prerequisites are done in - # parallel using Ruby threads. - # - class MultiTask < Task - private - - def invoke_prerequisites(task_args, invocation_chain) # :nodoc: - invoke_prerequisites_concurrently(task_args, invocation_chain) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/name_space.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/name_space.rb deleted file mode 100644 index 32f8139..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/name_space.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true -## -# The NameSpace class will lookup task names in the scope defined by a -# +namespace+ command. - -class Rake::NameSpace - - ## - # Create a namespace lookup object using the given task manager - # and the list of scopes. - - def initialize(task_manager, scope_list) - @task_manager = task_manager - @scope = scope_list.dup - end - - ## - # Lookup a task named +name+ in the namespace. - - def [](name) - @task_manager.lookup(name, @scope) - end - - ## - # The scope of the namespace (a LinkedList) - - def scope - @scope.dup - end - - ## - # Return the list of tasks defined in this and nested namespaces. - - def tasks - @task_manager.tasks_in_scope(@scope) - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/packagetask.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/packagetask.rb deleted file mode 100644 index 1b014d1..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/packagetask.rb +++ /dev/null @@ -1,222 +0,0 @@ -# frozen_string_literal: true -# Define a package task library to aid in the definition of -# redistributable package files. - -require "rake" -require "rake/tasklib" - -module Rake - - # Create a packaging task that will package the project into - # distributable files (e.g zip archive or tar files). - # - # The PackageTask will create the following targets: - # - # +:package+ :: - # Create all the requested package files. - # - # +:clobber_package+ :: - # Delete all the package files. This target is automatically - # added to the main clobber target. - # - # +:repackage+ :: - # Rebuild the package files from scratch, even if they are not out - # of date. - # - # "package_dir/name-version.tgz" :: - # Create a gzipped tar package (if need_tar is true). - # - # "package_dir/name-version.tar.gz" :: - # Create a gzipped tar package (if need_tar_gz is true). - # - # "package_dir/name-version.tar.bz2" :: - # Create a bzip2'd tar package (if need_tar_bz2 is true). - # - # "package_dir/name-version.zip" :: - # Create a zip package archive (if need_zip is true). - # - # Example: - # - # Rake::PackageTask.new("rake", "1.2.3") do |p| - # p.need_tar = true - # p.package_files.include("lib/**/*.rb") - # end - # - class PackageTask < TaskLib - # Name of the package (from the GEM Spec). - attr_accessor :name - - # Version of the package (e.g. '1.3.2'). - attr_accessor :version - - # Directory used to store the package files (default is 'pkg'). - attr_accessor :package_dir - - # True if a gzipped tar file (tgz) should be produced (default is - # false). - attr_accessor :need_tar - - # True if a gzipped tar file (tar.gz) should be produced (default - # is false). - attr_accessor :need_tar_gz - - # True if a bzip2'd tar file (tar.bz2) should be produced (default - # is false). - attr_accessor :need_tar_bz2 - - # True if a xz'd tar file (tar.xz) should be produced (default is false) - attr_accessor :need_tar_xz - - # True if a zip file should be produced (default is false) - attr_accessor :need_zip - - # List of files to be included in the package. - attr_accessor :package_files - - # Tar command for gzipped or bzip2ed archives. The default is 'tar'. - attr_accessor :tar_command - - # Zip command for zipped archives. The default is 'zip'. - attr_accessor :zip_command - - # True if parent directory should be omitted (default is false) - attr_accessor :without_parent_dir - - # Create a Package Task with the given name and version. Use +:noversion+ - # as the version to build a package without a version or to provide a - # fully-versioned package name. - - def initialize(name=nil, version=nil) - init(name, version) - yield self if block_given? - define unless name.nil? - end - - # Initialization that bypasses the "yield self" and "define" step. - def init(name, version) - @name = name - @version = version - @package_files = Rake::FileList.new - @package_dir = "pkg" - @need_tar = false - @need_tar_gz = false - @need_tar_bz2 = false - @need_tar_xz = false - @need_zip = false - @tar_command = "tar" - @zip_command = "zip" - @without_parent_dir = false - end - - # Create the tasks defined by this task library. - def define - fail "Version required (or :noversion)" if @version.nil? - @version = nil if :noversion == @version - - desc "Build all the packages" - task :package - - desc "Force a rebuild of the package files" - task repackage: [:clobber_package, :package] - - desc "Remove package products" - task :clobber_package do - rm_r package_dir rescue nil - end - - task clobber: [:clobber_package] - - [ - [need_tar, tgz_file, "z"], - [need_tar_gz, tar_gz_file, "z"], - [need_tar_bz2, tar_bz2_file, "j"], - [need_tar_xz, tar_xz_file, "J"] - ].each do |need, file, flag| - if need - task package: ["#{package_dir}/#{file}"] - file "#{package_dir}/#{file}" => - [package_dir_path] + package_files do - chdir(working_dir) { sh @tar_command, "#{flag}cvf", file, target_dir } - mv "#{package_dir_path}/#{target_dir}", package_dir if without_parent_dir - end - end - end - - if need_zip - task package: ["#{package_dir}/#{zip_file}"] - file "#{package_dir}/#{zip_file}" => - [package_dir_path] + package_files do - chdir(working_dir) { sh @zip_command, "-r", zip_file, target_dir } - mv "#{package_dir_path}/#{zip_file}", package_dir if without_parent_dir - end - end - - directory package_dir_path => @package_files do - @package_files.each do |fn| - f = File.join(package_dir_path, fn) - fdir = File.dirname(f) - mkdir_p(fdir) unless File.exist?(fdir) - if File.directory?(fn) - mkdir_p(f) - else - rm_f f - safe_ln(fn, f) - end - end - end - self - end - - # The name of this package - - def package_name - @version ? "#{@name}-#{@version}" : @name - end - - # The directory this package will be built in - - def package_dir_path - "#{package_dir}/#{package_name}" - end - - # The package name with .tgz added - - def tgz_file - "#{package_name}.tgz" - end - - # The package name with .tar.gz added - - def tar_gz_file - "#{package_name}.tar.gz" - end - - # The package name with .tar.bz2 added - - def tar_bz2_file - "#{package_name}.tar.bz2" - end - - # The package name with .tar.xz added - - def tar_xz_file - "#{package_name}.tar.xz" - end - - # The package name with .zip added - - def zip_file - "#{package_name}.zip" - end - - def working_dir - without_parent_dir ? package_dir_path : package_dir - end - - # target directory relative to working_dir - def target_dir - without_parent_dir ? "." : package_name - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/phony.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/phony.rb deleted file mode 100644 index 8caa5de..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/phony.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Defines a :phony task that you can use as a dependency. This allows -# file-based tasks to use non-file-based tasks as prerequisites -# without forcing them to rebuild. -# -# See FileTask#out_of_date? and Task#timestamp for more info. - -require "rake" - -task :phony - -Rake::Task[:phony].tap do |task| - def task.timestamp # :nodoc: - Time.at 0 - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/private_reader.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/private_reader.rb deleted file mode 100644 index 2815ce6..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/private_reader.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Include PrivateReader to use +private_reader+. - module PrivateReader # :nodoc: all - - def self.included(base) - base.extend(ClassMethods) - end - - module ClassMethods - - # Declare a list of private accessors - def private_reader(*names) - attr_reader(*names) - private(*names) - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/promise.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/promise.rb deleted file mode 100644 index f45af4f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/promise.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true -module Rake - - # A Promise object represents a promise to do work (a chore) in the - # future. The promise is created with a block and a list of - # arguments for the block. Calling value will return the value of - # the promised chore. - # - # Used by ThreadPool. - # - class Promise # :nodoc: all - NOT_SET = Object.new.freeze # :nodoc: - - attr_accessor :recorder - - # Create a promise to do the chore specified by the block. - def initialize(args, &block) - @mutex = Mutex.new - @result = NOT_SET - @error = NOT_SET - @args = args - @block = block - end - - # Return the value of this promise. - # - # If the promised chore is not yet complete, then do the work - # synchronously. We will wait. - def value - unless complete? - stat :sleeping_on, item_id: object_id - @mutex.synchronize do - stat :has_lock_on, item_id: object_id - chore - stat :releasing_lock_on, item_id: object_id - end - end - error? ? raise(@error) : @result - end - - # If no one else is working this promise, go ahead and do the chore. - def work - stat :attempting_lock_on, item_id: object_id - if @mutex.try_lock - stat :has_lock_on, item_id: object_id - chore - stat :releasing_lock_on, item_id: object_id - @mutex.unlock - else - stat :bailed_on, item_id: object_id - end - end - - private - - # Perform the chore promised - def chore - if complete? - stat :found_completed, item_id: object_id - return - end - stat :will_execute, item_id: object_id - begin - @result = @block.call(*@args) - rescue Exception => e - @error = e - end - stat :did_execute, item_id: object_id - discard - end - - # Do we have a result for the promise - def result? - !@result.equal?(NOT_SET) - end - - # Did the promise throw an error - def error? - !@error.equal?(NOT_SET) - end - - # Are we done with the promise - def complete? - result? || error? - end - - # free up these items for the GC - def discard - @args = nil - @block = nil - end - - # Record execution statistics if there is a recorder - def stat(*args) - @recorder.call(*args) if @recorder - end - - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/pseudo_status.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/pseudo_status.rb deleted file mode 100644 index 8b3c989..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/pseudo_status.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -module Rake - - ## - # Exit status class for times the system just gives us a nil. - class PseudoStatus # :nodoc: all - attr_reader :exitstatus - - def initialize(code=0) - @exitstatus = code - end - - def to_i - @exitstatus << 8 - end - - def >>(n) - to_i >> n - end - - def stopped? - false - end - - def exited? - true - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_module.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_module.rb deleted file mode 100644 index 03c2956..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_module.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true -require "rake/application" - -module Rake - - class << self - # Current Rake Application - def application - @application ||= Rake::Application.new - end - - # Set the current Rake application object. - def application=(app) - @application = app - end - - def suggested_thread_count # :nodoc: - @cpu_count ||= Rake::CpuCounter.count - @cpu_count + 4 - end - - # Return the original directory where the Rake application was started. - def original_dir - application.original_dir - end - - # Load a rakefile. - def load_rakefile(path) - load(path) - end - - # Add files to the rakelib list - def add_rakelib(*files) - application.options.rakelib ||= [] - application.options.rakelib.concat(files) - end - - # Make +block_application+ the default rake application inside a block so - # you can load rakefiles into a different application. - # - # This is useful when you want to run rake tasks inside a library without - # running rake in a sub-shell. - # - # Example: - # - # Dir.chdir 'other/directory' - # - # other_rake = Rake.with_application do |rake| - # rake.load_rakefile - # end - # - # puts other_rake.tasks - - def with_application(block_application = Rake::Application.new) - orig_application = Rake.application - - Rake.application = block_application - - yield block_application - - block_application - ensure - Rake.application = orig_application - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_test_loader.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_test_loader.rb deleted file mode 100644 index 3ecee5d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rake_test_loader.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require "rake/file_list" - -# Load the test files from the command line. -argv = ARGV.select do |argument| - case argument - when /^-/ then - argument - when /\*/ then - Rake::FileList[argument].to_a.each do |file| - require File.expand_path file - end - - false - else - path = File.expand_path argument - - abort "\nFile does not exist: #{path}\n\n" unless File.exist?(path) - - require path - - false - end -end - -ARGV.replace argv diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rule_recursion_overflow_error.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rule_recursion_overflow_error.rb deleted file mode 100644 index a51e774..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/rule_recursion_overflow_error.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Error indicating a recursion overflow error in task selection. - class RuleRecursionOverflowError < StandardError - def initialize(*args) - super - @targets = [] - end - - def add_target(target) - @targets << target - end - - def message - super + ": [" + @targets.reverse.join(" => ") + "]" - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/scope.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/scope.rb deleted file mode 100644 index fc1eb6c..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/scope.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true -module Rake - class Scope < LinkedList # :nodoc: all - - # Path for the scope. - def path - map(&:to_s).reverse.join(":") - end - - # Path for the scope + the named path. - def path_with_task_name(task_name) - "#{path}:#{task_name}" - end - - # Trim +n+ innermost scope levels from the scope. In no case will - # this trim beyond the toplevel scope. - def trim(n) - result = self - while n > 0 && !result.empty? - result = result.tail - n -= 1 - end - result - end - - # Scope lists always end with an EmptyScope object. See Null - # Object Pattern) - class EmptyScope < EmptyLinkedList - @parent = Scope - - def path - "" - end - - def path_with_task_name(task_name) - task_name - end - end - - # Singleton null object for an empty scope. - EMPTY = EmptyScope.new - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task.rb deleted file mode 100644 index a8ed24d..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task.rb +++ /dev/null @@ -1,434 +0,0 @@ -# frozen_string_literal: true -require "rake/invocation_exception_mixin" - -module Rake - - ## - # A Task is the basic unit of work in a Rakefile. Tasks have associated - # actions (possibly more than one) and a list of prerequisites. When - # invoked, a task will first ensure that all of its prerequisites have an - # opportunity to run and then it will execute its own actions. - # - # Tasks are not usually created directly using the new method, but rather - # use the +file+ and +task+ convenience methods. - # - class Task - # List of prerequisites for a task. - attr_reader :prerequisites - alias prereqs prerequisites - - # List of order only prerequisites for a task. - attr_reader :order_only_prerequisites - - # List of actions attached to a task. - attr_reader :actions - - # Application owning this task. - attr_accessor :application - - # Array of nested namespaces names used for task lookup by this task. - attr_reader :scope - - # File/Line locations of each of the task definitions for this - # task (only valid if the task was defined with the detect - # location option set). - attr_reader :locations - - # Has this task already been invoked? Already invoked tasks - # will be skipped unless you reenable them. - attr_reader :already_invoked - - # Return task name - def to_s - name - end - - def inspect # :nodoc: - "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" - end - - # List of sources for task. - attr_writer :sources - def sources - if defined?(@sources) - @sources - else - prerequisites - end - end - - # List of prerequisite tasks - def prerequisite_tasks - (prerequisites + order_only_prerequisites).map { |pre| lookup_prerequisite(pre) } - end - - def lookup_prerequisite(prerequisite_name) # :nodoc: - scoped_prerequisite_task = application[prerequisite_name, @scope] - if scoped_prerequisite_task == self - unscoped_prerequisite_task = application[prerequisite_name] - end - unscoped_prerequisite_task || scoped_prerequisite_task - end - private :lookup_prerequisite - - # List of all unique prerequisite tasks including prerequisite tasks' - # prerequisites. - # Includes self when cyclic dependencies are found. - def all_prerequisite_tasks - seen = {} - collect_prerequisites(seen) - seen.values - end - - def collect_prerequisites(seen) # :nodoc: - prerequisite_tasks.each do |pre| - next if seen[pre.name] - seen[pre.name] = pre - pre.collect_prerequisites(seen) - end - end - protected :collect_prerequisites - - # First source from a rule (nil if no sources) - def source - sources.first - end - - # Create a task named +task_name+ with no actions or prerequisites. Use - # +enhance+ to add actions and prerequisites. - def initialize(task_name, app) - @name = task_name.to_s - @prerequisites = [] - @actions = [] - @already_invoked = false - @comments = [] - @lock = Monitor.new - @application = app - @scope = app.current_scope - @arg_names = nil - @locations = [] - @invocation_exception = nil - @order_only_prerequisites = [] - end - - # Enhance a task with prerequisites or actions. Returns self. - def enhance(deps=nil, &block) - @prerequisites |= deps if deps - @actions << block if block_given? - self - end - - # Name of the task, including any namespace qualifiers. - def name - @name.to_s - end - - # Name of task with argument list description. - def name_with_args # :nodoc: - if arg_description - "#{name}#{arg_description}" - else - name - end - end - - # Argument description (nil if none). - def arg_description # :nodoc: - @arg_names ? "[#{arg_names.join(',')}]" : nil - end - - # Name of arguments for this task. - def arg_names - @arg_names || [] - end - - # Reenable the task, allowing its tasks to be executed if the task - # is invoked again. - def reenable - @already_invoked = false - @invocation_exception = nil - end - - # Clear the existing prerequisites, actions, comments, and arguments of a rake task. - def clear - clear_prerequisites - clear_actions - clear_comments - clear_args - self - end - - # Clear the existing prerequisites of a rake task. - def clear_prerequisites - prerequisites.clear - self - end - - # Clear the existing actions on a rake task. - def clear_actions - actions.clear - self - end - - # Clear the existing comments on a rake task. - def clear_comments - @comments = [] - self - end - - # Clear the existing arguments on a rake task. - def clear_args - @arg_names = nil - self - end - - # Invoke the task if it is needed. Prerequisites are invoked first. - def invoke(*args) - task_args = TaskArguments.new(arg_names, args) - invoke_with_call_chain(task_args, InvocationChain::EMPTY) - end - - # Same as invoke, but explicitly pass a call chain to detect - # circular dependencies. - # - # If multiple tasks depend on this - # one in parallel, they will all fail if the first execution of - # this task fails. - def invoke_with_call_chain(task_args, invocation_chain) - new_chain = Rake::InvocationChain.append(self, invocation_chain) - @lock.synchronize do - begin - if application.options.trace - application.trace "** Invoke #{name} #{format_trace_flags}" - end - - if @already_invoked - if @invocation_exception - if application.options.trace - application.trace "** Previous invocation of #{name} failed #{format_trace_flags}" - end - raise @invocation_exception - else - return - end - end - - @already_invoked = true - - invoke_prerequisites(task_args, new_chain) - execute(task_args) if needed? - rescue Exception => ex - add_chain_to(ex, new_chain) - @invocation_exception = ex - raise ex - end - end - end - protected :invoke_with_call_chain - - def add_chain_to(exception, new_chain) # :nodoc: - exception.extend(InvocationExceptionMixin) unless - exception.respond_to?(:chain) - exception.chain = new_chain if exception.chain.nil? - end - private :add_chain_to - - # Invoke all the prerequisites of a task. - def invoke_prerequisites(task_args, invocation_chain) # :nodoc: - if application.options.always_multitask - invoke_prerequisites_concurrently(task_args, invocation_chain) - else - prerequisite_tasks.each { |p| - prereq_args = task_args.new_scope(p.arg_names) - p.invoke_with_call_chain(prereq_args, invocation_chain) - } - end - end - - # Invoke all the prerequisites of a task in parallel. - def invoke_prerequisites_concurrently(task_args, invocation_chain)# :nodoc: - futures = prerequisite_tasks.map do |p| - prereq_args = task_args.new_scope(p.arg_names) - application.thread_pool.future(p) do |r| - r.invoke_with_call_chain(prereq_args, invocation_chain) - end - end - # Iterate in reverse to improve performance related to thread waiting and switching - futures.reverse_each(&:value) - end - - # Format the trace flags for display. - def format_trace_flags - flags = [] - flags << "first_time" unless @already_invoked - flags << "not_needed" unless needed? - flags.empty? ? "" : "(" + flags.join(", ") + ")" - end - private :format_trace_flags - - # Execute the actions associated with this task. - def execute(args=nil) - args ||= EMPTY_TASK_ARGS - if application.options.dryrun - application.trace "** Execute (dry run) #{name}" - return - end - application.trace "** Execute #{name}" if application.options.trace - application.enhance_with_matching_rule(name) if @actions.empty? - if opts = Hash.try_convert(args) and !opts.empty? - @actions.each { |act| act.call(self, args, **opts) } - else - @actions.each { |act| act.call(self, args) } - end - end - - # Is this task needed? - def needed? - true - end - - # Timestamp for this task. Basic tasks return the current time for their - # time stamp. Other tasks can be more sophisticated. - def timestamp - Time.now - end - - # Add a description to the task. The description can consist of an option - # argument list (enclosed brackets) and an optional comment. - def add_description(description) - return unless description - comment = description.strip - add_comment(comment) if comment && !comment.empty? - end - - def comment=(comment) # :nodoc: - add_comment(comment) - end - - def add_comment(comment) # :nodoc: - return if comment.nil? - @comments << comment unless @comments.include?(comment) - end - private :add_comment - - # Full collection of comments. Multiple comments are separated by - # newlines. - def full_comment - transform_comments("\n") - end - - # First line (or sentence) of all comments. Multiple comments are - # separated by a "/". - def comment - transform_comments(" / ") { |c| first_sentence(c) } - end - - # Transform the list of comments as specified by the block and - # join with the separator. - def transform_comments(separator, &block) - if @comments.empty? - nil - else - block ||= lambda { |c| c } - @comments.map(&block).join(separator) - end - end - private :transform_comments - - # Get the first sentence in a string. The sentence is terminated - # by the first period, exclamation mark, or the end of the line. - # Decimal points do not count as periods. - def first_sentence(string) - string.split(/(?<=\w)(\.|!)[ \t]|(\.$|!)|\n/).first - end - private :first_sentence - - # Set the names of the arguments for this task. +args+ should be - # an array of symbols, one for each argument name. - def set_arg_names(args) - @arg_names = args.map(&:to_sym) - end - - # Return a string describing the internal state of a task. Useful for - # debugging. - def investigation - result = "------------------------------\n".dup - result << "Investigating #{name}\n" - result << "class: #{self.class}\n" - result << "task needed: #{needed?}\n" - result << "timestamp: #{timestamp}\n" - result << "pre-requisites: \n" - prereqs = prerequisite_tasks - prereqs.sort! { |a, b| a.timestamp <=> b.timestamp } - prereqs.each do |p| - result << "--#{p.name} (#{p.timestamp})\n" - end - latest_prereq = prerequisite_tasks.map(&:timestamp).max - result << "latest-prerequisite time: #{latest_prereq}\n" - result << "................................\n\n" - return result - end - - # Format dependencies parameter to pass to task. - def self.format_deps(deps) - deps = [deps] unless deps.respond_to?(:to_ary) - deps.map { |d| Rake.from_pathname(d).to_s } - end - - # Add order only dependencies. - def |(deps) - @order_only_prerequisites |= Task.format_deps(deps) - @prerequisites - self - end - - # ---------------------------------------------------------------- - # Rake Module Methods - # - class << self - - # Clear the task list. This cause rake to immediately forget all the - # tasks that have been assigned. (Normally used in the unit tests.) - def clear - Rake.application.clear - end - - # List of all defined tasks. - def tasks - Rake.application.tasks - end - - # Return a task with the given name. If the task is not currently - # known, try to synthesize one from the defined rules. If no rules are - # found, but an existing file matches the task name, assume it is a file - # task with no dependencies or actions. - def [](task_name) - Rake.application[task_name] - end - - # TRUE if the task name is already defined. - def task_defined?(task_name) - Rake.application.lookup(task_name) != nil - end - - # Define a task given +args+ and an option block. If a rule with the - # given name already exists, the prerequisites and actions are added to - # the existing task. Returns the defined task. - def define_task(*args, &block) - Rake.application.define_task(self, *args, &block) - end - - # Define a rule for synthesizing tasks. - def create_rule(*args, &block) - Rake.application.create_rule(*args, &block) - end - - # Apply the scope to the task name according to the rules for - # this kind of task. Generic tasks will accept the scope as - # part of the name. - def scope_name(scope, task_name) - scope.path_with_task_name(task_name) - end - - end # class << Rake::Task - end # class Rake::Task -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_argument_error.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_argument_error.rb deleted file mode 100644 index ef20076..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_argument_error.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -module Rake - - # Error indicating an ill-formed task declaration. - class TaskArgumentError < ArgumentError - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_arguments.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_arguments.rb deleted file mode 100644 index 0d3001a..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_arguments.rb +++ /dev/null @@ -1,109 +0,0 @@ -# frozen_string_literal: true -module Rake - - ## - # TaskArguments manage the arguments passed to a task. - # - class TaskArguments - include Enumerable - - # Argument names - attr_reader :names - - # Create a TaskArgument object with a list of argument +names+ and a set - # of associated +values+. +parent+ is the parent argument object. - def initialize(names, values, parent=nil) - @names = names - @parent = parent - @hash = {} - @values = values - names.each_with_index { |name, i| - next if values[i].nil? || values[i] == "" - @hash[name.to_sym] = values[i] - } - end - - # Retrieve the complete array of sequential values - def to_a - @values.dup - end - - # Retrieve the list of values not associated with named arguments - def extras - @values[@names.length..-1] || [] - end - - # Create a new argument scope using the prerequisite argument - # names. - def new_scope(names) - values = names.map { |n| self[n] } - self.class.new(names, values + extras, self) - end - - # Find an argument value by name or index. - def [](index) - lookup(index.to_sym) - end - - # Specify a hash of default values for task arguments. Use the - # defaults only if there is no specific value for the given - # argument. - def with_defaults(defaults) - @hash = defaults.merge(@hash) - end - - # Enumerates the arguments and their values - def each(&block) - @hash.each(&block) - end - - # Extracts the argument values at +keys+ - def values_at(*keys) - keys.map { |k| lookup(k) } - end - - # Returns the value of the given argument via method_missing - def method_missing(sym, *args) - lookup(sym.to_sym) - end - - # Returns a Hash of arguments and their values - def to_hash - @hash.dup - end - - def to_s # :nodoc: - inspect - end - - def inspect # :nodoc: - inspection = @hash.map do |k,v| - "#{k.to_s}: #{v.to_s}" - end.join(", ") - - "#<#{self.class} #{inspection}>" - end - - # Returns true if +key+ is one of the arguments - def has_key?(key) - @hash.has_key?(key) - end - alias key? has_key? - - def fetch(*args, &block) - @hash.fetch(*args, &block) - end - - protected - - def lookup(name) # :nodoc: - if @hash.has_key?(name) - @hash[name] - elsif @parent - @parent.lookup(name) - end - end - end - - EMPTY_TASK_ARGS = TaskArguments.new([], []) # :nodoc: -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_manager.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_manager.rb deleted file mode 100644 index 0db5c24..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/task_manager.rb +++ /dev/null @@ -1,331 +0,0 @@ -# frozen_string_literal: true -module Rake - - # The TaskManager module is a mixin for managing tasks. - module TaskManager - # Track the last comment made in the Rakefile. - attr_accessor :last_description - - def initialize # :nodoc: - super - @tasks = Hash.new - @rules = Array.new - @scope = Scope.make - @last_description = nil - end - - def create_rule(*args, &block) # :nodoc: - pattern, args, deps, order_only = resolve_args(args) - pattern = Regexp.new(Regexp.quote(pattern) + "$") if String === pattern - @rules << [pattern, args, deps, order_only, block] - end - - def define_task(task_class, *args, &block) # :nodoc: - task_name, arg_names, deps, order_only = resolve_args(args) - - original_scope = @scope - if String === task_name and - not task_class.ancestors.include? Rake::FileTask - task_name, *definition_scope = *(task_name.split(":").reverse) - @scope = Scope.make(*(definition_scope + @scope.to_a)) - end - - task_name = task_class.scope_name(@scope, task_name) - task = intern(task_class, task_name) - task.set_arg_names(arg_names) unless arg_names.empty? - if Rake::TaskManager.record_task_metadata - add_location(task) - task.add_description(get_description(task)) - end - task.enhance(Task.format_deps(deps), &block) - task | order_only unless order_only.nil? - task - ensure - @scope = original_scope - end - - # Lookup a task. Return an existing task if found, otherwise - # create a task of the current type. - def intern(task_class, task_name) - @tasks[task_name.to_s] ||= task_class.new(task_name, self) - end - - # Find a matching task for +task_name+. - def [](task_name, scopes=nil) - task_name = task_name.to_s - self.lookup(task_name, scopes) or - enhance_with_matching_rule(task_name) or - synthesize_file_task(task_name) or - fail generate_message_for_undefined_task(task_name) - end - - def generate_message_for_undefined_task(task_name) - message = "Don't know how to build task '#{task_name}' "\ - "(See the list of available tasks with `#{Rake.application.name} --tasks`)" - message + generate_did_you_mean_suggestions(task_name) - end - - def generate_did_you_mean_suggestions(task_name) - return "" unless defined?(::DidYouMean::SpellChecker) - - suggestions = ::DidYouMean::SpellChecker.new(dictionary: @tasks.keys).correct(task_name.to_s) - if ::DidYouMean.respond_to?(:formatter)# did_you_mean v1.2.0 or later - ::DidYouMean.formatter.message_for(suggestions) - elsif defined?(::DidYouMean::Formatter) # before did_you_mean v1.2.0 - ::DidYouMean::Formatter.new(suggestions).to_s - else - "" - end - end - - def synthesize_file_task(task_name) # :nodoc: - return nil unless File.exist?(task_name) - define_task(Rake::FileTask, task_name) - end - - # Resolve the arguments for a task/rule. Returns a tuple of - # [task_name, arg_name_list, prerequisites, order_only_prerequisites]. - def resolve_args(args) - if args.last.is_a?(Hash) - deps = args.pop - resolve_args_with_dependencies(args, deps) - else - resolve_args_without_dependencies(args) - end - end - - # Resolve task arguments for a task or rule when there are no - # dependencies declared. - # - # The patterns recognized by this argument resolving function are: - # - # task :t - # task :t, [:a] - # - def resolve_args_without_dependencies(args) - task_name = args.shift - if args.size == 1 && args.first.respond_to?(:to_ary) - arg_names = args.first.to_ary - else - arg_names = args - end - [task_name, arg_names, [], nil] - end - private :resolve_args_without_dependencies - - # Resolve task arguments for a task or rule when there are - # dependencies declared. - # - # The patterns recognized by this argument resolving function are: - # - # task :t, order_only: [:e] - # task :t => [:d] - # task :t => [:d], order_only: [:e] - # task :t, [a] => [:d] - # task :t, [a] => [:d], order_only: [:e] - # - def resolve_args_with_dependencies(args, hash) # :nodoc: - fail "Task Argument Error" if - hash.size != 1 && - (hash.size != 2 || !hash.key?(:order_only)) - order_only = hash.delete(:order_only) - key, value = hash.map { |k, v| [k, v] }.first - if args.empty? - task_name = key - arg_names = [] - deps = value || [] - else - task_name = args.shift - arg_names = key || args.shift|| [] - deps = value || [] - end - deps = [deps] unless deps.respond_to?(:to_ary) - [task_name, arg_names, deps, order_only] - end - private :resolve_args_with_dependencies - - # If a rule can be found that matches the task name, enhance the - # task with the prerequisites and actions from the rule. Set the - # source attribute of the task appropriately for the rule. Return - # the enhanced task or nil of no rule was found. - def enhance_with_matching_rule(task_name, level=0) - fail Rake::RuleRecursionOverflowError, - "Rule Recursion Too Deep" if level >= 16 - @rules.each do |pattern, args, extensions, order_only, block| - if pattern && pattern.match(task_name) - task = attempt_rule(task_name, pattern, args, extensions, block, level) - task | order_only unless order_only.nil? - return task if task - end - end - nil - rescue Rake::RuleRecursionOverflowError => ex - ex.add_target(task_name) - fail ex - end - - # List of all defined tasks in this application. - def tasks - @tasks.values.sort_by { |t| t.name } - end - - # List of all the tasks defined in the given scope (and its - # sub-scopes). - def tasks_in_scope(scope) - prefix = scope.path - tasks.select { |t| - /^#{prefix}:/ =~ t.name - } - end - - # Clear all tasks in this application. - def clear - @tasks.clear - @rules.clear - end - - # Lookup a task, using scope and the scope hints in the task name. - # This method performs straight lookups without trying to - # synthesize file tasks or rules. Special scope names (e.g. '^') - # are recognized. If no scope argument is supplied, use the - # current scope. Return nil if the task cannot be found. - def lookup(task_name, initial_scope=nil) - initial_scope ||= @scope - task_name = task_name.to_s - if task_name =~ /^rake:/ - scopes = Scope.make - task_name = task_name.sub(/^rake:/, "") - elsif task_name =~ /^(\^+)/ - scopes = initial_scope.trim($1.size) - task_name = task_name.sub(/^(\^+)/, "") - else - scopes = initial_scope - end - lookup_in_scope(task_name, scopes) - end - - # Lookup the task name - def lookup_in_scope(name, scope) - loop do - tn = scope.path_with_task_name(name) - task = @tasks[tn] - return task if task - break if scope.empty? - scope = scope.tail - end - nil - end - private :lookup_in_scope - - # Return the list of scope names currently active in the task - # manager. - def current_scope - @scope - end - - # Evaluate the block in a nested namespace named +name+. Create - # an anonymous namespace if +name+ is nil. - def in_namespace(name) - name ||= generate_name - @scope = Scope.new(name, @scope) - ns = NameSpace.new(self, @scope) - yield(ns) - ns - ensure - @scope = @scope.tail - end - - private - - # Add a location to the locations field of the given task. - def add_location(task) - loc = find_location - task.locations << loc if loc - task - end - - # Find the location that called into the dsl layer. - def find_location - locations = caller - i = 0 - while locations[i] - return locations[i + 1] if locations[i] =~ /rake\/dsl_definition.rb/ - i += 1 - end - nil - end - - # Generate an anonymous namespace name. - def generate_name - @seed ||= 0 - @seed += 1 - "_anon_#{@seed}" - end - - def trace_rule(level, message) # :nodoc: - options.trace_output.puts "#{" " * level}#{message}" if - Rake.application.options.trace_rules - end - - # Attempt to create a rule given the list of prerequisites. - def attempt_rule(task_name, task_pattern, args, extensions, block, level) - sources = make_sources(task_name, task_pattern, extensions) - prereqs = sources.map { |source| - trace_rule level, "Attempting Rule #{task_name} => #{source}" - if File.exist?(source) || Rake::Task.task_defined?(source) - trace_rule level, "(#{task_name} => #{source} ... EXIST)" - source - elsif parent = enhance_with_matching_rule(source, level + 1) - trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" - parent.name - else - trace_rule level, "(#{task_name} => #{source} ... FAIL)" - return nil - end - } - task = FileTask.define_task(task_name, { args => prereqs }, &block) - task.sources = prereqs - task - end - - # Make a list of sources from the list of file name extensions / - # translation procs. - def make_sources(task_name, task_pattern, extensions) - result = extensions.map { |ext| - case ext - when /%/ - task_name.pathmap(ext) - when %r{/} - ext - when /^\./ - source = task_name.sub(task_pattern, ext) - source == ext ? task_name.ext(ext) : source - when String, Symbol - ext.to_s - when Proc, Method - if ext.arity == 1 - ext.call(task_name) - else - ext.call - end - else - fail "Don't know how to handle rule dependent: #{ext.inspect}" - end - } - result.flatten - end - - # Return the current description, clearing it in the process. - def get_description(task) - desc = @last_description - @last_description = nil - desc - end - - class << self - attr_accessor :record_task_metadata # :nodoc: - TaskManager.record_task_metadata = false - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/tasklib.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/tasklib.rb deleted file mode 100644 index 5354b4f..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/tasklib.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -require "rake" - -module Rake - - # Base class for Task Libraries. - class TaskLib - include Cloneable - include Rake::DSL - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/testtask.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/testtask.rb deleted file mode 100644 index 56521d2..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/testtask.rb +++ /dev/null @@ -1,189 +0,0 @@ -# frozen_string_literal: true -require "rake" -require "rake/tasklib" - -module Rake - - # Create a task that runs a set of tests. - # - # Example: - # require "rake/testtask" - # - # Rake::TestTask.new do |t| - # t.libs << "test" - # t.test_files = FileList['test/test*.rb'] - # t.verbose = true - # end - # - # If rake is invoked with a "TEST=filename" command line option, - # then the list of test files will be overridden to include only the - # filename specified on the command line. This provides an easy way - # to run just one test. - # - # If rake is invoked with a "TESTOPTS=options" command line option, - # then the given options are passed to the test process after a - # '--'. This allows Test::Unit options to be passed to the test - # suite. - # - # Examples: - # - # rake test # run tests normally - # rake test TEST=just_one_file.rb # run just one test file. - # rake test TESTOPTS="-v" # run in verbose mode - # rake test TESTOPTS="--runner=fox" # use the fox test runner - # - class TestTask < TaskLib - - # Name of test task. (default is :test) - attr_accessor :name - - # List of directories added to $LOAD_PATH before running the - # tests. (default is 'lib') - attr_accessor :libs - - # True if verbose test output desired. (default is false) - attr_accessor :verbose - - # Test options passed to the test suite. An explicit - # TESTOPTS=opts on the command line will override this. (default - # is NONE) - attr_accessor :options - - # Request that the tests be run with the warning flag set. - # E.g. warning=true implies "ruby -w" used to run the tests. - # (default is true) - attr_accessor :warning - - # Glob pattern to match test files. (default is 'test/test*.rb') - attr_accessor :pattern - - # Style of test loader to use. Options are: - # - # * :rake -- Rake provided test loading script (default). - # * :testrb -- Ruby provided test loading script. - # * :direct -- Load tests using command line loader. - # - attr_accessor :loader - - # Array of command line options to pass to ruby when running test loader. - attr_accessor :ruby_opts - - # Description of the test task. (default is 'Run tests') - attr_accessor :description - - # Task prerequisites. - attr_accessor :deps - - # Explicitly define the list of test files to be included in a - # test. +list+ is expected to be an array of file names (a - # FileList is acceptable). If both +pattern+ and +test_files+ are - # used, then the list of test files is the union of the two. - def test_files=(list) - @test_files = list - end - - # Create a testing task. - def initialize(name=:test) - @name = name - @libs = ["lib"] - @pattern = nil - @options = nil - @test_files = nil - @verbose = false - @warning = true - @loader = :rake - @ruby_opts = [] - @description = "Run tests" + (@name == :test ? "" : " for #{@name}") - @deps = [] - if @name.is_a?(Hash) - @deps = @name.values.first - @name = @name.keys.first - end - yield self if block_given? - @pattern = "test/test*.rb" if @pattern.nil? && @test_files.nil? - define - end - - # Create the tasks defined by this task lib. - def define - desc @description - task @name => Array(deps) do - FileUtilsExt.verbose(@verbose) do - puts "Use TESTOPTS=\"--verbose\" to pass --verbose" \ - ", etc. to runners." if ARGV.include? "--verbose" - args = - "#{ruby_opts_string} #{run_code} " + - "#{file_list_string} #{option_list}" - ruby args do |ok, status| - if !ok && status.respond_to?(:signaled?) && status.signaled? - raise SignalException.new(status.termsig) - elsif !ok - status = "Command failed with status (#{status.exitstatus})" - details = ": [ruby #{args}]" - message = - if Rake.application.options.trace or @verbose - status + details - else - status - end - - fail message - end - end - end - end - self - end - - def option_list # :nodoc: - (ENV["TESTOPTS"] || - ENV["TESTOPT"] || - ENV["TEST_OPTS"] || - ENV["TEST_OPT"] || - @options || - "") - end - - def ruby_opts_string # :nodoc: - opts = @ruby_opts.dup - opts.unshift("-I\"#{lib_path}\"") unless @libs.empty? - opts.unshift("-w") if @warning - opts.join(" ") - end - - def lib_path # :nodoc: - @libs.join(File::PATH_SEPARATOR) - end - - def file_list_string # :nodoc: - file_list.map { |fn| "\"#{fn}\"" }.join(" ") - end - - def file_list # :nodoc: - if ENV["TEST"] - FileList[ENV["TEST"]] - else - result = [] - result += @test_files.to_a if @test_files - result += FileList[@pattern].to_a if @pattern - result - end - end - - def ruby_version # :nodoc: - RUBY_VERSION - end - - def run_code # :nodoc: - case @loader - when :direct - "-e \"ARGV.each{|f| require f}\"" - when :testrb - "-S testrb" - when :rake - "#{__dir__}/rake_test_loader.rb" - end - end - - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_history_display.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_history_display.rb deleted file mode 100644 index 412ea37..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_history_display.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true -require "rake/private_reader" - -module Rake - - class ThreadHistoryDisplay # :nodoc: all - include Rake::PrivateReader - - private_reader :stats, :items, :threads - - def initialize(stats) - @stats = stats - @items = { _seq_: 1 } - @threads = { _seq_: "A" } - end - - def show - puts "Job History:" - stats.each do |stat| - stat[:data] ||= {} - rename(stat, :thread, threads) - rename(stat[:data], :item_id, items) - rename(stat[:data], :new_thread, threads) - rename(stat[:data], :deleted_thread, threads) - printf("%8d %2s %-20s %s\n", - (stat[:time] * 1_000_000).round, - stat[:thread], - stat[:event], - stat[:data].map do |k, v| "#{k}:#{v}" end.join(" ")) - end - end - - private - - def rename(hash, key, renames) - if hash && hash[key] - original = hash[key] - value = renames[original] - unless value - value = renames[:_seq_] - renames[:_seq_] = renames[:_seq_].succ - renames[original] = value - end - hash[key] = value - end - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_pool.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_pool.rb deleted file mode 100644 index 76aa3b7..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/thread_pool.rb +++ /dev/null @@ -1,163 +0,0 @@ -# frozen_string_literal: true - -require "rake/promise" -require "set" - -module Rake - - class ThreadPool # :nodoc: all - - # Creates a ThreadPool object. The +thread_count+ parameter is the size - # of the pool. - def initialize(thread_count) - @max_active_threads = [thread_count, 0].max - @threads = Set.new - @threads_mon = Monitor.new - @queue = Queue.new - @join_cond = @threads_mon.new_cond - - @history_start_time = nil - @history = [] - @history_mon = Monitor.new - @total_threads_in_play = 0 - end - - # Creates a future executed by the +ThreadPool+. - # - # The args are passed to the block when executing (similarly to - # Thread#new) The return value is an object representing - # a future which has been created and added to the queue in the - # pool. Sending #value to the object will sleep the - # current thread until the future is finished and will return the - # result (or raise an exception thrown from the future) - def future(*args, &block) - promise = Promise.new(args, &block) - promise.recorder = lambda { |*stats| stat(*stats) } - - @queue.enq promise - stat :queued, item_id: promise.object_id - start_thread - promise - end - - # Waits until the queue of futures is empty and all threads have exited. - def join - @threads_mon.synchronize do - begin - stat :joining - @join_cond.wait unless @threads.empty? - stat :joined - rescue Exception => e - stat :joined - $stderr.puts e - $stderr.print "Queue contains #{@queue.size} items. " + - "Thread pool contains #{@threads.count} threads\n" - $stderr.print "Current Thread #{Thread.current} status = " + - "#{Thread.current.status}\n" - $stderr.puts e.backtrace.join("\n") - @threads.each do |t| - $stderr.print "Thread #{t} status = #{t.status}\n" - $stderr.puts t.backtrace.join("\n") - end - raise e - end - end - end - - # Enable the gathering of history events. - def gather_history #:nodoc: - @history_start_time = Time.now if @history_start_time.nil? - end - - # Return a array of history events for the thread pool. - # - # History gathering must be enabled to be able to see the events - # (see #gather_history). Best to call this when the job is - # complete (i.e. after ThreadPool#join is called). - def history # :nodoc: - @history_mon.synchronize { @history.dup }. - sort_by { |i| i[:time] }. - each { |i| i[:time] -= @history_start_time } - end - - # Return a hash of always collected statistics for the thread pool. - def statistics # :nodoc: - { - total_threads_in_play: @total_threads_in_play, - max_active_threads: @max_active_threads, - } - end - - private - - # processes one item on the queue. Returns true if there was an - # item to process, false if there was no item - def process_queue_item #:nodoc: - return false if @queue.empty? - - # Even though we just asked if the queue was empty, it - # still could have had an item which by this statement - # is now gone. For this reason we pass true to Queue#deq - # because we will sleep indefinitely if it is empty. - promise = @queue.deq(true) - stat :dequeued, item_id: promise.object_id - promise.work - return true - - rescue ThreadError # this means the queue is empty - false - end - - def safe_thread_count - @threads_mon.synchronize do - @threads.count - end - end - - def start_thread # :nodoc: - @threads_mon.synchronize do - next unless @threads.count < @max_active_threads - - t = Thread.new do - begin - while safe_thread_count <= @max_active_threads - break unless process_queue_item - end - ensure - @threads_mon.synchronize do - @threads.delete Thread.current - stat :ended, thread_count: @threads.count - @join_cond.broadcast if @threads.empty? - end - end - end - - @threads << t - stat( - :spawned, - new_thread: t.object_id, - thread_count: @threads.count) - @total_threads_in_play = @threads.count if - @threads.count > @total_threads_in_play - end - end - - def stat(event, data=nil) # :nodoc: - return if @history_start_time.nil? - info = { - event: event, - data: data, - time: Time.now, - thread: Thread.current.object_id, - } - @history_mon.synchronize { @history << info } - end - - # for testing only - - def __queue__ # :nodoc: - @queue - end - end - -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/trace_output.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/trace_output.rb deleted file mode 100644 index d713a09..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/trace_output.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -module Rake - module TraceOutput # :nodoc: all - - # Write trace output to output stream +out+. - # - # The write is done as a single IO call (to print) to lessen the - # chance that the trace output is interrupted by other tasks also - # producing output. - def trace_on(out, *strings) - sep = $\ || "\n" - if strings.empty? - output = sep - else - output = strings.map { |s| - next if s.nil? - s.end_with?(sep) ? s : s + sep - }.join - end - out.print(output) - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/version.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/version.rb deleted file mode 100644 index bba5f1b..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/version.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -module Rake - VERSION = "13.2.1" - - module Version # :nodoc: all - MAJOR, MINOR, BUILD, *OTHER = Rake::VERSION.split "." - - NUMBERS = [MAJOR, MINOR, BUILD, *OTHER] - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/win32.rb b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/win32.rb deleted file mode 100644 index 6e62031..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/lib/rake/win32.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true -require "rbconfig" - -module Rake - # Win 32 interface methods for Rake. Windows specific functionality - # will be placed here to collect that knowledge in one spot. - module Win32 # :nodoc: all - - # Error indicating a problem in locating the home directory on a - # Win32 system. - class Win32HomeError < RuntimeError - end - - class << self - # True if running on a windows system. - def windows? - RbConfig::CONFIG["host_os"] =~ %r!(msdos|mswin|djgpp|mingw|[Ww]indows)! - end - - # The standard directory containing system wide rake files on - # Win 32 systems. Try the following environment variables (in - # order): - # - # * HOME - # * HOMEDRIVE + HOMEPATH - # * APPDATA - # * USERPROFILE - # - # If the above are not defined, the return nil. - def win32_system_dir #:nodoc: - win32_shared_path = ENV["HOME"] - if win32_shared_path.nil? && ENV["HOMEDRIVE"] && ENV["HOMEPATH"] - win32_shared_path = ENV["HOMEDRIVE"] + ENV["HOMEPATH"] - end - - win32_shared_path ||= ENV["APPDATA"] - win32_shared_path ||= ENV["USERPROFILE"] - raise Win32HomeError, - "Unable to determine home path environment variable." if - win32_shared_path.nil? or win32_shared_path.empty? - normalize(File.join(win32_shared_path, "Rake")) - end - - # Normalize a win32 path so that the slashes are all forward slashes. - def normalize(path) - path.gsub(/\\/, "/") - end - - end - end -end diff --git a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/rake.gemspec b/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/rake.gemspec deleted file mode 100644 index b3e8a8e..0000000 --- a/vendor/bundle/ruby/2.6.0/gems/rake-13.2.1/rake.gemspec +++ /dev/null @@ -1,101 +0,0 @@ -# frozen_string_literal: true - -require_relative "lib/rake/version" - -Gem::Specification.new do |s| - s.name = "rake" - s.version = Rake::VERSION - s.authors = ["Hiroshi SHIBATA", "Eric Hodel", "Jim Weirich"] - s.email = ["hsbt@ruby-lang.org", "drbrain@segment7.net", ""] - - s.summary = "Rake is a Make-like program implemented in Ruby" - s.description = <<~DESCRIPTION - Rake is a Make-like program implemented in Ruby. Tasks and dependencies are - specified in standard Ruby syntax. - Rake has the following features: - * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax. - No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?) - * Users can specify tasks with prerequisites. - * Rake supports rule patterns to synthesize implicit tasks. - * Flexible FileLists that act like arrays but know about manipulating file names and paths. - * Supports parallel execution of tasks. - DESCRIPTION - s.homepage = "https://github.com/ruby/rake" - s.licenses = ["MIT"] - - s.metadata = { - "bug_tracker_uri" => "https://github.com/ruby/rake/issues", - "changelog_uri" => "https://github.com/ruby/rake/blob/v#{s.version}/History.rdoc", - "documentation_uri" => "https://ruby.github.io/rake", - "source_code_uri" => "https://github.com/ruby/rake/tree/v#{s.version}" - } - - s.files = [ - "History.rdoc", - "MIT-LICENSE", - "README.rdoc", - "doc/command_line_usage.rdoc", - "doc/example/Rakefile1", - "doc/example/Rakefile2", - "doc/example/a.c", - "doc/example/b.c", - "doc/example/main.c", - "doc/glossary.rdoc", - "doc/jamis.rb", - "doc/proto_rake.rdoc", - "doc/rake.1", - "doc/rakefile.rdoc", - "doc/rational.rdoc", - "exe/rake", - "lib/rake.rb", - "lib/rake/application.rb", - "lib/rake/backtrace.rb", - "lib/rake/clean.rb", - "lib/rake/cloneable.rb", - "lib/rake/cpu_counter.rb", - "lib/rake/default_loader.rb", - "lib/rake/dsl_definition.rb", - "lib/rake/early_time.rb", - "lib/rake/ext/core.rb", - "lib/rake/ext/string.rb", - "lib/rake/file_creation_task.rb", - "lib/rake/file_list.rb", - "lib/rake/file_task.rb", - "lib/rake/file_utils.rb", - "lib/rake/file_utils_ext.rb", - "lib/rake/invocation_chain.rb", - "lib/rake/invocation_exception_mixin.rb", - "lib/rake/late_time.rb", - "lib/rake/linked_list.rb", - "lib/rake/loaders/makefile.rb", - "lib/rake/multi_task.rb", - "lib/rake/name_space.rb", - "lib/rake/packagetask.rb", - "lib/rake/phony.rb", - "lib/rake/private_reader.rb", - "lib/rake/promise.rb", - "lib/rake/pseudo_status.rb", - "lib/rake/rake_module.rb", - "lib/rake/rake_test_loader.rb", - "lib/rake/rule_recursion_overflow_error.rb", - "lib/rake/scope.rb", - "lib/rake/task.rb", - "lib/rake/task_argument_error.rb", - "lib/rake/task_arguments.rb", - "lib/rake/task_manager.rb", - "lib/rake/tasklib.rb", - "lib/rake/testtask.rb", - "lib/rake/thread_history_display.rb", - "lib/rake/thread_pool.rb", - "lib/rake/trace_output.rb", - "lib/rake/version.rb", - "lib/rake/win32.rb", - "rake.gemspec" - ] - s.bindir = "exe" - s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) } - s.require_paths = ["lib"] - - s.required_ruby_version = Gem::Requirement.new(">= 2.3") - s.rdoc_options = ["--main", "README.rdoc"] -end diff --git a/vendor/bundle/ruby/2.6.0/specifications/addressable-2.8.7.gemspec b/vendor/bundle/ruby/2.6.0/specifications/addressable-2.8.7.gemspec deleted file mode 100644 index 55232bb..0000000 --- a/vendor/bundle/ruby/2.6.0/specifications/addressable-2.8.7.gemspec +++ /dev/null @@ -1,40 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: addressable 2.8.7 ruby lib - -Gem::Specification.new do |s| - s.name = "addressable".freeze - s.version = "2.8.7" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v2.8.7" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Bob Aman".freeze] - s.date = "2024-06-21" - s.description = "Addressable is an alternative implementation to the URI implementation that is\npart of Ruby's standard library. It is flexible, offers heuristic parsing, and\nadditionally provides extensive support for IRIs and URI templates.\n".freeze - s.email = "bob@sporkmonger.com".freeze - s.extra_rdoc_files = ["README.md".freeze] - s.files = ["README.md".freeze] - s.homepage = "https://github.com/sporkmonger/addressable".freeze - s.licenses = ["Apache-2.0".freeze] - s.rdoc_options = ["--main".freeze, "README.md".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze) - s.rubygems_version = "3.0.3.1".freeze - s.summary = "URI Implementation".freeze - - s.installed_by_version = "3.0.3.1" if s.respond_to? :installed_by_version - - if s.respond_to? :specification_version then - s.specification_version = 4 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q.freeze, [">= 2.0.2", "< 7.0"]) - s.add_development_dependency(%q.freeze, [">= 1.0", "< 3.0"]) - else - s.add_dependency(%q.freeze, [">= 2.0.2", "< 7.0"]) - s.add_dependency(%q.freeze, [">= 1.0", "< 3.0"]) - end - else - s.add_dependency(%q.freeze, [">= 2.0.2", "< 7.0"]) - s.add_dependency(%q.freeze, [">= 1.0", "< 3.0"]) - end -end diff --git a/vendor/bundle/ruby/2.6.0/specifications/colorator-1.1.0.gemspec b/vendor/bundle/ruby/2.6.0/specifications/colorator-1.1.0.gemspec deleted file mode 100644 index 0663736..0000000 --- a/vendor/bundle/ruby/2.6.0/specifications/colorator-1.1.0.gemspec +++ /dev/null @@ -1,34 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: colorator 1.1.0 ruby lib - -Gem::Specification.new do |s| - s.name = "colorator".freeze - s.version = "1.1.0" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib".freeze] - s.authors = ["Parker Moore".freeze, "Brandon Mathis".freeze] - s.date = "2016-06-29" - s.email = ["parkrmoore@gmail.com".freeze, "brandon@imathis.com".freeze] - s.extra_rdoc_files = ["README.markdown".freeze, "LICENSE".freeze] - s.files = ["LICENSE".freeze, "README.markdown".freeze] - s.homepage = "https://github.com/octopress/colorator".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--charset=UTF-8".freeze] - s.rubygems_version = "3.0.3.1".freeze - s.summary = "Colorize your text in the terminal.".freeze - - s.installed_by_version = "3.0.3.1" if s.respond_to? :installed_by_version - - if s.respond_to? :specification_version then - s.specification_version = 4 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q.freeze, ["~> 3.1"]) - else - s.add_dependency(%q.freeze, ["~> 3.1"]) - end - else - s.add_dependency(%q.freeze, ["~> 3.1"]) - end -end diff --git a/vendor/bundle/ruby/2.6.0/specifications/concurrent-ruby-1.3.4.gemspec b/vendor/bundle/ruby/2.6.0/specifications/concurrent-ruby-1.3.4.gemspec deleted file mode 100644 index 28c52a5..0000000 --- a/vendor/bundle/ruby/2.6.0/specifications/concurrent-ruby-1.3.4.gemspec +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: concurrent-ruby 1.3.4 ruby lib/concurrent-ruby - -Gem::Specification.new do |s| - s.name = "concurrent-ruby".freeze - s.version = "1.3.4" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "changelog_uri" => "https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md", "source_code_uri" => "https://github.com/ruby-concurrency/concurrent-ruby" } if s.respond_to? :metadata= - s.require_paths = ["lib/concurrent-ruby".freeze] - s.authors = ["Jerry D'Antonio".freeze, "Petr Chalupa".freeze, "The Ruby Concurrency Team".freeze] - s.date = "2024-08-10" - s.description = "Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.\nInspired by Erlang, Clojure, Go, JavaScript, actors, and classic concurrency patterns.\n".freeze - s.email = "concurrent-ruby@googlegroups.com".freeze - s.extra_rdoc_files = ["README.md".freeze, "LICENSE.txt".freeze, "CHANGELOG.md".freeze] - s.files = ["CHANGELOG.md".freeze, "LICENSE.txt".freeze, "README.md".freeze] - s.homepage = "http://www.concurrent-ruby.com".freeze - s.licenses = ["MIT".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze) - s.rubygems_version = "3.0.3.1".freeze - s.summary = "Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns.".freeze - - s.installed_by_version = "3.0.3.1" if s.respond_to? :installed_by_version -end diff --git a/vendor/bundle/ruby/2.6.0/specifications/public_suffix-5.1.1.gemspec b/vendor/bundle/ruby/2.6.0/specifications/public_suffix-5.1.1.gemspec deleted file mode 100644 index 83f9269..0000000 --- a/vendor/bundle/ruby/2.6.0/specifications/public_suffix-5.1.1.gemspec +++ /dev/null @@ -1,24 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: public_suffix 5.1.1 ruby lib - -Gem::Specification.new do |s| - s.name = "public_suffix".freeze - s.version = "5.1.1" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/weppos/publicsuffix-ruby/issues", "changelog_uri" => "https://github.com/weppos/publicsuffix-ruby/blob/master/CHANGELOG.md", "documentation_uri" => "https://rubydoc.info/gems/public_suffix/5.1.1", "homepage_uri" => "https://simonecarletti.com/code/publicsuffix-ruby", "source_code_uri" => "https://github.com/weppos/publicsuffix-ruby/tree/v5.1.1" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Simone Carletti".freeze] - s.date = "2024-06-17" - s.description = "PublicSuffix can parse and decompose a domain name into top level domain, domain and subdomains.".freeze - s.email = ["weppos@weppos.net".freeze] - s.extra_rdoc_files = ["LICENSE.txt".freeze] - s.files = ["LICENSE.txt".freeze] - s.homepage = "https://simonecarletti.com/code/publicsuffix-ruby".freeze - s.licenses = ["MIT".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.6".freeze) - s.rubygems_version = "3.0.3.1".freeze - s.summary = "Domain name parser based on the Public Suffix List.".freeze - - s.installed_by_version = "3.0.3.1" if s.respond_to? :installed_by_version -end diff --git a/vendor/bundle/ruby/2.6.0/specifications/rake-13.2.1.gemspec b/vendor/bundle/ruby/2.6.0/specifications/rake-13.2.1.gemspec deleted file mode 100644 index f6da5a1..0000000 --- a/vendor/bundle/ruby/2.6.0/specifications/rake-13.2.1.gemspec +++ /dev/null @@ -1,26 +0,0 @@ -# -*- encoding: utf-8 -*- -# stub: rake 13.2.1 ruby lib - -Gem::Specification.new do |s| - s.name = "rake".freeze - s.version = "13.2.1" - - s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= - s.metadata = { "bug_tracker_uri" => "https://github.com/ruby/rake/issues", "changelog_uri" => "https://github.com/ruby/rake/blob/v13.2.1/History.rdoc", "documentation_uri" => "https://ruby.github.io/rake", "source_code_uri" => "https://github.com/ruby/rake/tree/v13.2.1" } if s.respond_to? :metadata= - s.require_paths = ["lib".freeze] - s.authors = ["Hiroshi SHIBATA".freeze, "Eric Hodel".freeze, "Jim Weirich".freeze] - s.bindir = "exe".freeze - s.date = "2024-04-05" - s.description = "Rake is a Make-like program implemented in Ruby. Tasks and dependencies are\nspecified in standard Ruby syntax.\nRake has the following features:\n * Rakefiles (rake's version of Makefiles) are completely defined in standard Ruby syntax.\n No XML files to edit. No quirky Makefile syntax to worry about (is that a tab or a space?)\n * Users can specify tasks with prerequisites.\n * Rake supports rule patterns to synthesize implicit tasks.\n * Flexible FileLists that act like arrays but know about manipulating file names and paths.\n * Supports parallel execution of tasks.\n".freeze - s.email = ["hsbt@ruby-lang.org".freeze, "drbrain@segment7.net".freeze, "".freeze] - s.executables = ["rake".freeze] - s.files = ["exe/rake".freeze] - s.homepage = "https://github.com/ruby/rake".freeze - s.licenses = ["MIT".freeze] - s.rdoc_options = ["--main".freeze, "README.rdoc".freeze] - s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze) - s.rubygems_version = "3.0.3.1".freeze - s.summary = "Rake is a Make-like program implemented in Ruby".freeze - - s.installed_by_version = "3.0.3.1" if s.respond_to? :installed_by_version -end