property-list 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa876b36addfa71b3f6ae9e2cbda72bf85644cad
4
- data.tar.gz: 4a9757255bc2bf508d8db8a3a0aae5b6a2c7c59c
3
+ metadata.gz: 6a77c93353f4ae1b3e24f38e0976a133a68251ec
4
+ data.tar.gz: 2c68650d8755fc85dd1752951e930f153624a372
5
5
  SHA512:
6
- metadata.gz: a54bf12b89e339523d7a29de13096d32ddb4e7c99ab6a6ff5f09cb09b480848883b2379826b6759472b8c1b8447b5b88b6f615dca6ada8fe1bce37dcabad543a
7
- data.tar.gz: 3d9320c8aee3e89789ccc5d3212a70f1fcc119a5b9ca34412a2622a91ac15471e6e951d5c0b4b104c69c6a48292a7ec992e887b7892767a30472d1760ac72b32
6
+ metadata.gz: 786bb0eaba6ebf83dee461f951ce9966b51c649e945fd1a06ebb3d6a7176ebd886abb6c773172ae85455a310a23a9b93ed00b567b18d58b5bc74cc4696985e4d
7
+ data.tar.gz: 4c64f96962192fa6cea63ceb476baaa9129996ec33f322465134b169b19b270ff136836419ca18ddd96fe5a804a35948fa89bdb6c0f8dc89dc4cc8fee4f10ed4
data/.rdoc_options ADDED
@@ -0,0 +1,23 @@
1
+ --- !ruby/object:RDoc::Options
2
+ encoding: UTF-8
3
+ static_path: []
4
+ rdoc_include:
5
+ - "."
6
+ charset: UTF-8
7
+ exclude:
8
+ - "test"
9
+ hyperlink_all: false
10
+ line_numbers: false
11
+ locale:
12
+ locale_dir: locale
13
+ locale_name:
14
+ main_page:
15
+ markup: markdown
16
+ output_decoration: true
17
+ page_dir:
18
+ show_hash: false
19
+ tab_width: 8
20
+ template_stylesheets: []
21
+ title:
22
+ visibility: :protected
23
+ webcvs:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- This is a full-featured property list library which supports XML/Binary/ASCII format plists, and performance is tuned for large property list files.
2
-
3
- The code is as clean and complete as possible. There is no runtime dependency to any other gems or libplist or other libraries.
1
+ Fully featured propertylist library.
2
+ Can load and dump XML/ASCII/Binary plists and offer fine-grained formatting options.
3
+ Cross platform, clean code, performance tuned, no dependency.
4
4
 
5
5
  ## Install
6
6
 
@@ -25,20 +25,22 @@ Generate a plist file data
25
25
 
26
26
  XML formatting options for `PropertyList.dump_xml object, options`
27
27
 
28
- - `segment:` whether wrap the xml output is a segment or wrapped with `<?xml>` and `<plist>` tags. default is `false`.
28
+ - `segment:` whether output an XML segment (not wrapped with `<?xml>`, `<DOCTYPE>`, `<plist>` tags), default is `false`.
29
29
  - `xml_version:` you can also specify `"1.1"` for https://www.w3.org/TR/xml11/, default is `"1.0"`, no effect if `:segment` is set to `true`.
30
- - `indent_unit:` the indent unit, default value is `"\t"`, set to `nil` or `''` if you don't need indent.
30
+ - `gnu_dtd:` use GNUStep DTD instead (which is a bit different in string escaping), default is `false`.
31
+ - `indent_unit:` the indent unit, default value is `"\t"`, set to or `''` if you don't need indent.
31
32
  - `initial_indent:` initial indent space, default is `''`, the indentation per line equals to `initial_indent + indent * current_indent_level`.
32
33
  - `base64_width:` the width of characters per line when serializing data with Base64, default value is `68`, must be multiple of `4`.
33
34
  - `base64_indent:` whether indent the Base64 encoded data, you can use `false` for compatibility to generate same output for other frameworks, default value is `true`.
34
35
 
35
36
  ASCII formatting options for `PropertyList.dump_ascii object, options`
36
37
 
37
- - `indent_unit:` the indent unit, default value is `"\t"`, set to `''` if you don't need indent
38
- - `initial_indent:` initial indent space, default is `''`, the indentation per line equals to `initial_indent + indent * current_indent_level`
38
+ - `indent_unit:` the indent unit, default value is `"\t"`, set to `''` if you don't need indent.
39
+ - `initial_indent:` initial indent space, default is `''`, the indentation per line equals to `initial_indent + indent * current_indent_level`.
39
40
  - `wrap:` wrap the top level output with `{...}` when obj is a Hash, default is `true`.
