java-properties 0.0.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fa01303d1449ae0f74ddd1a56b9da076f232335e
4
- data.tar.gz: 9704efbe011c991ddede20ea11cc5d63da9897d1
2
+ SHA256:
3
+ metadata.gz: 5c361bfd271f8672e0b30fc875cfeb546e4750d76663109821abaa16712b7d4d
4
+ data.tar.gz: fa5a4a45d2f9df8d04cab3a3a64b5a0442a742de890b1dbeb9ec7f7148e32038
5
5
  SHA512:
6
- metadata.gz: c4df80543ad68a53c37dd7cc6aea82b256591c11813e30737a2a65ee340ec1c4eb877436f265466f47f93b1ac68c46a0c7b9fa77529cc061cb4965b5ce38f960
7
- data.tar.gz: ea06f6daad8d178218f6bb227f080263c3b7341b1c2d128993b8b9b5734e00f2e9eee85b87a51f240dbd2f4aa35780f6c2e8add55d004fb1affb5c8e40e4a54a
6
+ metadata.gz: 34950a3536aa41fb22e18a207343bff2a9f159047326f2340e013d86f648e0c9edd0769cb500e2fab13566c95a04cda7015f0a06d14480b2b17abd7a698012d6
7
+ data.tar.gz: a26f13baf630740d763672041c638c3c9af16202a4b9746cfffbb7260d04655f41c3fbec48bb4bff638c5bbf57e3e306b0c0b8427e6787abad824a0507c8650b
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # JavaProperties
2
2
 
