Module: Plist4r::Backend::RubyCocoa
- Defined in:
- lib/plist4r/backend/ruby_cocoa.rb
Class Methods
- convert_19_to_hash
- from_binary
- from_gnustep
- from_string
- from_xml
- open_with_args
- read_result_file
- ruby_cocoa_exec
- ruby_cocoa_wrapper_rb
- to_binary
- to_xml
Overview
This backend only works on MacOSX. It supports everything except Example.to_gnustep, and saving in the :gnustep file format. This is Because RubyCocoa uses the NSPropertyListSerialization class, which doesnt support writing to OpenStep Format.
Here we are calling the stock OSX Ruby in a seperate process. It isolates the runtime from any shared lib (.so) LoadErrors. And allows calling from other installed Ruby instances (eg REE), which dont usually have RubyCocoa enabled.
This Backend should work for any 10.5 (Leopard), 10.6 (Snow Leopard) Mac OSX distribution. It will do nothing on non-mac platforms (eg Linux etc).
Class Method Details
+ (Object) convert_19_to_hash(hash, key = nil)
263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 263 def convert_19_to_hash hash, key=nil h = Hash.new h.replace hash hash.each do |key,value| if value.class.ancestors.include? Hash unless value.class == Hash h[key] = convert_19_to_hash(value) end end end h end |
+ (Object) from_binary(plist)
356 357 358 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 356 def from_binary plist from_string plist end |
+ (Object) from_gnustep(plist)
360 361 362 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 360 def from_gnustep plist from_string plist end |
+ (Object) from_string(plist)
343 344 345 346 347 348 349 350 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 343 def from_string plist require 'tempfile' tf = Tempfile.new "from_string.plist." tf.write plist.from_string tf.close filename = tf.path return open_with_args plist, filename end |
+ (Object) from_xml(plist)
352 353 354 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 352 def from_xml plist from_string plist end |
+ (Object) open_with_args(plist, filename)
328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 328 def open_with_args plist, filename result = ruby_cocoa_exec "open(\"#{filename}\")" case result[1].exitstatus when 0 hash = Plist4r::OrderedHash.new hash.replace Marshal.load(read_result_file) plist.import_hash hash else $stderr.puts result[3] raise "Error executing #{result[0]}. See stderr for more information" end return plist end |
+ (Object) read_result_file
259 260 261 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 259 def read_result_file File.read @result_file.path end |
+ (Array) ruby_cocoa_exec(stdin_str)
Write a temporary script to the filesystem, then execute it
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 216 def ruby_cocoa_exec stdin_str rubycocoa_framework = "/System/Library/Frameworks/RubyCocoa.framework" raise "RubyCocoa Framework not found. Searched in: #{rubycocoa_framework}" unless File.exists? rubycocoa_framework require 'tempfile' require 'plist4r/mixin/popen4' unless @rb_script && File.exists?(@rb_script.path) @rb_script = Tempfile.new "ruby_cocoa_wrapper.rb." @rb_script.puts ruby_cocoa_wrapper_rb @rb_script.close File.chmod 0755, @rb_script.path end cmd = @rb_script.path plist4r_root = File. File.join(File.dirname(__FILE__), "..", "..") @result_file = Tempfile.new("result_file.rb") @result_file.close pid, stdin, stdout, stderr = ::Plist4r::Popen4::popen4 [cmd, plist4r_root, @result_file.path] stdin.puts stdin_str stdin.close ignored, status = [nil,nil] begin Timeout::timeout(Plist4r::Config[:backend_timeout]) do ignored, status = Process::waitpid2 pid end rescue Timeout::Error => exc puts "#{exc.message}, killing pid #{pid}" Process::kill('TERM', pid) # Process::kill('HUP', pid) ignored, status = Process::waitpid2 pid end stdout_result = stdout.read.strip stderr_result = stderr.read.strip return [cmd, status, stdout_result, stderr_result] end |
+ (Object) ruby_cocoa_wrapper_rb
A seperate ruby script, which runs in its own process.
62 63 64 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 62 def ruby_cocoa_wrapper_rb @ruby_cocoa_wrapper_rb ||= "#!/usr/bin/ruby\nraise \"No path given to plist4r\" unless ARGV[0] && File.exists?(\"\#{ARGV[0]}/plist4r.rb\")\n\ndir = ARGV[0]\n$LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)\n\nrequire 'osx/cocoa'\nrequire 'time'\nrequire 'plist4r/mixin/ordered_hash'\nrequire 'plist4r/mixin/ruby_stdlib'\n\nmodule Plist4r\nclass StringIOData\nattr_accessor :string\ndef initialize string\n@string = string\nend\n\ndef to_s\n@string\nend\n\ndef _dump arg\n@string\nend\n\ndef self._load string\nOSX::NSData.dataWithRubyString(string)\nend\nend\nend\n\nclass String\ndef _dump arg\nself\nend\n\ndef self._load string\nString.new(string)\nend\nend\n\n# Property list API.\nmodule OSX\ndef object_to_plist(object, format=nil)\nformat ||= OSX::NSPropertyListXMLFormat_v1_0\ndata, error = OSX::NSPropertyListSerialization.objc_send \\\n:dataFromPropertyList, object,\n:format, format,\n:errorDescription\nraise error.to_s if data.nil?\ncase format\nwhen OSX::NSPropertyListXMLFormat_v1_0,\nOSX::NSPropertyListOpenStepFormat\nOSX::NSString.alloc.initWithData_encoding(data,\nOSX::NSUTF8StringEncoding).to_s\nelse\ndata.bytes.bytestr(data.length)\nend\nend\nmodule_function :object_to_plist\nend\n\nclass OSX::NSObject\ndef to_ruby\ncase self\nwhen OSX::NSDate\nself.to_time\nwhen OSX::NSCFBoolean\nself.boolValue\nwhen OSX::NSNumber\nself.integer? ? self.to_i : self.to_f\nwhen OSX::NSString\nself.to_s\nwhen OSX::NSData\nPlist4r::StringIOData.new self.rubyString\nwhen OSX::NSAttributedString\nself.string.to_s\nwhen OSX::NSArray\nself.to_a.map { |x| x.is_a?(OSX::NSObject) ? x.to_ruby : x }\nwhen OSX::NSDictionary\nh = Plist4r::ActiveSupport::OrderedHash.new\nself.each do |x, y|\nx = x.to_ruby if x.is_a?(OSX::NSObject)\ny = y.to_ruby if y.is_a?(OSX::NSObject)\nh[x] = y\nend\nh\nelse\nself\nend\nend\nend\n\nmodule Plist\ndef write_result_file obj\nFile.open @result_file, 'w' do |o|\no << obj\nend\nend\n\ndef to_xml input_file\n# to_plist defaults to NSPropertyListXMLFormat_v1_0\nhash = Marshal.load(File.read(input_file))\nx = hash.to_plist\n# x = hash.inspect\nwrite_result_file x\nend\n\ndef to_binary input_file\n# Here 200 == NSPropertyListBinaryFormat_v1_0\nhash = Marshal.load(File.read(input_file))\nx = hash.to_plist 200\n# x = hash.inspect\nwrite_result_file x\nend\n\ndef open filename\nplist_dict = ::OSX::NSDictionary.dictionaryWithContentsOfFile(filename)\nunless plist_dict\nplist_array = ::OSX::NSArray.arrayWithContentsOfFile(filename) unless plist_dict\nraise \"Couldnt parse file: \#{filename}\" unless plist_array\nplist_dict = Plist4r::ActiveSupport::OrderedHash.new\nplist_dict[\"Array\"] = plist_array.to_ruby\nend\n\nFile.open @result_file, 'w' do |o|\no.write Marshal.dump(plist_dict.to_ruby)\nend\nend\nend\n\nclass RubyCocoaWrapper\ninclude Plist\n\ndef exec stdin\n@result_file = ARGV[1]\ninstance_eval stdin\nexit 0\nend\nend\n\nstdin = $stdin.read()\nwrapper = RubyCocoaWrapper.new()\nwrapper.exec stdin\n" end |
+ (Object) to_binary(plist)
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 303 def to_binary plist require 'tempfile' input_file = Tempfile.new "input_file.rb." if RUBY_VERSION >= '1.9' old_style_hash = convert_19_to_hash(plist.to_hash) input_file.puts Marshal.dump(old_style_hash) else input_file.puts Marshal.dump(plist.to_hash) end input_file.close result = ruby_cocoa_exec "to_binary(\"#{input_file.path}\")" # print read_result_file case result[1].exitstatus when 0 binary_string = read_result_file return binary_string else $stderr.puts result[3] raise "Error executing #{result[0]}. See stderr for more information" end end |
+ (Object) to_xml(plist)
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/plist4r/backend/ruby_cocoa.rb', line 277 def to_xml plist require 'tempfile' input_file = Tempfile.new "input_file.rb." oh = nil if RUBY_VERSION >= '1.9' old_style_hash = convert_19_to_hash(plist.to_hash) input_file.puts Marshal.dump(old_style_hash) else input_file.puts Marshal.dump(plist.to_hash) end input_file.close result = ruby_cocoa_exec "to_xml(\"#{input_file.path}\")" # print read_result_file case result[1].exitstatus when 0 xml_string = read_result_file return xml_string else $stderr.puts result[3] raise "Error executing #{result[0]}. See stderr for more information" end end |