40
- - `encoding_comment:` add encoding comment `// !$*UTF8*$!` on top of file, default is `false`
41
- - `sort_keys:` sort dict keys, default is `true`
41
+ - `encoding_comment:` add encoding comment `// !$*UTF8*$!` on top of file, default is `false`.
42
+ - `sort_keys:` sort dict keys, default is `true`.
43
+ - `gnu_extension` whether allow GNUStep extensions for ASCII plist to support serializing more types, default is `true`.
42
44
 
43
45
  ## Data type mapping
44
46
 
@@ -51,7 +53,10 @@ Data type mapping in `PropertyList.load`:
51
53
  date: DateTime
52
54
  true: true
53
55
  false: false
54
- uid: PropertyList::Uid # obj.uid is the integer index
56
+ uid: PropertyList::UID # only in binary plist, obj.uid is the integer index
57
+ array: Array
58
+ dict: Hash
59
+ set: Set # only in binary plist
55
60
 
56
61
  Reverse mapping in `PropertyList.dump_*`:
57
62
 
@@ -62,7 +67,12 @@ Reverse mapping in `PropertyList.dump_*`:
62
67
  Time, DateTime, Date: date
63
68
  true: true
64
69
  false: false
65
- PropertyList::Uid: uid
70
+ PropertyList::Uid: uid # only in binary plist
71
+ Dict: dict
72
+ Array: array
73
+ Set: set # only in binary plist
74
+
75
+ Type mappings in ASCII plist depends on the DTD.
66
76
 
67
77
  ## Credits
68
78
 
data/lib/property-list.rb CHANGED
@@ -14,22 +14,17 @@ require_relative 'property-list/binary_generator'
14
14
  require_relative 'property-list/binary_parser'
15
15
  require_relative 'property-list/version'
16
16
 
17
- # === Load a plist file
18
- #
19
- # PropertyList.load_xml File.read "some_plist.xml"
20
- # PropertyList.load_binary File.binread "some_binary.plist"
21
- # PropertyList.load_ascii File.read "some_ascii.strings"
22
- # PropertyList.load File.binread "unknown_format.plist"
23
- #
24
- # === Generate a plist file data
25
- #
26
- # PropertyList.dump_xml obj
27
- # PropertyList.dump_binary obj
28
- # PropertyList.dump_ascii obj
29
- #
30
17
  module PropertyList
31
- # load plist (binary or xml or ascii) into a ruby object
32
- # auto detect the format
18
+ # Load plist from file
19
+ #
20
+ # Auto detects format
21
+ def self.load_file file_name
22
+ load File.binread file_name
23
+ end
24
+
25
+ # Load plist (binary or xml or ascii) into a ruby object.
26
+ #
27
+ # Auto detects format.
33
28
  def self.load data
34
29
  case data.byteslice(0, 8)
35
30
  when /\Abplist\d\d/n
@@ -44,6 +39,9 @@ module PropertyList
44
39
  class SyntaxError < RuntimeError
45
40
  end
46
41
 
42
+ class UnsupportedTypeError < RuntimeError
43
+ end
44
+
47
45
  # binary plist v0x elements:
48
46
 
49
47
  class UID
@@ -1,18 +1,17 @@
1
1
  module PropertyList
2
- # options can be:
2
+ # Generate ASCII (Plain) plist.
3
3
  #
4
- # [:indent_unit] the indent unit, default value is <code>"\t"</code>, set to <code>''</code> if you don't need indent
4
+ # Options:
5
5
  #
6
- # [:initial_indent] initial indent space, default is <code>''</code>, the indentation per line equals to <code>initial_indent + indent * current_indent_level</code>
6
+ # - `indent_unit:` the indent unit, default value is `"\t"`, set to `''` if you don't need indent.
7
+ # - `initial_indent:` initial indent space, default is `''`, the indentation per line equals to `initial_indent + indent * current_indent_level`.
8
+ # - `wrap:` wrap the top level output with `{...}` when obj is a Hash, default is `true`.
9
+ # - `encoding_comment:` add encoding comment `// !$*UTF8*$!` on top of file, default is `false`.
10
+ # - `sort_keys:` sort dict keys, default is `true`.
11
+ # - `gnu_extension` whether allow GNUStep extensions for ASCII plist to support serializing more types, default is `true`.
7
12
  #