3
- [![Build Status](http://img.shields.io/travis/jnbt/java-properties.png)](https://travis-ci.org/jnbt/jnbt/java-properties)
4
- [![Code Climate](http://img.shields.io/codeclimate/github/jnbt/java-properties.png)](https://codeclimate.com/github/jnbt/java-properties)
5
- [![Coveralls](http://img.shields.io/coveralls/jnbt/java-properties.png)](https://coveralls.io/r/jnbt/java-properties)
6
- [![RubyGems](http://img.shields.io/gem/v/java-properties.png)](http://rubygems.org/gems/java-properties)
3
+ [![Build Status](http://img.shields.io/travis/jnbt/java-properties)](https://travis-ci.org/jnbt/java-properties)
4
+ [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/jnbt/java-properties)](https://codeclimate.com/github/jnbt/java-properties)
5
+ [![Coveralls](http://img.shields.io/coveralls/jnbt/java-properties)](https://coveralls.io/r/jnbt/java-properties)
6
+ [![RubyGems](http://img.shields.io/gem/v/java-properties)](http://rubygems.org/gems/java-properties)
7
+ [![Inline docs](http://inch-ci.org/github/jnbt/java-properties.svg?style=shields)](http://inch-ci.org/github/jnbt/java-properties)
7
8
 
8
9
  A ruby library to read and write [Java properties files](http://en.wikipedia.org/wiki/.properties).
9
10
 
@@ -33,7 +34,7 @@ properties[:foo] # => "bar"
33
34
  If have already the content of the properties file at hand than parse the content as:
34
35
 
35
36
  ```ruby
36
- properties = JavaProperties.load("foo=bar")
37
+ properties = JavaProperties.parse("foo=bar")
37
38
  properties[:foo] # => "bar"
38
39
  ```
39
40
 
@@ -59,18 +60,19 @@ As Java properties files normally hold UTF-8 chars in their escaped representati
59
60
 
60
61
  ```
61
62
  "ה" <=> "\u05d4"
63
+ "𪀯" <=> "\ud868\udc2f"
62
64
  ```
63
65
 
64
66
  The tool also escaped every '=', ' ' and ':' in the name part of a property line:
65
67
 
66
68
  ```ruby
67
- JavaProperties.generate({"i : like=strange" => "bar"})
69
+ JavaProperties.generate({"i : like=strange" => "bar"})
68
70
  # => "i\ \:\ like\=strange=bar"
69
71
  ```
70
72
 
71
73
  ## Multi line and line breaks
72
74
 
73
- In Java properties files a string can be multi line but line breaks have to be escaped.
75
+ In Java properties files a string can be multi line but line breaks have to be escaped.
74
76
 
75
77
  Assume the following input:
76
78
 
@@ -1,23 +1,27 @@
1
- # coding: utf-8
2
- # coding: utf-8
3
- lib = File.expand_path('../lib', __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'java-properties/version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/java-properties/version'
6
4
 
7
5
  Gem::Specification.new do |spec|
8
- spec.name = "java-properties"
6
+ spec.name = 'java-properties'
9
7
  spec.version = JavaProperties::VERSION.dup
10
- spec.authors = ["Jonas Thiel"]
11
- spec.email = ["jonas@thiel.io"]
8
+ spec.authors = ['Jonas Thiel']
9
+ spec.email = ['jonas@thiel.io']
12
10
  spec.summary = %q{Loader and writer for *.properties files}
13
11
  spec.description = %q{Tool for loading and writing Java properties files}
14
- spec.homepage = "https://github.com/jnbt/java-properties"
15
- spec.license = "MIT"
12
+ spec.homepage = 'https://github.com/jnbt/java-properties'
13
+ spec.license = 'MIT'
16
14
 
17
15
  spec.files = %w(LICENSE README.md Rakefile java-properties.gemspec)
18
- spec.files += Dir.glob("lib/**/*.rb")
19
- spec.test_files = Dir.glob("spec/**/*.rb")
20
- spec.test_files = Dir.glob("spec/fixtures/**/*.properties")
16
+ spec.files += Dir.glob('lib/**/*.rb')
17
+ spec.test_files = Dir.glob('spec/**/*.rb')
18
+ spec.test_files = Dir.glob('spec/fixtures/**/*.properties')
21
19
 
22
20
  spec.required_rubygems_version = '>= 1.3.5'
23
- end
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+
23
+ spec.add_development_dependency 'rake', '~> 13.0'
24
+ spec.add_development_dependency 'inch', '~> 0.8'
25
+ spec.add_development_dependency 'minitest', '~> 5.14'
26
+ spec.add_development_dependency 'coveralls', '~> 0.8'
27
+ end
@@ -30,7 +30,9 @@ module JavaProperties
30
30
  # @param path [String]
31
31
  # @return [Properties]
32
32
  def self.load(path)
33
- parse(File.read(path))
33
+ File.open(path, "r:bom|utf-8") do |f|
34
+ parse(f.read)
35
+ end
34
36
  end
35
37
 
36
38
  # Generates a Java properties file
@@ -4,6 +4,18 @@ require 'java-properties/encoding/unicode'
4
4
 
5
5
  module JavaProperties
6
6
  # Module to encode and decode
7
+ #
8
+ # Usage:
9
+ # encoded = Encoding.encode!("Some text to be encoded")
10
+ # decoded = Encoding.decode!("Some text to be decoded")
11
+ #
12
+ # You can disable separate encoding (and decoding) steps,
13
+ # by passing in additional flags:
14
+ #
15
+ # * SKIP_SEPARATORS: Do not code the separators (space,:,=)
16
+ # * SKIP_UNICODE: Do not code unicode chars
17
+ # * SKIP_SPECIAL_CHARS: Do not code newlines, tab stops, ...
18
+ #
7
19
  module Encoding
8
20
 
9
21
  # Flag for skipping separators encodings / decoding
@@ -20,8 +32,8 @@ module JavaProperties
20
32
 
21
33
  # Encode a given text in place
22
34
  # @param text [String]
23
- # @param flags [Symbol] Optional flags to skip encoding steps
24
- # @return [String]
35
+ # @param *flags [Array] Optional flags to skip encoding steps
36
+ # @return [String] The encoded text for chaining
25
37
  def self.encode!(text, *flags)
26
38
  SpecialChars.encode!(text) unless flags.include?(SKIP_SPECIAL_CHARS)
27
39
  Separators.encode!(text) unless flags.include?(SKIP_SEPARATORS)
@@ -31,8 +43,8 @@ module JavaProperties
31
43
 
32
44
  # Decodes a given text in place
33
45
  # @param text [String]
34
- # @param flags [Symbol] Optional flags to skip decoding steps
35
- # @return [String]
46
+ # @param *flags [Array] Optional flags to skip decoding steps
47
+ # @return [String] The decoded text for chaining
36
48
  def self.decode!(text, *flags)
37
49
  Unicode.decode!(text) unless flags.include?(SKIP_UNICODE)
38
50
  Separators.decode!(text) unless flags.include?(SKIP_SEPARATORS)
@@ -1,6 +1,7 @@
1
1
  module JavaProperties
2
2
  module Encoding
3
3
  # Module to escape separators as : or =
4
+ # @see JavaProperties::Encoding
4
5
  module Separators
5
6
 
6
7
  # Marker for all separators
@@ -21,7 +22,7 @@ module JavaProperties
21
22
 
22
23
  # Escapes all not already escaped separators
23
24
  # @param text [text]
24
- # @return [String]
25
+ # @return [String] The escaped text for chaining
25
26
  def self.encode!(text)
26
27
  buffer = StringIO.new
27
28
  last_token = ''
@@ -38,7 +39,7 @@ module JavaProperties
38
39
 
39
40
  # Removes escapes from escaped separators
40
41
  # @param text [text]
41
- # @return [String]
42
+ # @return [String] The unescaped text for chaining
42
43
  def self.decode!(text)
43
44
  text.gsub!(DECODE_SEPARATOR_MARKER) do
44
45
  $1
@@ -1,6 +1,7 @@
1
1
  module JavaProperties
2
2
  module Encoding
3
3
  # Module to escape and unescape special chars
4
+ # @see JavaProperties::Encoding
4
5
  module SpecialChars
5
6
 
6
7
  # Lookup table for escaping special chars
@@ -9,7 +10,8 @@ module JavaProperties
9
10
  "\t" => '\\t',
10
11
  "\r" => '\\r',
11
12
  "\n" => '\\n',
12
- "\f" => '\\f'
13
+ "\f" => '\\f',
14
+ "\\" => '\\\\',
13
15
  }.freeze
14
16
 
15
17
  # Lookup table to remove escaping from special chars
@@ -22,7 +24,7 @@ module JavaProperties
22
24
 
23
25
  # Encodes the content a text by escaping all special chars
24
26
  # @param text [String]
25
- # @return [String]
27
+ # @return [String] The escaped text for chaining
26
28
  def self.encode!(text)
27
29
  buffer = StringIO.new
28
30
  text.each_char do |char|
@@ -34,7 +36,7 @@ module JavaProperties
34
36
 
35
37
  # Decodes the content a text by removing all escaping from special chars
36
38
  # @param text [String]
37
- # @return [String]
39
+ # @return [String] The unescaped text for chaining
38
40
  def self.decode!(text)
39
41
  text.gsub!(DESCAPING_MARKER) do |match|
40
42
  DESCAPING.fetch(match, match)
@@ -44,4 +46,4 @@ module JavaProperties
44
46
 
45
47
  end
46
48
  end
47
- end
49
+ end
@@ -1,60 +1,105 @@
1
1
  module JavaProperties
2
2
  module Encoding
3
3
  # Module to encode and decode unicode chars
4
+ # This code is highly influced by Florian Frank's JSON gem
5
+ # @see https://github.com/flori/json/
4
6
  module Unicode
5
-
6
- # Marker for encoded unicode chars
7
- # @return [Regexp]
8
- UNICODE_MARKER = /\\[uU]([0-9a-fA-F]{4,5}|10[0-9a-fA-F]{4})/
9
7
 
10
- # Escape char for unicode chars
11
- # @return [String]
12
- UNICODE_ESCAPE = "\\u"
8
+ # @private
9
+ MAP = {
10
+ "\x0" => '\u0000',
11
+ "\x1" => '\u0001',
12
+ "\x2" => '\u0002',
13
+ "\x3" => '\u0003',
14
+ "\x4" => '\u0004',
15
+ "\x5" => '\u0005',
16
+ "\x6" => '\u0006',
17
+ "\x7" => '\u0007',
18
+ "\xb" => '\u000b',
19
+ "\xe" => '\u000e',
20
+ "\xf" => '\u000f',
21
+ "\x10" => '\u0010',
22
+ "\x11" => '\u0011',
23
+ "\x12" => '\u0012',
24
+ "\x13" => '\u0013',
25
+ "\x14" => '\u0014',
26
+ "\x15" => '\u0015',
27
+ "\x16" => '\u0016',
28
+ "\x17" => '\u0017',
29
+ "\x18" => '\u0018',
30
+ "\x19" => '\u0019',
31
+ "\x1a" => '\u001a',
32
+ "\x1b" => '\u001b',
33
+ "\x1c" => '\u001c',
34
+ "\x1d" => '\u001d',
35
+ "\x1e" => '\u001e',
36
+ "\x1f" => '\u001f',
37
+ }
38
+
39
+ # @private
40
+ EMPTY_8BIT_STRING = ''
41
+ EMPTY_8BIT_STRING.force_encoding(::Encoding::ASCII_8BIT)
13
42
 
14
43
  # Decodes all unicode chars from escape sequences in place
15
44
  # @param text [String]
16
- # @return [String]
45
+ # @return [String] The encoded text for chaining
17
46
  def self.decode!(text)
18
- text.gsub!(UNICODE_MARKER) do
19
- unicode($1.hex)
47
+ string = text.dup
48
+ string = string.gsub(%r((?:\\[uU](?:[A-Fa-f\d]{4}))+)) do |c|
49
+ c.downcase!
50
+ bytes = EMPTY_8BIT_STRING.dup
51
+ i = 0
52
+ while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
53
+ bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
54
+ i += 1
55
+ end
56
+ bytes.encode("utf-8", "utf-16be")
20
57
  end
58
+ string.force_encoding(::Encoding::UTF_8)
59
+
60
+ text.replace string
21
61
  text
22
62
  end
23
63
 
24
64
  # Decodes all unicode chars into escape sequences in place
25
65
  # @param text [String]
26
- # @return [String]
66
+ # @return [String] The decoded text for chaining
27
67
  def self.encode!(text)
28
- buffer = StringIO.new
29
- text.each_char do |char|
30
- if char.ascii_only?
31
- buffer << char
32
- else
33
- buffer << UNICODE_ESCAPE
34
- buffer << hex(char.codepoints.first)
35
- end
36
- end
37
- text.replace buffer.string
68
+ string = text.dup
69
+ string.force_encoding(::Encoding::ASCII_8BIT)
70
+ string.gsub!(/["\\\x0-\x1f]/n) { |c| MAP[c] || c }
71
+ string.gsub!(/(
72
+ (?:
73
+ [\xc2-\xdf][\x80-\xbf] |
74
+ [\xe0-\xef][\x80-\xbf]{2} |
75
+ [\xf0-\xf4][\x80-\xbf]{3}
76
+ )+ |
77
+ [\x80-\xc1\xf5-\xff] # invalid
78
+ )/nx) { |c|
79
+ c.size == 1 and raise "Invalid utf8 byte: '#{c}'"
80
+ s = c.encode("utf-16be", "utf-8").unpack('H*')[0]
81
+ s.force_encoding(::Encoding::ASCII_8BIT)
82
+ s.gsub!(/.{4}/n, '\\\\u\&')
83
+ s.force_encoding(::Encoding::UTF_8)
84
+ }
85
+ string.force_encoding(::Encoding::UTF_8)
86
+ text.replace string
38
87
  text
39
88
  end
40
89
 
41
90
  private
42
91
 
43
92
  def self.unicode(code)
44
- [code].pack("U")
93
+ code.chr(::Encoding::UTF_8)
45
94
  end
46
95
 
47
96
  def self.hex(codepoint)
48
97
  hex = codepoint.to_s(16)
49
- size = hex.size
50
- # padding the hex value for uneven digest
51
- if (size % 2) == 1
52
- "0#{hex}"
53
- else
54
- hex
55
- end
98
+ size = [4, hex.size].max
99
+ target_size = size.even? ? size : size+1
100
+ hex.rjust(target_size, '0')
56
101
  end
57
102
 
58
103
  end
59
104
  end
60
- end
105
+ end
@@ -2,6 +2,6 @@ module JavaProperties
2
2
 
3
3
  # Current version
4
4
  # @return [String]
5
- VERSION = "0.0.2".freeze
5
+ VERSION = "0.3.0".freeze
6
6
 
7
- end
7
+ end
@@ -0,0 +1,2 @@
1
+ pageTitle=Some ü text
2
+ tagOther=Other
@@ -1,16 +1,16 @@
1
1
  # Comment 1
2
2
  ! Comment 2
3
3
  item0
4
- item1 = item1
5
- item2 : item2
4
+ item1 = item1
5
+ item2 : item2
6
6
  item3 item3
7
7
 
8
8
  #Comment 3
9
9
  ! Comment 4
10
-
10
+
11
11
  it\ em4=item4
12
- it\=em5:item5
13
- item6 item6
12
+ it\=em5:item5
13
+ item6 item6
14
14
 
15
15
  !Comment 4
16
16
  # Comment 5
@@ -31,3 +31,8 @@ item10=test\n\ttest\u0050 \
31
31
  test\n\ttest \
32
32
  test\n\ttest = test
33
33
 
34
+ item11=a\u00e4b \ud868\udc2f
35
+
36
+ item12=#no comment
37
+
38
+ item13=with\\back\\nslash\\t
@@ -8,4 +8,7 @@ item6=item6
8
8
  item7=line 1 line 2 line 3
9
9
  item8=line 1 line 2 line 3
10
10
  item9=line 1 line 2 line 3
11
- item10=test\n\ttest\u0050 test\n\ttest test\n\ttest = test
11
+ item10=test\n\ttest\u0050 test\n\ttest test\n\ttest = test
12
+ item11=a\u00e4b \ud868\udc2f
13
+ item12=#no comment
14
+ item13=with\\back\\nslash\\t
@@ -8,4 +8,5 @@ it\:em6=item6
8
8
  item7=line 1 line 2 line 3
9
9
  item8=line 1 line 2 line 3
10
10
  item9=line 1 line 2 line 3
11
- item10=test\n\ttest\u05d4 test\n\ttest test\n\ttest = test
11
+ item10=test\n\ttest\u05d4 test\n\ttest test\n\ttest\u00fc = test
12
+ item11=a\u00e4b \ud868\udc2f
@@ -8,4 +8,5 @@ it:em6=item6
8
8
  item7=line 1 line 2 line 3
9
9
  item8=line 1 line 2 line 3
10
10
  item9=line 1 line 2 line 3
11
- item10=test\n\ttest\u05d4 test\n\ttest test\n\ttest = test
11
+ item10=test\n\ttest\u05d4 test\n\ttest test\n\ttest\u00fc = test
12
+ item11=a\u00e4b \ud868\udc2f
@@ -11,4 +11,5 @@ item9=line 1 line 2 line 3
11
11
  item10=test
12
12
  test\u05d4 test
13
13
  test test
14
- test = test
14
+ test\u00fc = test
15
+ item11=a\u00e4b \ud868\udc2f
@@ -8,4 +8,5 @@ it\:em6=item6
8
8
  item7=line 1 line 2 line 3
9
9
  item8=line 1 line 2 line 3
10
10
  item9=line 1 line 2 line 3
11
- item10=test\n\ttestה test\n\ttest test\n\ttest = test
11
+ item10=test\n\ttestה test\n\ttest test\n\ttestü = test
12
+ item11=aäb 𪀯
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: java-properties
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Thiel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-17 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-02-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: inch
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: coveralls
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
13
69
  description: Tool for loading and writing Java properties files
14
70
  email:
15
71
  - jonas@thiel.io
@@ -33,6 +89,7 @@ files:
33
89
  - lib/java-properties/parsing/parser.rb
34
90
  - lib/java-properties/properties.rb
35
91
  - lib/java-properties/version.rb
92
+ - spec/fixtures/bom.properties
36
93
  - spec/fixtures/test.properties
37
94
  - spec/fixtures/test_normalized.properties
38
95
  - spec/fixtures/test_out.properties
@@ -43,31 +100,30 @@ homepage: https://github.com/jnbt/java-properties
43
100
  licenses:
44
101
  - MIT
45
102
  metadata: {}
46
- post_install_message:
103
+ post_install_message:
47
104
  rdoc_options: []
48
105
  require_paths:
49
106
  - lib
50
107
  required_ruby_version: !ruby/object:Gem::Requirement
51
108
  requirements:
52
- - - '>='
109
+ - - ">="
53
110
  - !ruby/object:Gem::Version
54
- version: '0'
111
+ version: 2.0.0
55
112
  required_rubygems_version: !ruby/object:Gem::Requirement
56
113
  requirements:
57
- - - '>='
114
+ - - ">="
58
115
  - !ruby/object:Gem::Version
59
116
  version: 1.3.5
60
117
  requirements: []
61
- rubyforge_project:
62
- rubygems_version: 2.2.1
63
- signing_key:
118
+ rubygems_version: 3.2.3
119
+ signing_key:
64
120
  specification_version: 4
65
121
  summary: Loader and writer for *.properties files
66
122
  test_files:
123
+ - spec/fixtures/bom.properties
67
124
  - spec/fixtures/test.properties
68
125
  - spec/fixtures/test_normalized.properties
69
126
  - spec/fixtures/test_out.properties
70
127
  - spec/fixtures/test_out_skip_separators.properties
71
128
  - spec/fixtures/test_out_skip_special_chars.properties
72
129
  - spec/fixtures/test_out_skip_unicode.properties
73
- has_rdoc: