stringprep 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 53c5549dcea0b8123d552f5560d3f73d0fb9ae3b
4
+ data.tar.gz: e46aac94f3974548ecbc06b7a4cc08b7367292e5
5
+ SHA512:
6
+ metadata.gz: 0362f7124c807224bd07d0a39d7b9aefdddecc8e5eb8fed54871059308ff445b58f3cd7f7829543ce6d1f79f587addc05a8d88437b967abf5e3cdd98c6439d03
7
+ data.tar.gz: 9f7ab163f277f67c1b92952c4a554ba7580043f6ae5cfbad1eec89b0f5aa0cbdfd772e0559884b8e6d8af1a72d2f041b9868b141cddd77ff03b619d281e82863
checksums.yaml.gz.sig ADDED
Binary file
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ [![Build Status](https://travis-ci.org/steakknife/stringprep.svg)](https://travis-ci.org/steakknife/stringprep)
2
+
3
+ # Stringprep
4
+
5
+ Pure Ruby implementation
6
+
7
+ ## Usage
8
+
9
+ ```ruby
10
+ require 'stringprep'
11
+
12
+ # code can be a 1 character string OR an Integer,
13
+ # and it will return the same type that was passed
14
+
15
+ Stringprep.in_a1 "\u1234" # code in Table A.1 ?
16
+ # => false
17
+ # or
18
+ Stringprep.in_a1 0x1234
19
+ # => false
20
+
21
+ Stringprep.in_c11 "\u1234" # code in Table C.1.1 ?
22
+ # => false
23
+
24
+ Stringprep.in_c21_c22 "\u1234" # code in Table C.2.1 or C.2.2 ?
25
+ # => false
26
+
27
+ Stringprep.map_b2 "\u1234" # map Table B.2
28
+ # => "ሴ"
29
+ ```
30
+
31
+ ## Installation
32
+
33
+ ### Signed gem
34
+
35
+ [sudo] gem cert --add <(curl -L https://raw.githubusercontent.com/steakknife/stringprep/master/gem-public_cert.pem) # adds my cert (do once)
36
+ [sudo] gem install stringprep -P HighSecurity
37
+
38
+ ### Bundler
39
+
40
+ gem 'stringprep'
41
+
42
+ ## Contributors
43
+
44
+ ! Your Name Here ! (in neon lights, top of the bill even)
45
+
46
+ ## Author
47
+
48
+ Barry Allard
49
+
50
+ ## License
51
+
52
+ MIT
53
+
54
+ ## References
55
+
56
+ - Stringprep [rfc3494](http://tools.ietf.org/html/rfc3494)
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ fail 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+ fail 'Gemfile missing' unless defined? Bundler::GemHelper
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'Stringprep'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.rdoc')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ desc 'Run RSpec specs'
20
+ task :spec do
21
+ ARGV.delete 'spec'
22
+ sh "bundle exec rspec #{ARGV.join ' '}"
23
+ end
24
+
25
+ task default: :spec
@@ -0,0 +1,62 @@
1
+ autoload :FileUtils, 'fileutils'
2
+ autoload :JSON, 'json'
3
+
4
+ module Stringprep
5
+ module Rfc3454
6
+
7
+ # Loads code point tables from data/rfc3454.json, creates it if it does not exist
8
+ def self.tables
9
+ tries = READ_RETRIES
10
+ @tables ||= begin
11
+ raw_read_tables
12
+ rescue Errno::ENOENT
13
+ write_tables(parse_rfc_txt)
14
+ retry if (tries -= 1) > 0
15
+ raise
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ TABLES_DATA_DIR = 'data'
22
+ RFC_DIR = 'data'
23
+ TABLES_FILE = File.join(TABLES_DATA_DIR, 'rfc3454.json')
24
+ RFC_FILE = File.join(TABLES_DATA_DIR, 'rfc3454.txt')
25
+
26
+
27
+ START_TABLE = /^[[:space:]]*----- Start Table ([^-]*) -----[[:space:]]*$/
28
+ END_TABLE = /^[[:space:]]*----- End Table ([^-]*) -----[[:space:]]*$/
29
+ DATA_LINE = /[[:xdigit:]]{2}/
30
+ SKIP_LINE = /Standards Track|RFC /
31
+ READ_RETRIES = 4
32
+
33
+ def self.raw_read_tables
34
+ JSON.parse(File.read(TABLES_FILE))
35
+ end
36
+
37
+ def self.parse_rfc_txt
38
+ tables = {}
39
+ table_name = nil
40
+ started = false
41
+ File.readlines(RFC_FILE).each do |line|
42
+ if line =~ START_TABLE
43
+ started = true
44
+ table_name = $1.gsub('.', '').downcase
45
+ tables[table_name] = []
46
+ elsif line =~ END_TABLE
47
+ started = false
48
+ elsif started && line =~ DATA_LINE && line !~ SKIP_LINE
49
+ tables[table_name] << line.strip
50
+ end
51
+ end
52
+ tables
53
+ end
54
+
55
+ def self.write_tables(tables)
56
+ FileUtils.mkdir_p TABLES_DATA_DIR
57
+ File.open(TABLES_FILE, 'w') { |f|
58
+ f.write(JSON.generate(tables))
59
+ }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ module Stringprep
2
+ module Table
3
+ class Base
4
+ private_class_method :new
5
+ def self.create_read_only(*args, &block)
6
+ x = new(*args, &block)
7
+ x.freeze
8
+ x
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'stringprep/table/base'
2
+
3
+ module Stringprep
4
+ module Table
5
+ class In < Base
6
+ def initialize(data)
7
+ @code_list = In.parse(data)
8
+ end
9
+
10
+ def include?(code)
11
+ if code.is_a?(String)
12
+ unpacked = code.unpack('U*')
13
+ raise ArgumentError, 'Only one character is allowed' unless unpacked.length == 1
14
+ code = unpacked[0]
15
+ end
16
+ return unless code.class < Integer
17
+ @code_list.any? { |x| (x.is_a?(Range)) ? x.include?(code) : x == code }
18
+ end
19
+
20
+ private
21
+
22
+ # returns an Array
23
+ def self.parse(data)
24
+ data.map { |line|
25
+ if line =~ /([[:xdigit:]]+)-([[:xdigit:]]+)/
26
+ $1.to_i(16) .. $2.to_i(16)
27
+ elsif line =~ /([[:xdigit:]]+)/
28
+ $1.to_i(16)
29
+ else
30
+ raise "Parse error '#{data}'"
31
+ end
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ require 'stringprep/table/base'
2
+
3
+ module Stringprep
4
+ module Table
5
+ class Map < Base
6
+ def initialize(data)
7
+ @codes = Map.parse(data)
8
+ end
9
+
10
+ def map(code)
11
+ if string_char = ((code.is_a?(String)) && (code.length == 1))
12
+ code = code.unpack('U')[0]
13
+ end
14
+ return unless code.class < Integer
15
+ new_code = @codes[code] || code
16
+ if string_char
17
+ if new_code.is_a?(Array)
18
+ new_code = new_code.pack('U*')
19
+ else
20
+ new_code = [new_code].pack('U') if !new_code.nil?
21
+ end
22
+ end
23
+ new_code
24
+ end
25
+
26
+ private
27
+ def self.parse(data)
28
+ Hash[ data.map { |line|
29
+ parse_line(line).tap { |x|
30
+ raise "Parse error '#{line}'" if x.nil?
31
+ }
32
+ }]
33
+ end
34
+
35
+ def self.parse_line(line)
36
+ parse_map_to_nothing(line) || parse_case_map(line)
37
+ end
38
+
39
+ def self.parse_map_to_nothing(line)
40
+ if line =~ /([[:xdigit:]]+);[[:space:]]*;[[:space:]]*/
41
+ [ $1.to_i(16), nil ]
42
+ end
43
+ end
44
+
45
+ def self.parse_case_map(line)
46
+ if r = line.match(/([[:xdigit:]]+);(?:[[:space:]]*([[:xdigit:]]+))+;[[:space:]]*/)
47
+ [ r[1].to_i(16), r[2..-1].map { |x| x.to_i(16) } ]
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,3 @@
1
+ module Stringprep
2
+ VERSION = '0.0.1'
3
+ end
data/lib/stringprep.rb ADDED
@@ -0,0 +1,124 @@
1
+ module Stringprep
2
+ extend self
3
+
4
+ # Determine whether code is in tableA.1 (Unassigned code points in Unicode 3.2).
5
+ def in_a1(code)
6
+ @a1 ||= Table::In.create_read_only(Rfc3454.tables['a1'])
7
+ @a1.include?(code)
8
+ end
9
+
10
+ # Determine whether code is in tableB.1 (Commonly mapped to nothing).
11
+ def in_b1(code)
12
+ @b1 ||= Table::In.create_read_only(Rfc3454.tables['b1'])
13
+ @b1.include?(code)
14
+ end
15
+
16
+ # Return the mapped value for code according to tableB.2 (Mapping for case-folding used with NFKC).
17
+ def map_b2(code)
18
+ @b2 ||= Table::Map.create_read_only(Rfc3454.tables['b2'])
19
+ @b2.map(code)
20
+ end
21
+
22
+ # Return the mapped value for code according to tableB.3 (Mapping for case-folding used with no normalization).
23
+ def map_b3(code)
24
+ @b3 ||= Table::Map.create_read_only(Rfc3454.tables['b3'])
25
+ @b3.map(code)
26
+ end
27
+
28
+ # Determine whether code is in tableC.1.1 (ASCII space characters).
29
+ def in_c11(code)
30
+ @c11 ||= Table::In.create_read_only(Rfc3454.tables['c11'])
31
+ @c11.include? code
32
+ end
33
+
34
+ # Determine whether code is in tableC.1.2 (Non-ASCII space characters).
35
+ def in_c12(code)
36
+ @c12 ||= Table::In.create_read_only(Rfc3454.tables['c12'])
37
+ @c12.include? code
38
+ end
39
+
40
+ # Determine whether code is in tableC.1 (Space characters, union of C.1.1 and C.1.2).
41
+ def in_c11_c12(code)
42
+ in_c11(code) || in_c12(code)
43
+ end
44
+
45
+ # Determine whether code is in tableC.2.1 (ASCII control characters).
46
+ def in_c21(code)
47
+ @c21 ||= Table::In.create_read_only(Rfc3454.tables['c21'])
48
+ @c21.include? code
49
+ end
50
+
51
+ # Determine whether code is in tableC.2.2 (Non-ASCII control characters).
52
+ def in_c22(code)
53
+ @c22 ||= Table::In.create_read_only(Rfc3454.tables['c22'])
54
+ @c22.include? code
55
+ end
56
+
57
+ # Determine whether code is in tableC.2 (Control characters, union of C.2.1 and C.2.2).
58
+ def in_c21_c22(code)
59
+ in_c21(code) || in_c22(code)
60
+ end
61
+
62
+ # Determine whether code is in tableC.3 (Private use).
63
+ def in_c3(code)
64
+ @c3 ||= Table::In.create_read_only(Rfc3454.tables['c3'])
65
+ @c3.include?(code)
66
+ end
67
+
68
+ # Determine whether code is in tableC.4 (Non-character code points).
69
+ def in_c4(code)
70
+ @c4 ||= Table::In.create_read_only(Rfc3454.tables['c4'])
71
+ @c4.include?(code)
72
+ end
73
+
74
+ # Determine whether code is in tableC.5 (Surrogate codes).
75
+ def in_c5(code)
76
+ @c5 ||= Table::In.create_read_only(Rfc3454.tables['c5'])
77
+ @c5.include?(code)
78
+ end
79
+
80
+ # Determine whether code is in tableC.6 (Inappropriate for plain text).
81
+ def in_c6(code)
82
+ @c6 ||= Table::In.create_read_only(Rfc3454.tables['c6'])
83
+ @c6.include?(code)
84
+ end
85
+
86
+ # Determine whether code is in tableC.7 (Inappropriate for canonical representation).
87
+ def in_c7(code)
88
+ @c7 ||= Table::In.create_read_only(Rfc3454.tables['c7'])
89
+ @c7.include?(code)
90
+ end
91
+
92
+ # Determine whether code is in tableC.8 (Change display properties or are deprecated).
93
+ def in_c8(code)
94
+ @c8 ||= Table::In.create_read_only(Rfc3454.tables['c8'])
95
+ @c8.include?(code)
96
+ end
97
+
98
+ # Determine whether code is in tableC.9 (Tagging characters).
99
+ def in_c9(code)
100
+ @c9 ||= Table::In.create_read_only(Rfc3454.tables['c9'])
101
+ @c9.include?(code)
102
+ end
103
+
104
+ # Determine whether code is in tableD.1 (Characters with bidirectional property “R” or “AL”).
105
+ def in_d1(code)
106
+ @d1 ||= Table::In.create_read_only(Rfc3454.tables['d1'])
107
+ @d1.include?(code)
108
+ end
109
+
110
+ # Determine whether code is in tableD.2 (Characters with bidirectional property “L”).
111
+ def in_d2(code)
112
+ @d2 ||= Table::In.create_read_only(Rfc3454.tables['d2'])
113
+ @d2.include?(code)
114
+ end
115
+
116
+ private
117
+
118
+ autoload :Rfc3454, 'stringprep/rfc3454'
119
+
120
+ module Table
121
+ autoload :In, 'stringprep/table/in'
122
+ autoload :Map, 'stringprep/table/map'
123
+ end
124
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
@@ -0,0 +1,96 @@
1
+ require 'stringprep'
2
+
3
+ # thank you Python for your test cases ;)
4
+ # adapted from test_stringprep.py
5
+
6
+ describe Stringprep do
7
+ describe '.in_a1' do
8
+ it { expect(Stringprep::in_a1("\u0221")).to be_true }
9
+ it { expect(Stringprep::in_a1("\u0222")).to be_false }
10
+ end
11
+
12
+ describe '.in_b1' do
13
+ it { expect(Stringprep::in_b1("\u00ad")).to be_true }
14
+ it { expect(Stringprep::in_b1("\u00ae")).to be_false }
15
+ end
16
+
17
+ describe '.map_b3' do
18
+ it { expect(Stringprep::map_b2("\u0041")).to eq("\u0061") }
19
+ it { expect(Stringprep::map_b2("\u0061")).to eq("\u0061") }
20
+ end
21
+
22
+ describe '.in_c11' do
23
+ it { expect(Stringprep::in_c11("\u0020")).to be_true }
24
+ it { expect(Stringprep::in_c11("\u0021")).to be_false }
25
+ end
26
+
27
+ describe '.in_c12' do
28
+ it { expect(Stringprep::in_c12("\u00a0")).to be_true }
29
+ it { expect(Stringprep::in_c12("\u00a1")).to be_false }
30
+ end
31
+
32
+ describe '.in_c11_c12' do
33
+ it { expect(Stringprep::in_c11_c12("\u00a0")).to be_true }
34
+ it { expect(Stringprep::in_c11_c12("\u00a1")).to be_false }
35
+ end
36
+
37
+ describe '.in_c21' do
38
+ it { expect(Stringprep::in_c21("\u001f")).to be_true }
39
+ it { expect(Stringprep::in_c21("\u0020")).to be_false }
40
+ end
41
+
42
+ describe '.in_c22' do
43
+ it { expect(Stringprep::in_c22("\u009f")).to be_true }
44
+ it { expect(Stringprep::in_c22("\u00a0")).to be_false }
45
+ end
46
+
47
+ describe '.in_c21_c22' do
48
+ it { expect(Stringprep::in_c21_c22("\u009f")).to be_true }
49
+ it { expect(Stringprep::in_c21_c22("\u00a0")).to be_false }
50
+ end
51
+
52
+ describe '.in_c3' do
53
+ it { expect(Stringprep::in_c3("\ue000")).to be_true }
54
+ it { expect(Stringprep::in_c3("\uf900")).to be_false }
55
+ end
56
+
57
+ describe '.in_c4' do
58
+ it { expect(Stringprep::in_c4("\uffff")).to be_true }
59
+ it { expect(Stringprep::in_c4("\u0000")).to be_false }
60
+ end
61
+
62
+ describe '.in_c5' do
63
+ it { expect(Stringprep::in_c5("\ud800")).to be_true }
64
+ it { expect(Stringprep::in_c5("\ud7ff")).to be_false }
65
+ end
66
+
67
+ describe '.in_c6' do
68
+ it { expect(Stringprep::in_c6("\ufff9")).to be_true }
69
+ it { expect(Stringprep::in_c6("\ufffe")).to be_false }
70
+ end
71
+
72
+ describe '.in_c7' do
73
+ it { expect(Stringprep::in_c7("\u2ff0")).to be_true }
74
+ it { expect(Stringprep::in_c7("\u2ffc")).to be_false }
75
+ end
76
+
77
+ describe '.in_c8' do
78
+ it { expect(Stringprep::in_c8("\u0340")).to be_true }
79
+ it { expect(Stringprep::in_c8("\u0342")).to be_false }
80
+ end
81
+
82
+ describe '.in_c9' do
83
+ it { expect(Stringprep::in_c9("\u{e0001}")).to be_true }
84
+ it { expect(Stringprep::in_c9("\u{e0002}")).to be_false }
85
+ end
86
+
87
+ describe '.in_d1' do
88
+ it { expect(Stringprep::in_d1("\u05be")).to be_true }
89
+ it { expect(Stringprep::in_d1("\u05bf")).to be_false }
90
+ end
91
+
92
+ describe '.in_d2' do
93
+ it { expect(Stringprep::in_d2("\u0041")).to be_true }
94
+ it { expect(Stringprep::in_d2("\u0040")).to be_false }
95
+ end
96
+ end
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ }�C� ���=�<J��4� ǟ��<�����i��:$��zf��3QJ>�h�J����3V���`��;2M/��1�#������~@8�(@9����0@q �׵��pR���:��5%��� &#���$�z��"~W��������ˑy�L�/�� a���
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stringprep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Barry Allard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDOjCCAiKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBDMRUwEwYDVQQDDAxiYXJy
14
+ eS5hbGxhcmQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
15
+ A2NvbTAeFw0xMzA0MDgwMTI0NThaFw0xNDA0MDgwMTI0NThaMEMxFTATBgNVBAMM
16
+ DGJhcnJ5LmFsbGFyZDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
17
+ LGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDcmlxJH
18
+ eySiUBcYTqGXaWETRVYmgfGwWRPZzqkmBdIVZkbk9SWxseiHWIReFWjP438UoUTs
19
+ J17G/HuQb0SmjPCMZy8967Fb2wqs+QRbcmpnmtYA1vilgC2CIzntFOFLSA2KpfZH
20
+ dJSsg6aaXqwS4/KJxK6ooDsp+iR6zGTINwkdUt4ktpqgCHz1VYuzvii2slnazbm4
21
+ cQUi/wWIynHyzzdrPvDhGgaZm161MYHidCtV+wzqwjeVeFsyQwCFVEkrD/0G98ho
22
+ Gti8vB6Xj6VjO3n+kh/KlYZgmM7SWauLpo+2RGlIYVYdpQQWGwhMEmvSgBxjfX4c
23
+ unDFxO1ZAQIRBQIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS+Kk7ypi9u
24
+ kFUcaqJlpaKO7eWiUTALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBALie
25
+ YCNeW9EIQ/j8+2emMm0484JVtycOqPyIu5UALtsU42En392HVOZ6oEA/rh2KFRvq
26
+ dcDwcJPI/u7PzWp9TNp81PTShtHMtSs7Wv1UsC04vQ9b6XBEomWbbzoxxgzyjP7l
27
+ ZV4L5HzmX0nDOSEFJyYkqbwgYjIoldg2TMlw2BeoVqGm7Gx1ljXKb2Kg5iasyDpI
28
+ C/gAiGBIAX7FxyIXmjZq38xWBOxyGF3NFL/W6z+vhJg81HGdNBCpIdwrQ/eXOjba
29
+ VqwwfY+Ms3gcCHSERG1X4AFW1zesX+UWcTCwVLtAsuRWQhC8odDSVDWzUfkZmOQt
30
+ ViIxU1ZphInql7L5g34=
31
+ -----END CERTIFICATE-----
32
+ date: 2014-04-05 00:00:00.000000000 Z
33
+ dependencies:
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2'
62
+ - !ruby/object:Gem::Dependency
63
+ name: should_not
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ description: Pure Ruby Stringprep implementation (RFC 3494)
77
+ email:
78
+ - barry.allard@gmail.com
79
+ executables: []
80
+ extensions: []
81
+ extra_rdoc_files: []
82
+ files:
83
+ - ".rspec"
84
+ - README.md
85
+ - Rakefile
86
+ - lib/stringprep.rb
87
+ - lib/stringprep/rfc3454.rb
88
+ - lib/stringprep/table/base.rb
89
+ - lib/stringprep/table/in.rb
90
+ - lib/stringprep/table/map.rb
91
+ - lib/stringprep/version.rb
92
+ - spec/spec_helper.rb
93
+ - spec/stringprep_spec.rb
94
+ homepage: https://github.com/steakknife/stringprep
95
+ licenses:
96
+ - MIT
97
+ metadata:
98
+ source_code_uri: https://github.com/steakknife/stringprep.git
99
+ project_uri: https://github.com/steakknife/stringprep
100
+ bug_tracker_uri: https://github.com/steakknife/stringprep/issues
101
+ wiki_uri: https://github.com/steakknife/stringprep/wiki
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Stringprep
122
+ test_files:
123
+ - spec/spec_helper.rb
124
+ - spec/stringprep_spec.rb
125
+ - ".rspec"
126
+ has_rdoc:
metadata.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ n��
2
+ �\�,�,}���x��G�,yb|��Fl mנ��.�䱓�;��Z� 6I!��qn��7~�J�������.ŴcD\��j�sB���\��������s�`�x�eƻ��pg��M���r�� �8���.��b�DW�t���C���V�#�I�"2��*J�9H���W�g� ��^t�R�Ӕ��nj���tF���,0I�wf�bqNq
3
+ bM<��Lغ7�>ˈ��:~����h*6��]/!�-�@�l