property-list 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []