plist4r 0.2.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.yardopts +11 -0
- data/LICENSE +3 -1
- data/README.rdoc +25 -122
- data/Rakefile +14 -0
- data/VERSION +1 -1
- data/bin/plist4r +2 -0
- data/ext/osx_plist/Makefile +157 -0
- data/ext/osx_plist/extconf.rb +9 -0
- data/ext/osx_plist/plist.c +606 -0
- data/ext/osx_plist/plist.o +0 -0
- data/lib/plist4r.rb +6 -3
- data/lib/plist4r/application.rb +1 -2
- data/lib/plist4r/backend.rb +102 -34
- data/lib/plist4r/backend/c_f_property_list.rb +65 -0
- data/lib/plist4r/backend/c_f_property_list/LICENSE +19 -0
- data/lib/plist4r/backend/c_f_property_list/README +34 -0
- data/lib/plist4r/backend/c_f_property_list/cfpropertylist.rb +6 -0
- data/lib/plist4r/backend/c_f_property_list/rbBinaryCFPropertyList.rb +663 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFPlistError.rb +26 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFPropertyList.rb +348 -0
- data/lib/plist4r/backend/c_f_property_list/rbCFTypes.rb +241 -0
- data/lib/plist4r/backend/c_f_property_list/rbXMLCFPropertyList.rb +116 -0
- data/lib/plist4r/backend/example.rb +37 -52
- data/lib/plist4r/backend/haml.rb +47 -36
- data/lib/plist4r/backend/libxml4r.rb +24 -20
- data/lib/plist4r/backend/osx_plist.rb +82 -0
- data/lib/plist4r/backend/ruby_cocoa.rb +172 -54
- data/lib/plist4r/backend/test/data_types.rb +163 -0
- data/lib/plist4r/backend/test/harness.rb +255 -0
- data/lib/plist4r/backend/test/output.rb +47 -0
- data/lib/plist4r/backend_base.rb +4 -2
- data/lib/plist4r/{options.rb → cli.rb} +2 -1
- data/lib/plist4r/commands.rb +13 -8
- data/lib/plist4r/config.rb +36 -9
- data/lib/plist4r/docs/Backends.html +59 -0
- data/lib/plist4r/docs/DeveloperGuide.rdoc +53 -0
- data/lib/plist4r/docs/EditingPlistFiles.rdoc +88 -0
- data/lib/plist4r/docs/InfoPlistExample.rdoc +33 -0
- data/lib/plist4r/docs/LaunchdPlistExample.rdoc +33 -0
- data/lib/plist4r/docs/PlistKeyNames.rdoc +47 -0
- data/lib/plist4r/mixin/array_dict.rb +61 -0
- data/lib/plist4r/mixin/data_methods.rb +178 -54
- data/lib/plist4r/mixin/haml4r.rb +4 -0
- data/lib/plist4r/mixin/haml4r/css_attributes.rb +19 -0
- data/lib/plist4r/mixin/haml4r/examples.rb +261 -0
- data/lib/plist4r/mixin/haml4r/haml_table_example.rb +79 -0
- data/lib/plist4r/mixin/haml4r/table.rb +157 -0
- data/lib/plist4r/mixin/haml4r/table_cell.rb +160 -0
- data/lib/plist4r/mixin/haml4r/table_cells.rb +485 -0
- data/lib/plist4r/mixin/haml4r/table_section.rb +101 -0
- data/lib/plist4r/mixin/ordered_hash.rb +9 -1
- data/lib/plist4r/mixin/popen4.rb +1 -1
- data/lib/plist4r/mixin/ruby_stdlib.rb +154 -1
- data/lib/plist4r/mixin/script.rb +133 -0
- data/lib/plist4r/mixin/table.rb +435 -0
- data/lib/plist4r/plist.rb +272 -94
- data/lib/plist4r/plist_cache.rb +42 -43
- data/lib/plist4r/plist_type.rb +31 -74
- data/lib/plist4r/plist_type/info.rb +157 -3
- data/lib/plist4r/plist_type/launchd.rb +54 -48
- data/lib/plist4r/plist_type/plist.rb +1 -3
- data/plist4r.gemspec +74 -14
- data/spec/{examples.rb → launchd_examples.rb} +131 -139
- data/spec/plist4r/application_spec.rb +37 -0
- data/spec/plist4r/backend_spec.rb +256 -0
- data/spec/plist4r/cli_spec.rb +25 -0
- data/spec/plist4r/commands_spec.rb +20 -0
- data/spec/plist4r/config_spec.rb +38 -0
- data/spec/plist4r/mixin/array_dict_spec.rb +120 -0
- data/spec/plist4r/mixin/data_methods_spec.rb +96 -0
- data/spec/plist4r/mixin/haml4r/examples.rb +261 -0
- data/spec/plist4r/mixin/ruby_stdlib_spec.rb +228 -0
- data/spec/plist4r/plist_cache_spec.rb +261 -0
- data/spec/plist4r/plist_spec.rb +841 -23
- data/spec/plist4r/plist_type_spec.rb +126 -0
- data/spec/plist4r_spec.rb +53 -27
- data/spec/scratchpad.rb +226 -0
- data/spec/spec_helper.rb +5 -1
- metadata +109 -23
- data/lib/plist4r/backend/plutil.rb +0 -25
- data/lib/plist4r/mixin.rb +0 -7
- data/plists/array_mini.xml +0 -14
- data/plists/example_big_binary.plist +0 -0
- data/plists/example_medium_binary_launchd.plist +0 -0
- data/plists/example_medium_launchd.xml +0 -53
- data/plists/mini.xml +0 -12
- data/test.rb +0 -40
@@ -0,0 +1,116 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module CFPropertyList
|
4
|
+
# XML parser
|
5
|
+
class XML < ParserInterface
|
6
|
+
# read a XML file
|
7
|
+
# opts::
|
8
|
+
# * :file - The filename of the file to load
|
9
|
+
# * :data - The data to parse
|
10
|
+
def load(opts)
|
11
|
+
if(opts.has_key?(:file)) then
|
12
|
+
doc = LibXML::XML::Document.file(opts[:file],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
|
13
|
+
else
|
14
|
+
doc = LibXML::XML::Document.string(opts[:data],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
|
15
|
+
end
|
16
|
+
|
17
|
+
root = doc.root.first
|
18
|
+
return import_xml(root)
|
19
|
+
end
|
20
|
+
|
21
|
+
# serialize CFPropertyList object to XML
|
22
|
+
# opts = {}:: Specify options: :formatted - Use indention and line breaks
|
23
|
+
def to_str(opts={})
|
24
|
+
doc = LibXML::XML::Document.new
|
25
|
+
|
26
|
+
doc.root = LibXML::XML::Node.new('plist')
|
27
|
+
doc.encoding = LibXML::XML::Encoding::UTF_8
|
28
|
+
|
29
|
+
doc.root['version'] = '1.0'
|
30
|
+
doc.root << opts[:root].to_xml()
|
31
|
+
|
32
|
+
# ugly hack, but there's no other possibility I know
|
33
|
+
str = doc.to_s(:indent => opts[:formatted])
|
34
|
+
str1 = String.new
|
35
|
+
first = false
|
36
|
+
str.each_line do
|
37
|
+
|line|
|
38
|
+
str1 << line
|
39
|
+
unless(first) then
|
40
|
+
str1 << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
|
41
|
+
end
|
42
|
+
|
43
|
+
first = true
|
44
|
+
end
|
45
|
+
|
46
|
+
return str1
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
# get the value of a DOM node
|
52
|
+
def get_value(n)
|
53
|
+
return n.first.content if n.children?
|
54
|
+
return n.content
|
55
|
+
end
|
56
|
+
|
57
|
+
# import the XML values
|
58
|
+
def import_xml(node)
|
59
|
+
ret = nil
|
60
|
+
|
61
|
+
case node.name
|
62
|
+
when 'dict'
|
63
|
+
hsh = Hash.new
|
64
|
+
key = nil
|
65
|
+
|
66
|
+
if node.children? then
|
67
|
+
node.children.each do
|
68
|
+
|n|
|
69
|
+
next if n.text? # avoid a bug of libxml
|
70
|
+
|
71
|
+
if n.name == "key" then
|
72
|
+
key = get_value(n)
|
73
|
+
else
|
74
|
+
raise CFFormatError.new("Format error!") if key.nil?
|
75
|
+
hsh[key] = import_xml(n)
|
76
|
+
key = nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
ret = CFDictionary.new(hsh)
|
82
|
+
|
83
|
+
when 'array'
|
84
|
+
ary = Array.new
|
85
|
+
|
86
|
+
if node.children? then
|
87
|
+
node.children.each do
|
88
|
+
|n|
|
89
|
+
ary.push import_xml(n)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
ret = CFArray.new(ary)
|
94
|
+
|
95
|
+
when 'true'
|
96
|
+
ret = CFBoolean.new(true)
|
97
|
+
when 'false'
|
98
|
+
ret = CFBoolean.new(false)
|
99
|
+
when 'real'
|
100
|
+
ret = CFReal.new(get_value(node).to_f)
|
101
|
+
when 'integer'
|
102
|
+
ret = CFInteger.new(get_value(node).to_i)
|
103
|
+
when 'string'
|
104
|
+
ret = CFString.new(get_value(node))
|
105
|
+
when 'data'
|
106
|
+
ret = CFData.new(get_value(node))
|
107
|
+
when 'date'
|
108
|
+
ret = CFDate.new(CFDate.parse_date(get_value(node)))
|
109
|
+
end
|
110
|
+
|
111
|
+
return ret
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# eof
|
@@ -11,32 +11,55 @@ require 'plist4r/backend_base'
|
|
11
11
|
# as appropriate. Then raise an exception for those situation where backend is unable to continue.
|
12
12
|
#
|
13
13
|
# For example, if your backend is only able to load :xml files, then it should raise an exception
|
14
|
-
# whenever it encounters :binary or :
|
14
|
+
# whenever it encounters :binary or :gnustep formatted files. This is intentional.
|
15
15
|
# By throwing the error, it means the API call can be picked up and passed on to the next available backend.
|
16
16
|
#
|
17
17
|
# @see Plist4r::Backend
|
18
18
|
module Plist4r::Backend::Example
|
19
19
|
class << self
|
20
|
-
|
20
|
+
|
21
21
|
# Parse a String of plist data and store it into the supplied {Plist4r::Plist}
|
22
22
|
# * Please click "View Source" for the example.
|
23
23
|
# @param [Plist4r::Plist] plist The plist object to read the string from
|
24
24
|
# @return [Plist4r::Plist] the same plist object, but updated to match its from_string
|
25
25
|
# @see Plist4r::Plist#from_string
|
26
26
|
# @see Plist4r.string_detect_format
|
27
|
-
def
|
28
|
-
|
29
|
-
plist_format = Plist4r.string_detect_format plist.from_string
|
30
|
-
unless [:supported_fmt1,:supported_fmt2].include? plist_format
|
31
|
-
raise "#{self} - cant convert string of format #{plist_format}"
|
32
|
-
end
|
27
|
+
def from_xml plist
|
28
|
+
xml_string = plist.from_string
|
33
29
|
hash = ::Plist4r::OrderedHash.new
|
34
30
|
# import / convert plist data into ruby ordered hash
|
35
31
|
plist.import_hash hash
|
36
|
-
plist.file_format plist_format
|
37
32
|
return plist
|
38
33
|
end
|
39
34
|
|
35
|
+
# Parse a String of plist data and store it into the supplied {Plist4r::Plist}
|
36
|
+
# * Please click "View Source" for the example.
|
37
|
+
# @param [Plist4r::Plist] plist The plist object to read the string from
|
38
|
+
# @return [Plist4r::Plist] the same plist object, but updated to match its from_string
|
39
|
+
# @see Plist4r::Plist#from_string
|
40
|
+
# @see Plist4r.string_detect_format
|
41
|
+
def from_binary plist
|
42
|
+
binary_string = plist.from_string
|
43
|
+
hash = ::Plist4r::OrderedHash.new
|
44
|
+
# import / convert plist data into ruby ordered hash
|
45
|
+
plist.import_hash hash
|
46
|
+
return plist
|
47
|
+
end
|
48
|
+
|
49
|
+
# Parse a String of plist data and store it into the supplied {Plist4r::Plist}
|
50
|
+
# * Please click "View Source" for the example.
|
51
|
+
# @param [Plist4r::Plist] plist The plist object to read the string from
|
52
|
+
# @return [Plist4r::Plist] the same plist object, but updated to match its from_string
|
53
|
+
# @see Plist4r::Plist#from_string
|
54
|
+
# @see Plist4r.string_detect_format
|
55
|
+
def from_gnustep plist
|
56
|
+
gnustep_string = plist.from_string
|
57
|
+
hash = ::Plist4r::OrderedHash.new
|
58
|
+
# import / convert plist data into ruby ordered hash
|
59
|
+
plist.import_hash hash
|
60
|
+
return plist
|
61
|
+
end
|
62
|
+
|
40
63
|
# Convert a {Plist4r::Plist} into an "xml" formatted plist String
|
41
64
|
# * Please click "View Source" for the example.
|
42
65
|
# @param [Plist4r::Plist] plist The plist object to convert
|
@@ -57,52 +80,14 @@ module Plist4r::Backend::Example
|
|
57
80
|
return binary_string
|
58
81
|
end
|
59
82
|
|
60
|
-
# Convert a {Plist4r::Plist} into a "
|
61
|
-
# * Please click "View Source" for the example.
|
62
|
-
# @param [Plist4r::Plist] plist The plist object to convert
|
63
|
-
# @return [String] the next_step string
|
64
|
-
def to_next_step plist
|
65
|
-
hash = plist.to_hash
|
66
|
-
next_step_string = "Convert the plists's nested ruby hash into next_step format here"
|
67
|
-
return next_step_string
|
68
|
-
end
|
69
|
-
|
70
|
-
# Open a plist file and store the contents into the supplied {Plist4r::Plist}
|
83
|
+
# Convert a {Plist4r::Plist} into a "gnustep" formatted plist String
|
71
84
|
# * Please click "View Source" for the example.
|
72
85
|
# @param [Plist4r::Plist] plist The plist object to convert
|
73
|
-
# @return [String] the
|
74
|
-
|
75
|
-
def open plist
|
76
|
-
filename = plist.filename_path
|
77
|
-
file_format = Plist4r.file_detect_format filename
|
78
|
-
unless [:supported_fmt1,:supported_fmt2].include? file_format
|
79
|
-
raise "#{self} - cant load file of format #{file_format}"
|
80
|
-
end
|
81
|
-
plist_file_as_string = File.read(filename)
|
82
|
-
hash = ::Plist4r::OrderedHash.new
|
83
|
-
# import / convert plist data into ruby ordered hash
|
84
|
-
plist.import_hash hash
|
85
|
-
plist.file_format file_format
|
86
|
-
return plist
|
87
|
-
end
|
88
|
-
|
89
|
-
# @param [Plist4r::Plist] plist The plist object to read the filename from
|
90
|
-
# @return [Plist4r::Plist] the same plist object, but updated to match the file contents
|
91
|
-
# @see Plist4r::Plist#filename_path
|
92
|
-
def save plist
|
93
|
-
filename = plist.filename_path
|
94
|
-
file_format = plist.file_format || Config[:default_format]
|
95
|
-
unless [:xml,:binary].include? file_format
|
96
|
-
raise "#{self} - cant save file of format #{file_format}"
|
97
|
-
end
|
86
|
+
# @return [String] the gnustep string
|
87
|
+
def to_gnustep plist
|
98
88
|
hash = plist.to_hash
|
99
|
-
|
100
|
-
|
101
|
-
# and formatted to your supported plist file_format(s)
|
102
|
-
File.open(filename,'w') do |out|
|
103
|
-
out << output_string
|
104
|
-
end
|
105
|
-
return true
|
89
|
+
gnustep_string = "Convert the plists's nested ruby hash into gnustep format here"
|
90
|
+
return gnustep_string
|
106
91
|
end
|
107
92
|
end
|
108
93
|
end
|
data/lib/plist4r/backend/haml.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
|
2
2
|
require 'plist4r/backend_base'
|
3
|
+
require 'plist4r/mixin/ruby_stdlib'
|
4
|
+
require 'haml'
|
5
|
+
require 'base64'
|
6
|
+
require 'date'
|
3
7
|
|
4
|
-
#
|
8
|
+
# This backend uses haml to generate xml plists
|
9
|
+
# @author Dreamcat4 (dreamcat4@gmail.com)
|
5
10
|
module Plist4r::Backend::Haml
|
6
|
-
|
7
|
-
|
8
|
-
|
11
|
+
class << self
|
12
|
+
def to_xml_haml
|
13
|
+
@to_xml_haml ||= <<-'EOC'
|
9
14
|
!!! XML UTF-8
|
10
15
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
|
11
16
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
|
@@ -20,56 +25,62 @@ module Plist4r::Backend::Haml
|
|
20
25
|
<#{v}/>
|
21
26
|
- when String
|
22
27
|
%key #{k}
|
23
|
-
|
24
|
-
|
28
|
+
- if v.blob?
|
29
|
+
- data = Base64::encode64(v)
|
30
|
+
%data #{data}
|
31
|
+
- else
|
32
|
+
%string #{v}
|
33
|
+
- when Integer
|
25
34
|
%key #{k}
|
26
35
|
%integer #{v}
|
36
|
+
- when Float
|
37
|
+
%key #{k}
|
38
|
+
%real #{v}
|
39
|
+
- when Time
|
40
|
+
%key #{k}
|
41
|
+
%date #{v.utc.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
42
|
+
- when Date
|
43
|
+
%key #{k}
|
44
|
+
%date #{v.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
27
45
|
- when Array
|
28
46
|
%key #{k}
|
29
47
|
%array
|
30
48
|
- v.compact.each do |e|
|
31
49
|
- case e
|
32
50
|
- when TrueClass, FalseClass
|
33
|
-
<#{
|
51
|
+
<#{e}/>
|
34
52
|
- when String
|
35
|
-
|
36
|
-
|
37
|
-
|
53
|
+
- if e.blob?
|
54
|
+
- data = Base64::encode64(e)
|
55
|
+
%data #{data}
|
56
|
+
- else
|
57
|
+
%string #{e}
|
58
|
+
- when Integer
|
59
|
+
%integer #{e}
|
60
|
+
- when Float
|
61
|
+
%real #{e}
|
62
|
+
- when Time
|
63
|
+
%date #{e.utc.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
64
|
+
- when Date
|
65
|
+
%date #{e.strftime('%Y-%m-%dT%H:%M:%SZ')}
|
38
66
|
- when Hash
|
39
67
|
%dict
|
40
68
|
- tab_up ; block.call(e, block) ; tab_down
|
41
|
-
- else
|
42
|
-
- raise "Invalid input. Array: #{v.inspect} can only contain elements of type String (<string>) or Hash (<dict>). Found element: #{e.inspect} of type: \"#{e.class}\""
|
43
69
|
- when Hash
|
44
70
|
%key #{k}
|
45
71
|
%dict
|
46
72
|
- tab_up ; block.call(v, block) ; tab_down
|
47
|
-
- else
|
48
|
-
- raise "Invalid input. Hash: #{data.inspect} can only contain values of type true, false, String (<string>) Fixnum (<integer>) Array (<array>) or Hash (<dict>). Found value: #{v.inspect} of type: \"#{v.class}\""
|
49
|
-
- p.call( @hash, p)
|
50
|
-
EOC
|
51
|
-
end
|
52
73
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
engine = Haml::Engine.new to_xml_haml
|
57
|
-
rendered_xml_output = engine.render self
|
58
|
-
File.open(@filename,'w') do |o|
|
59
|
-
o << rendered_xml_output
|
60
|
-
end
|
61
|
-
end
|
74
|
+
- p.call( @plist.to_hash, p)
|
75
|
+
EOC
|
76
|
+
end
|
62
77
|
|
63
|
-
|
64
|
-
|
65
|
-
|
78
|
+
def to_xml plist
|
79
|
+
@plist = plist
|
80
|
+
engine = Haml::Engine.new to_xml_haml
|
81
|
+
rendered_xml_output = engine.render self
|
82
|
+
end
|
66
83
|
|
67
|
-
|
68
|
-
filename = plist.filename_path
|
69
|
-
File.open(filename,'w') do |out|
|
70
|
-
out << to_xml(plist)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
84
|
+
end
|
74
85
|
end
|
75
86
|
|
@@ -1,7 +1,11 @@
|
|
1
1
|
|
2
2
|
require 'plist4r/backend_base'
|
3
|
+
require 'libxml4r'
|
4
|
+
require 'base64'
|
5
|
+
require 'date'
|
3
6
|
|
4
|
-
#
|
7
|
+
# This backend uses Libxml4r / Libxml-Ruby to parse xml plists
|
8
|
+
# @author Dreamcat4 (dreamcat4@gmail.com)
|
5
9
|
module Plist4r::Backend::Libxml4r
|
6
10
|
class << self
|
7
11
|
def tree_hash n
|
@@ -17,12 +21,18 @@ module Plist4r::Backend::Libxml4r
|
|
17
21
|
hash[k] = vnode.inner_xml
|
18
22
|
when "integer"
|
19
23
|
hash[k] = vnode.inner_xml.to_i
|
24
|
+
when "real"
|
25
|
+
hash[k] = vnode.inner_xml.to_f
|
26
|
+
when "date"
|
27
|
+
hash[k] = Time.parse vnode.inner_xml
|
28
|
+
when "data"
|
29
|
+
bstr = Base64.decode64(vnode.inner_xml)
|
30
|
+
bstr.blob = true
|
31
|
+
hash[k] = bstr
|
20
32
|
when "array"
|
21
33
|
hash[k] = tree_array(vnode)
|
22
34
|
when "dict"
|
23
35
|
hash[k] = tree_hash(vnode)
|
24
|
-
else
|
25
|
-
raise "Unsupported / not recognized plist key: #{vnode.name}"
|
26
36
|
end
|
27
37
|
end
|
28
38
|
return hash
|
@@ -38,20 +48,24 @@ module Plist4r::Backend::Libxml4r
|
|
38
48
|
array << node.inner_xml
|
39
49
|
when "integer"
|
40
50
|
array << node.inner_xml.to_i
|
51
|
+
when "real"
|
52
|
+
array << node.inner_xml.to_f
|
53
|
+
when "date"
|
54
|
+
array << Time.parse(node.inner_xml)
|
55
|
+
when "data"
|
56
|
+
bstr = bstr = Base64.decode64(node.inner_xml)
|
57
|
+
bstr.blob = true
|
58
|
+
array << bstr
|
41
59
|
when "array"
|
42
60
|
array << tree_array(node)
|
43
61
|
when "dict"
|
44
62
|
array << tree_hash(node)
|
45
|
-
else
|
46
|
-
raise "Unsupported / not recognized plist key: #{vnode.name}"
|
47
63
|
end
|
48
64
|
end
|
49
65
|
return array
|
50
66
|
end
|
51
67
|
|
52
68
|
def parse_plist_xml string
|
53
|
-
require 'rubygems'
|
54
|
-
require 'libxml4r'
|
55
69
|
::LibXML::XML.default_keep_blanks = false
|
56
70
|
doc = string.to_xmldoc
|
57
71
|
doc.strip!
|
@@ -70,22 +84,12 @@ module Plist4r::Backend::Libxml4r
|
|
70
84
|
ordered_hash
|
71
85
|
end
|
72
86
|
|
73
|
-
def
|
74
|
-
|
75
|
-
raise "#{self} - cant convert string of format #{plist_format}" unless plist_format == :xml
|
76
|
-
hash = parse_plist_xml string
|
87
|
+
def from_xml plist
|
88
|
+
hash = parse_plist_xml plist.from_string
|
77
89
|
plist.import_hash hash
|
78
|
-
plist.file_format
|
90
|
+
plist.file_format "xml"
|
79
91
|
return plist
|
80
92
|
end
|
81
|
-
|
82
|
-
def open plist
|
83
|
-
filename = plist.filename_path
|
84
|
-
file_format = Plist4r.file_detect_format filename
|
85
|
-
raise "#{self} - cant load file of format #{file_format}" unless file_format == :xml
|
86
|
-
|
87
|
-
return from_string plist, File.read(filename)
|
88
|
-
end
|
89
93
|
end
|
90
94
|
end
|
91
95
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
require 'plist4r/backend_base'
|
3
|
+
|
4
|
+
# Source: http://github.com/kballard/osx-plist
|
5
|
+
#
|
6
|
+
# This backend only works on MacOSX. It supports everything using a compiled CoreFoundation helper
|
7
|
+
# in ext directory, and uses native Cocoa CoreFoundation API calls. This backend invokes
|
8
|
+
# CFPropertyListWriteToStream.
|
9
|
+
#
|
10
|
+
# Should work for any 10.5 (Leopard), 10.6 (Snow Leopard) Mac OSX distribution.
|
11
|
+
# It will do nothing on non-mac platforms (eg Linux etc).
|
12
|
+
# @author Kevin Ballard (http://github.com/kballard)
|
13
|
+
module Plist4r::Backend::OsxPlist
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def require_c_ext
|
17
|
+
core_foundation_framework = "/System/Library/Frameworks/CoreFoundation.framework"
|
18
|
+
unless File.exists? core_foundation_framework
|
19
|
+
raise "CoreFoundation Framework not found. Searched in: #{core_foundation_framework}"
|
20
|
+
end
|
21
|
+
require "#{File.dirname(__FILE__)}/osx_plist/ext/osx_plist"
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_string plist
|
25
|
+
require_c_ext
|
26
|
+
ruby_object = Plist4r::Backend::OsxPlist.load(plist.from_string, nil)
|
27
|
+
|
28
|
+
hash_obj = nil
|
29
|
+
if ruby_object.is_a? Hash
|
30
|
+
hash_obj = ruby_object
|
31
|
+
|
32
|
+
elsif ruby_object
|
33
|
+
hash_obj = { ruby_object.class.to_s => ruby_object }
|
34
|
+
|
35
|
+
else
|
36
|
+
raise "Conversion tp plist object failed"
|
37
|
+
end
|
38
|
+
|
39
|
+
hash = ::Plist4r::OrderedHash.new
|
40
|
+
hash.replace hash_obj
|
41
|
+
plist.import_hash hash
|
42
|
+
|
43
|
+
return plist
|
44
|
+
end
|
45
|
+
|
46
|
+
def from_xml plist
|
47
|
+
from_string plist
|
48
|
+
end
|
49
|
+
|
50
|
+
def from_binary plist
|
51
|
+
from_string plist
|
52
|
+
end
|
53
|
+
|
54
|
+
def from_gnustep plist
|
55
|
+
from_string plist
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_fmt plist, fmt
|
59
|
+
require_c_ext
|
60
|
+
string = ""
|
61
|
+
sio = StringIO.new(string, "w")
|
62
|
+
Plist4r::Backend::OsxPlist.dump(sio, plist.to_hash, fmt)
|
63
|
+
return string
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_xml plist
|
67
|
+
to_fmt plist, :xml1
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_binary plist
|
71
|
+
to_fmt plist, :binary1
|
72
|
+
end
|
73
|
+
|
74
|
+
# alas, no longer supported by the apple apis :(
|
75
|
+
# def to_gnustep plist
|
76
|
+
# to_fmt plist, :openstep
|
77
|
+
# end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|