8
- # [:wrap] wrap the top level output with '{}' when obj is a Hash, default is true.
9
- #
10
- # [:encoding_comment] add encoding comment '!$*UTF8*$!' on top of file, default is false
11
- #
12
- # [:sort_keys] sort dict keys, default is true
13
- #
14
- def self.dump_ascii obj, indent_unit: "\t", initial_indent: '', wrap: true, encoding_comment: false, sort_keys: true
15
- generator = AsciiGenerator.new indent_unit: indent_unit, initial_indent: initial_indent, sort_keys: sort_keys
13
+ def self.dump_ascii obj, indent_unit: "\t", initial_indent: '', wrap: true, encoding_comment: false, sort_keys: true, gnu_extension: true
14
+ generator = AsciiGenerator.new indent_unit: indent_unit, initial_indent: initial_indent, sort_keys: sort_keys, gnu_extension: gnu_extension
16
15
  generator.output << "// !$*UTF8*$!\n" if encoding_comment
17
16
  generator.generate obj, wrap
18
17
  generator.output << "\n" if wrap and obj.is_a?(Hash)
@@ -20,12 +19,13 @@ module PropertyList
20
19
  end
21
20
 
22
21
  class AsciiGenerator #:nodoc:
23
- def initialize indent_unit: "\t", initial_indent: '', sort_keys: true
22
+ def initialize indent_unit: "\t", initial_indent: '', sort_keys: true, gnu_extension: true
24
23
  @indent_unit = indent_unit
25
24
  @indent_level = 0
26
25
  @initial_indent = initial_indent
27
26
  @indent = @initial_indent + @indent_unit * @indent_level
28
27
  @sort_keys = sort_keys
28
+ @gnu_extension = gnu_extension
29
29
  @output = []
30
30
  end
31
31
  attr_reader :output
@@ -52,18 +52,38 @@ module PropertyList
52
52
  ascii_hash_content object
53
53
  end
54
54
  when true
55
- ascii_value "<*BY>"
55
+ if @gnu_extension
56
+ ascii_value "<*BY>"
57
+ else
58
+ raise UnsupportedTypeError, 'TrueClass'
59
+ end
56
60
  when false
57
- ascii_value "<*BN>"
61
+ if @gnu_extension
62
+ ascii_value "<*BN>"
63
+ else
64
+ raise UnsupportedTypeError, 'FalseClass'
65
+ end
58
66
  when Float
59
- if object.to_i == object
60
- object = object.to_i
67
+ if @gnu_extension
68
+ if object.to_i == object
69
+ object = object.to_i
70
+ end
71
+ ascii_value "<*R#{object}>"
72
+ else
73
+ raise UnsupportedTypeError, 'Float'
61
74
  end
62
- ascii_value "<*R#{object}>"
63
75
  when Integer
64
- ascii_value "<*I#{object}>"
76
+ if @gnu_extension
77
+ ascii_value "<*I#{object}>"
78
+ else
79
+ raise UnsupportedTypeError, 'Integer'
80
+ end
65
81
  when Time, Date # also covers DateTime
66
- ascii_value "<*D#{object.strftime '%Y-%m-%d %H:%M:%S %z'}>"
82
+ if @gnu_extension
83
+ ascii_value "<*D#{object.strftime '%Y-%m-%d %H:%M:%S %z'}>"
84
+ else
85
+ raise UnsupportedTypeError, object.class.to_s
86
+ end
67
87
  when String
68
88
  ascii_string object
69
89
  when Symbol
@@ -73,7 +93,7 @@ module PropertyList
73
93
  contents = object.read
74
94
  ascii_data contents
75
95
  else
76
- raise "Generating of this class is not supported"
96
+ raise UnsupportedTypeError, object.class.to_s
77
97
  end
78
98
  end
79
99
 
@@ -1,9 +1,10 @@
1
1
  module PropertyList
2
- def self.load_ascii(data)
3
- AsciiParser.new(data).parse
2
+ # Parse ASCII plist into a Ruby object
3
+ def self.load_ascii text
4
+ AsciiParser.new(text).parse
4
5
  end
5
6
 
6
- class AsciiParser
7
+ class AsciiParser #:nodoc:
7
8
  def initialize src
8
9
  @lexer = StringScanner.new src.strip
9
10
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: binary
2
2
 
3
3
  module PropertyList
4
+ # Generate binary plist, the version is auto detected
4
5
  def self.dump_binary obj, options=nil
5
6
  generator = BinaryGenerator.new options
6
7
  generator.generate obj
@@ -11,7 +12,7 @@ module PropertyList
11
12
  # https://github.com/jarib/plist/blob/master/lib/plist/binary.rb
12
13
  #
13
14
  # With improved performance
