stringprep 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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