14
- class BinaryGenerator
15
+ class BinaryGenerator #:nodoc:
15
16
  include BinaryMarkers
16
17
 
17
18
  def initialize opts
@@ -1,5 +1,5 @@
1
1
  module PropertyList
2
- module BinaryMarkers
2
+ module BinaryMarkers #:nodoc:
3
3
  # These marker bytes are prefixed to objects in a binary property list to
4
4
  # indicate the type of the object.
5
5
  MARKER_NULL = 0b0000_0000 # v1?+ only
@@ -1,11 +1,12 @@
1
1
  module PropertyList
2
- def self.load_binary(data)
2
+ # Parse binary plist into a Ruby object
3
+ def self.load_binary data
3
4
  BinaryParser.new(data).parse
4
5
  end
5
6
 
6
7
  # Reference:
7
8
  # https://opensource.apple.com/source/CF/CF-1151.16/CFBinaryPList.c.auto.html
8
- class BinaryParser
9
+ class BinaryParser #:nodoc:
9
10
  include BinaryMarkers
10
11
 
11
12
  def initialize src
@@ -1,3 +1,3 @@
1
1
  module PropertyList
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.0.2'.freeze
3
3
  end
@@ -1,31 +1,34 @@
1
1
  module PropertyList
2
2
 
3
- # options can be:
3
+ # Generate ASCII (Plain) plist.
4
4
  #
5
- # [:segment] whether wrap the xml output is a segment or wrapped with &lt;?xml&gt; and &lt;plist&gt; tags. default is <code>false</code>.
5
+ # Options:
6
6
  #
7
- # [:xml_version] you can also specify <code>"1.1"</code> for https://www.w3.org/TR/xml11/, default is <code>"1.0"</code>, no effect if <code>:segment</code> is set to <code>true</code>
7
+ # - `segment:` whether output an XML segment (not wrapped with `<?xml>`, `<DOCTYPE>`, `<plist>` tags), default is `false`.
8
+ # - `xml_version:` you can also specify `"1.1"` for https://www.w3.org/TR/xml11/, default is `"1.0"`, no effect if `:segment` is set to `true`.
9
+ # - `gnu_dtd:` use GNUStep DTD instead (which is a bit different in string escaping), default is `false`.
10
+ # - `indent_unit:` the indent unit, default value is `"\t"`, set to or `''` if you don't need indent.
11
+ # - `initial_indent:` initial indent space, default is `''`, the indentation per line equals to `initial_indent + indent * current_indent_level`.
12
+ # - `base64_width:` the width of characters per line when serializing data with Base64, default value is `68`, must be multiple of `4`.
13
+ # - `base64_indent:` whether indent the Base64 encoded data, you can use `false` for compatibility to generate same output for other frameworks, default value is `true`.
8
14
  #
9
- # [:indent_unit] the indent unit, default value is <code>"\t"</code>, set to <code>nil</code> or <code>''</code> if you don't need indent
10
- #
11
- # [:initial_indent] initial indent space, default is <code>''</code>, the indentation per line equals to <code>initial_indent + indent * current_indent_level</code>
12
- #
13
- # [:base64_width] the width of characters per line when serializing data with Base64, default value is <code>68</code>, must be multiple of <code>4</code>
14
- #
15
- # [:base64_indent] whether indent the Base64 encoded data, you can use <code>false</code> for compatibility to generate same output for other frameworks, default value is <code>true</code>
16
- #
17
- def self.dump_xml obj, segment: false, xml_version: '1.0', base64_width: 68, base64_indent: true, indent_unit: "\t", initial_indent: ''
15
+ def self.dump_xml obj, segment: false, xml_version: '1.0', gnu_dtd: false, base64_width: 68, base64_indent: true, indent_unit: "\t", initial_indent: ''
18
16
  if !base64_width.is_a?(Integer) or base64_width <= 0 or base64_width % 4 != 0
19
17
  raise ArgumentError, "option :base64_width must be a positive integer and a multiple of 4"
20
18
  end
21
19
 
22
- generator = XmlGenerator.new base64_width: base64_width, base64_indent: base64_indent, indent_unit: indent_unit, initial_indent: initial_indent
20
+ generator = XmlGenerator.new gnu_dtd: gnu_dtd, base64_width: base64_width, base64_indent: base64_indent, indent_unit: indent_unit, initial_indent: initial_indent
23
21
  if segment
24
22
  generator.generate obj
25
23
  else
26
24
  generator.output << %|<?xml version="#{xml_version}" encoding="UTF-8"?>\n|
27
- generator.output << %|<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n|
28
- generator.output << %|<plist version="1.0">\n|
25
+ if gnu_dtd
26
+ generator.output << %|<!DOCTYPE plist PUBLIC "-//GNUstep//DTD plist 0.9//EN" "http://www.gnustep.org/plist-0_9.xml">\n|
27
+ generator.output << %|<plist>\n|
28
+ else
29
+ generator.output << %|<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n|
30
+ generator.output << %|<plist version="1.0">\n|
31
+ end
29
32
  generator.generate obj
30
33
  generator.output << %|</plist>\n|
31
34
  end
@@ -33,7 +36,8 @@ module PropertyList
33
36
  end
34
37
 
35
38
  class XmlGenerator #:nodoc:
36
- def initialize base64_width: 68, base64_indent: true, indent_unit: "\t", initial_indent: ''
39
+ def initialize gnu_dtd: false, base64_width: 68, base64_indent: true, indent_unit: "\t", initial_indent: ''
40
+ @gnu_dtd = gnu_dtd
37
41
  @indent_unit = indent_unit
38
42
  @indent_level = 0
39
43
  @initial_indent = initial_indent
@@ -101,7 +105,7 @@ module PropertyList
101
105
  contents = obj.read
102
106
  data_tag contents
103
107
  else
104
- raise "Unsupported class: #{obj.class}"
108
+ raise UnsupportedTypeError, obj.class.to_s
105
109
  end
106
110
  end
107
111
 
@@ -139,9 +143,15 @@ module PropertyList
139
143
  TABLE_FOR_ESCAPE = {"&" => "&amp;", "<" => "&lt;", ">" => "&gt;"}.freeze
140
144
  def escape_string s
141
145
  # Likes CGI.escapeHTML but leaves `'` or `"` as mac plist does
142
- s.gsub /[&<>]/ do |c|
146
+ s = s.gsub /[&<>]/ do |c|
143
147
  TABLE_FOR_ESCAPE[c]
144
148
  end
149
+ if @gnu_dtd
150
+ # use \u to escape all control chars
151
+ s.gsub(/[[:cntrl:]]/) {|c| "\\U#{c.ord.to_s(16).rjust 4, '0'}" }
152
+ else
153
+ s
154
+ end
145
155
  end
146
156
  end
147
157
  end
@@ -1,9 +1,10 @@
1
1
  module PropertyList
2
+ # Parse XML plist into a Ruby object
2
3
  def self.load_xml xml
3
4
  XmlParser.new(xml).parse
4
5
  end
5
6
 
6
- class XmlParser
7
+ class XmlParser #:nodoc:
7
8
  def initialize src
8
9
  @lexer = StringScanner.new src
9
10
  end
@@ -6,8 +6,10 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Luikore"]
7
7
  spec.email = 'no@email'
8
8
 
9
- spec.summary = "Property List (plist) library with all formats support"
10
- spec.description = "Full-featured property list library. Supports XML/ASCII/Binary plist generate and parse. Finely-tuned formatting options. No line-ending bug like plist gem. Cross platform. No dependency."
9
+ spec.summary = "Property List (plist, propertylist) library with all formats support"
10
+ spec.description = "Fully featured propertylist library.
11
+ Can load and dump XML/ASCII/Binary plists and offer fine-grained formatting options.
12
+ Cross platform, clean code, performance tuned, no dependency."
11
13
  spec.homepage = "https://github.com/luikore/property-list"
12
14
  spec.license = "BSD-3-Clause"
13
15
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: property-list
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luikore
@@ -80,15 +80,17 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.14'
83
- description: Full-featured property list library. Supports XML/ASCII/Binary plist
84
- generate and parse. Finely-tuned formatting options. No line-ending bug like plist
85
- gem. Cross platform. No dependency.
83
+ description: |-
84
+ Fully featured propertylist library.
85
+ Can load and dump XML/ASCII/Binary plists and offer fine-grained formatting options.
86
+ Cross platform, clean code, performance tuned, no dependency.
86
87
  email: no@email
87
88
  executables: []
88
89
  extensions: []
89
90
  extra_rdoc_files: []
90
91
  files:
91
92
  - ".gitignore"
93
+ - ".rdoc_options"
92
94
  - LICENSE
93
95
  - README.md
94
96
  - Rakefile
@@ -127,5 +129,5 @@ rubyforge_project:
127
129
  rubygems_version: 2.6.11
128
130
  signing_key:
129
131
  specification_version: 4
130
- summary: Property List (plist) library with all formats support
132
+ summary: Property List (plist, propertylist) library with all formats support
131
133
  test_files: []