From 2bba8c5feeee27bb9de20cdfd7a6343af40f3739 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Sat, 12 Jun 2010 17:59:50 +0200 Subject: [PATCH] first commit --- MIT-LICENSE | 20 + README | 40 + Rakefile | 23 + init.rb | 4 + install.rb | 1 + lib/cfpropertylist/LICENSE | 19 + lib/cfpropertylist/README | 34 + .../doc/classes/CFFormatError.html | 117 +++ .../doc/classes/CFPropertyList.html | 210 ++++++ .../classes/CFPropertyList.src/M000001.html | 51 ++ .../classes/CFPropertyList.src/M000002.html | 41 + .../doc/classes/CFPropertyList/Binary.html | 710 ++++++++++++++++++ .../CFPropertyList/Binary.src/M000018.html | 64 ++ .../CFPropertyList/Binary.src/M000019.html | 65 ++ .../CFPropertyList/Binary.src/M000020.html | 25 + .../CFPropertyList/Binary.src/M000021.html | 40 + .../CFPropertyList/Binary.src/M000022.html | 37 + .../CFPropertyList/Binary.src/M000023.html | 37 + .../CFPropertyList/Binary.src/M000024.html | 20 + .../CFPropertyList/Binary.src/M000025.html | 22 + .../CFPropertyList/Binary.src/M000026.html | 19 + .../CFPropertyList/Binary.src/M000027.html | 21 + .../CFPropertyList/Binary.src/M000028.html | 24 + .../CFPropertyList/Binary.src/M000029.html | 32 + .../CFPropertyList/Binary.src/M000030.html | 37 + .../CFPropertyList/Binary.src/M000031.html | 54 ++ .../CFPropertyList/Binary.src/M000032.html | 20 + .../CFPropertyList/Binary.src/M000033.html | 24 + .../CFPropertyList/Binary.src/M000034.html | 25 + .../CFPropertyList/Binary.src/M000035.html | 25 + .../CFPropertyList/Binary.src/M000036.html | 25 + .../CFPropertyList/Binary.src/M000037.html | 28 + .../CFPropertyList/Binary.src/M000038.html | 27 + .../CFPropertyList/Binary.src/M000039.html | 86 +++ .../CFPropertyList/Binary.src/M000040.html | 25 + .../CFPropertyList/Binary.src/M000041.html | 48 ++ .../CFPropertyList/Binary.src/M000042.html | 44 ++ .../CFPropertyList/Binary.src/M000043.html | 20 + .../CFPropertyList/Binary.src/M000044.html | 29 + .../CFPropertyList/Binary.src/M000045.html | 26 + .../CFPropertyList/Binary.src/M000046.html | 22 + .../CFPropertyList/Binary.src/M000047.html | 24 + .../CFPropertyList/Binary.src/M000048.html | 28 + .../CFPropertyList/Binary.src/M000049.html | 34 + .../doc/classes/CFPropertyList/CFArray.html | 187 +++++ .../CFPropertyList/CFArray.src/M000010.html | 18 + .../CFPropertyList/CFArray.src/M000011.html | 24 + .../CFPropertyList/CFArray.src/M000012.html | 18 + .../doc/classes/CFPropertyList/CFBoolean.html | 166 ++++ .../CFPropertyList/CFBoolean.src/M000065.html | 18 + .../CFPropertyList/CFBoolean.src/M000066.html | 18 + .../doc/classes/CFPropertyList/CFData.html | 232 ++++++ .../CFPropertyList/CFData.src/M000052.html | 22 + .../CFPropertyList/CFData.src/M000053.html | 18 + .../CFPropertyList/CFData.src/M000054.html | 18 + .../CFPropertyList/CFData.src/M000055.html | 18 + .../doc/classes/CFPropertyList/CFDate.html | 285 +++++++ .../CFPropertyList/CFDate.src/M000071.html | 19 + .../CFPropertyList/CFDate.src/M000072.html | 21 + .../CFPropertyList/CFDate.src/M000073.html | 22 + .../CFPropertyList/CFDate.src/M000074.html | 22 + .../CFPropertyList/CFDate.src/M000075.html | 22 + .../CFPropertyList/CFDate.src/M000076.html | 18 + .../CFPropertyList/CFDate.src/M000077.html | 18 + .../classes/CFPropertyList/CFDictionary.html | 186 +++++ .../CFDictionary.src/M000013.html | 18 + .../CFDictionary.src/M000014.html | 26 + .../CFDictionary.src/M000015.html | 18 + .../doc/classes/CFPropertyList/CFInteger.html | 166 ++++ .../CFPropertyList/CFInteger.src/M000067.html | 18 + .../CFPropertyList/CFInteger.src/M000068.html | 18 + .../doc/classes/CFPropertyList/CFReal.html | 166 ++++ .../CFPropertyList/CFReal.src/M000016.html | 18 + .../CFPropertyList/CFReal.src/M000017.html | 18 + .../doc/classes/CFPropertyList/CFString.html | 167 ++++ .../CFPropertyList/CFString.src/M000069.html | 20 + .../CFPropertyList/CFString.src/M000070.html | 18 + .../doc/classes/CFPropertyList/CFType.html | 201 +++++ .../CFPropertyList/CFType.src/M000003.html | 18 + .../CFPropertyList/CFType.src/M000004.html | 17 + .../CFPropertyList/CFType.src/M000005.html | 17 + .../doc/classes/CFPropertyList/List.html | 412 ++++++++++ .../CFPropertyList/List.src/M000056.html | 23 + .../CFPropertyList/List.src/M000057.html | 18 + .../CFPropertyList/List.src/M000058.html | 18 + .../CFPropertyList/List.src/M000059.html | 18 + .../CFPropertyList/List.src/M000060.html | 18 + .../CFPropertyList/List.src/M000061.html | 40 + .../CFPropertyList/List.src/M000062.html | 43 ++ .../CFPropertyList/List.src/M000063.html | 36 + .../CFPropertyList/List.src/M000064.html | 20 + .../CFPropertyList/ParserInterface.html | 164 ++++ .../ParserInterface.src/M000050.html | 18 + .../ParserInterface.src/M000051.html | 18 + .../doc/classes/CFPropertyList/XML.html | 218 ++++++ .../CFPropertyList/XML.src/M000006.html | 25 + .../CFPropertyList/XML.src/M000007.html | 40 + .../CFPropertyList/XML.src/M000008.html | 19 + .../CFPropertyList/XML.src/M000009.html | 69 ++ lib/cfpropertylist/doc/created.rid | 1 + .../doc/files/rbBinaryCFPropertyList_rb.html | 120 +++ .../doc/files/rbCFFormatError_rb.html | 118 +++ .../doc/files/rbCFPropertyList_rb.html | 157 ++++ .../doc/files/rbCFTypes_rb.html | 125 +++ .../doc/files/rbXMLCFPropertyList_rb.html | 120 +++ lib/cfpropertylist/doc/fr_class_index.html | 41 + lib/cfpropertylist/doc/fr_file_index.html | 31 + lib/cfpropertylist/doc/fr_method_index.html | 103 +++ lib/cfpropertylist/doc/index.html | 24 + lib/cfpropertylist/doc/rdoc-style.css | 208 +++++ lib/cfpropertylist/example.plist | Bin 0 -> 152 bytes lib/cfpropertylist/rbBinaryCFPropertyList.rb | 669 +++++++++++++++++ lib/cfpropertylist/rbCFFormatError.rb | 14 + lib/cfpropertylist/rbCFPropertyList.rb | 288 +++++++ lib/cfpropertylist/rbCFTypes.rb | 233 ++++++ lib/cfpropertylist/rbXMLCFPropertyList.rb | 121 +++ lib/plistifier/plist_encoding.rb | 115 +++ lib/rails_extensions.rb | 47 ++ tasks/plistifier_tasks.rake | 4 + test/plistifier_test.rb | 8 + test/test_helper.rb | 3 + uninstall.rb | 1 + 122 files changed, 8389 insertions(+) create mode 100644 MIT-LICENSE create mode 100644 README create mode 100644 Rakefile create mode 100644 init.rb create mode 100644 install.rb create mode 100644 lib/cfpropertylist/LICENSE create mode 100644 lib/cfpropertylist/README create mode 100644 lib/cfpropertylist/doc/classes/CFFormatError.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList.src/M000001.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList.src/M000002.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000018.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000019.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000020.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000021.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000022.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000023.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000024.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000025.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000026.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000027.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000028.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000029.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000030.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000031.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000032.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000033.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000034.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000035.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000036.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000037.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000038.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000039.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000040.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000041.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000042.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000043.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000044.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000045.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000046.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000047.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000048.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000049.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000010.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000011.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000012.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000065.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000066.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFData.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000052.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000053.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000054.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000055.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000071.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000072.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000073.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000074.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000075.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000076.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000077.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000013.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000014.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000015.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000067.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000068.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000016.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000017.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFString.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000069.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000070.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFType.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000003.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000004.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000005.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000056.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000057.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000058.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000059.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000060.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000061.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000062.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000063.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000064.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000050.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000051.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/XML.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000006.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000007.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000008.html create mode 100644 lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000009.html create mode 100644 lib/cfpropertylist/doc/created.rid create mode 100644 lib/cfpropertylist/doc/files/rbBinaryCFPropertyList_rb.html create mode 100644 lib/cfpropertylist/doc/files/rbCFFormatError_rb.html create mode 100644 lib/cfpropertylist/doc/files/rbCFPropertyList_rb.html create mode 100644 lib/cfpropertylist/doc/files/rbCFTypes_rb.html create mode 100644 lib/cfpropertylist/doc/files/rbXMLCFPropertyList_rb.html create mode 100644 lib/cfpropertylist/doc/fr_class_index.html create mode 100644 lib/cfpropertylist/doc/fr_file_index.html create mode 100644 lib/cfpropertylist/doc/fr_method_index.html create mode 100644 lib/cfpropertylist/doc/index.html create mode 100644 lib/cfpropertylist/doc/rdoc-style.css create mode 100644 lib/cfpropertylist/example.plist create mode 100644 lib/cfpropertylist/rbBinaryCFPropertyList.rb create mode 100644 lib/cfpropertylist/rbCFFormatError.rb create mode 100644 lib/cfpropertylist/rbCFPropertyList.rb create mode 100644 lib/cfpropertylist/rbCFTypes.rb create mode 100644 lib/cfpropertylist/rbXMLCFPropertyList.rb create mode 100644 lib/plistifier/plist_encoding.rb create mode 100644 lib/rails_extensions.rb create mode 100644 tasks/plistifier_tasks.rake create mode 100644 test/plistifier_test.rb create mode 100644 test/test_helper.rb create mode 100644 uninstall.rb diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..ec4ddd4 --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2010 [name of plugin creator] + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README b/README new file mode 100644 index 0000000..cd1a548 --- /dev/null +++ b/README @@ -0,0 +1,40 @@ +Plistifier +========== + +Adds the ActiveRecord#to_plist and Array#to_plist methods similar to ActiveRecord#to_xml. +The :only, :except, :methods, and :include options are supported. + +It too ads the :plist option to the ActiveRecord::Base#render method + +Example +======= + + def index + @posts = Post.all + + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @posts } + format.plist { render :plist => @posts, :only => [:id, :title] } + end + end + + def show + @post = Post.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @post } + format.plist { render :plist => @post } + end + end + + +Thanks +====== + +This plugin uses Christian Kruses CFPropertyList http://rubyforge.org/projects/cfpropertylist/ +to generate Plists. + + +Copyright (c) 2010 Jeena Paradies, released under the MIT license diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..65f7d75 --- /dev/null +++ b/Rakefile @@ -0,0 +1,23 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the plistifier plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the plistifier plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'Plistifier' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/init.rb b/init.rb new file mode 100644 index 0000000..575a517 --- /dev/null +++ b/init.rb @@ -0,0 +1,4 @@ +require 'plistifier/plist_encoding' +require 'rails_extensions' + +Mime::Type.register "application/plist", :plist \ No newline at end of file diff --git a/install.rb b/install.rb new file mode 100644 index 0000000..f7732d3 --- /dev/null +++ b/install.rb @@ -0,0 +1 @@ +# Install hook code here diff --git a/lib/cfpropertylist/LICENSE b/lib/cfpropertylist/LICENSE new file mode 100644 index 0000000..ba6ffb2 --- /dev/null +++ b/lib/cfpropertylist/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Christian Kruse, + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/lib/cfpropertylist/README b/lib/cfpropertylist/README new file mode 100644 index 0000000..156ffbe --- /dev/null +++ b/lib/cfpropertylist/README @@ -0,0 +1,34 @@ +CFPropertyList implementation +class to read, manipulate and write both XML and binary property list +files (plist(5)) as defined by Apple + +== Example + + # create a arbitrary data structure of basic data types + data = { + 'name' => 'John Doe', + 'missing' => true, + 'last_seen' => Time.now, + 'friends' => ['Jane Doe','Julian Doe'], + 'likes' => { + 'me' => false + } + } + + # create CFPropertyList::List object + plist = CFPropertyList::List.new + + # call CFPropertyList.guess() to create corresponding CFType values + plist.value = CFPropertyList.guess(data) + + # write plist to file + plist.save("example.plist", CFPropertyList::List::FORMAT_BINARY) + + # … later, read it again + plist = CFPropertyList::List.new("example.plist") + data = CFPropertyList.native_types(plist.value) + +Author:: Christian Kruse (mailto:cjk@wwwtech.de) +Copyright:: Copyright (c) 2010 +License:: Distributes under the same terms as Ruby + diff --git a/lib/cfpropertylist/doc/classes/CFFormatError.html b/lib/cfpropertylist/doc/classes/CFFormatError.html new file mode 100644 index 0000000..9915ad4 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFFormatError.html @@ -0,0 +1,117 @@ + + + + + + Class: CFFormatError + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFFormatError
In: + + rbCFFormatError.rb + +
+
Parent: + Exception +
+
+ + +
+ + + +
+ +
+

+Exception thrown when format errors occur +

+ +
+ + +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList.html b/lib/cfpropertylist/doc/classes/CFPropertyList.html new file mode 100644 index 0000000..64eb131 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList.html @@ -0,0 +1,210 @@ + + + + + + Module: CFPropertyList + + + + + + + + + + + + + +
+ + + +
+ +
+

+CFPropertyList implementation parser +class to read, manipulate and write XML property list files (plist(5)) as +defined by Apple +

+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2010 + +
License:Distributes under the same terms as Ruby + +
+ +
+ + +
+ +
+

Methods

+ +
+ guess   + native_types   +
+
+ +
+ + + + +
+ + + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+Create CFType hierarchy by +guessing the correct CFType, e.g. +

+
+ x = {
+   'a' => ['b','c','d']
+ }
+ cftypes = CFPropertyList.guess(x)
+
+
+
+ +
+ + + + +
+

+Converts a CFType hiercharchy to +native Ruby types +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000001.html b/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000001.html new file mode 100644 index 0000000..09b5c21 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000001.html @@ -0,0 +1,51 @@ + + + + + + guess (CFPropertyList) + + + + +
# File rbCFPropertyList.rb, line 72
+  def guess(object, options = {})
+    return if object.nil?
+
+    if(object.is_a?(Fixnum) || object.is_a?(Integer)) then
+      return CFInteger.new(object)
+    elsif(object.is_a?(Float)) then
+      return CFReal.new(object)
+    elsif(object.is_a?(TrueClass) || object.is_a?(FalseClass)) then
+      return CFBoolean.new(object)
+    elsif(object.is_a?(String)) then
+      return CFString.new(object)
+    elsif(object.is_a?(Time) || object.is_a?(DateTime)) then
+      return CFDate.new(object)
+    elsif(object.is_a?(IO)) then
+      return CFData.new(object.read, CFData::DATA_RAW)
+    elsif(object.is_a?(Array)) then
+      ary = Array.new
+      object.each do
+        |o|
+        ary.push CFPropertyList.guess(o, options)
+      end
+
+      return CFArray.new(ary)
+    elsif(object.is_a?(Hash)) then
+      hsh = Hash.new
+      object.each_pair do
+        |k,v|
+        k = k.to_s if k.is_a?(Symbol)
+        hsh[k] = CFPropertyList.guess(v, options)
+      end
+
+      return CFDictionary.new(hsh)
+    elsif options[:convert_unknown_to_string]
+      return CFString.new(object.to_s)
+    end
+  end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000002.html b/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000002.html new file mode 100644 index 0000000..3e51dd2 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList.src/M000002.html @@ -0,0 +1,41 @@ + + + + + + native_types (CFPropertyList) + + + + +
# File rbCFPropertyList.rb, line 110
+  def native_types(object,keys_as_symbols=false)
+    return if object.nil?
+
+    if(object.is_a?(CFDate) || object.is_a?(CFString) || object.is_a?(CFInteger) || object.is_a?(CFReal) || object.is_a?(CFBoolean)) then
+      return object.value
+    elsif(object.is_a?(CFData)) then
+      return object.decoded_value
+    elsif(object.is_a?(CFArray)) then
+      ary = []
+      object.value.each do
+        |v|
+        ary.push CFPropertyList.native_types(v)
+      end
+
+      return ary
+    elsif(object.is_a?(CFDictionary)) then
+      hsh = {}
+      object.value.each_pair do
+        |k,v|
+        k = k.to_sym if keys_as_symbols
+        hsh[k] = CFPropertyList.native_types(v)
+      end
+
+      return hsh
+    end
+  end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.html new file mode 100644 index 0000000..34a259e --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.html @@ -0,0 +1,710 @@ + + + + + + Class: CFPropertyList::Binary + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::Binary
In: + + rbBinaryCFPropertyList.rb + +
+
Parent: + Object +
+
+ + + + + + + +
+ + + + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+Counts the number of bytes the string will have when coded; utf-16be if +non-ascii characters are present. +

+
+
+ +
+ + + + +
+

+Calculate the byte needed for a „normal” integer value +

+
+
+ +
+ + + + +
+

+calculate how many bytes are needed to save count +

+
+
+ +
+ + + + +
+

+calculate the bytes needed for a size integer value +

+
+
+ +
+ + + + +
+

+Convert the given string from one charset to another +

+
+
+ +
+ + + + +
+

+Count characters considering character set +

+
+
+ +
+ + + + +
+

+create integer bytes of int +

+
+
+ +
+ + + + +
+

+pack an int of nbytes with size +

+
+
+ +
+ + + + +
+

+Create a type byte for binary format as defined by apple +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+Convert array to binary format and add it to the object table +

+
+
+ +
+ + + + +
+

+Convert a bool value to binary and add it to the object table +

+
+
+ +
+ + + + +
+

+Convert data value to binary format and add it to the object table +

+
+
+ +
+ + + + +
+

+Convert date value (apple format) to binary and adds it to the object table +

+
+
+ +
+ + + + +
+

+Convert dictionary to binary format and add it to the object table +

+
+
+ +
+ + + + +
+

+Codes an integer to binary format +

+
+
+ +
+ + + + +
+

+Read a binary plist file +

+
+
+ +
+ + + + +
+

+Converts a numeric value to binary and adds it to the object table +

+
+
+ +
+ + + + +
+

+Codes a real value to binary format +

+
+
+ +
+ + + + +
+

+Uniques and transforms a string value to binary format and adds it to the +object table +

+
+
+ +
+ + + + +
+

+Convert CFPropertyList to binary +format; since we have to count our objects we simply unique CFDictionary and CFArray +

+
+
+ +

Protected Instance methods

+ +
+ + + + +
+

+Read an binary array value, including contained objects +

+
+
+ +
+ + + + +
+

+Read a binary data value +

+
+
+ +
+ + + + +
+

+read a binary date value +

+
+
+ +
+ + + + +
+

+Read a dictionary value, including contained objects +

+
+
+ +
+ + + + +
+

+read a binary int value +

+
+
+ +
+ + + + +
+

+read a „null” type (i.e. null byte, marker byte, bool value) +

+
+
+ +
+ + + + +
+

+Read an object type byte, decode it and delegate to the correct reader +function +

+
+
+ +
+ + + + +
+

+Read an object type byte at position $pos, decode it and delegate to the +correct reader function +

+
+
+ +
+ + + + +
+

+read a binary real value +

+
+
+ +
+ + + + +
+

+Read a binary string value +

+
+
+ +
+ + + + +
+

+Read a unicode string value, coded as UTF-16BE +

+
+
+ +
+ + + + +
+

+„unique” and count values. „Unique” means, several objects (e.g. +strings) will only be saved once and referenced later +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000018.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000018.html new file mode 100644 index 0000000..48ccc8e --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000018.html @@ -0,0 +1,64 @@ + + + + + + load (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 13
+    def load(opts)
+      @unique_table = {}
+      @count_objects = 0
+      @string_size = 0
+      @int_size = 0
+      @misc_size = 0
+      @object_refs = 0
+
+      @written_object_count = 0
+      @object_table = []
+      @object_ref_size = 0
+
+      @offsets = []
+
+      fd = nil
+      if(opts.has_key?(:file)) then
+        fd = File.open(opts[:file],"rb")
+        file = opts[:file]
+      else
+        fd = StringIO.new(opts[:data],"rb")
+        file = "<string>"
+      end
+
+      # first, we read the trailer: 32 byte from the end
+      fd.seek(-32,IO::SEEK_END)
+      buff = fd.read(32)
+
+      offset_size, object_ref_size, number_of_objects, top_object, table_offset = buff.unpack "x6CCx4Nx4Nx4N"
+
+      # after that, get the offset table
+      fd.seek(table_offset, IO::SEEK_SET)
+      coded_offset_table = fd.read(number_of_objects * offset_size)
+      raise CFFormatError.new("#{file}: Format error!") unless coded_offset_table.bytesize == number_of_objects * offset_size
+
+      @count_objects = number_of_objects
+
+      # decode offset table
+      formats = ["","C*","n*","(H6)*","N*"]
+      @offsets = coded_offset_table.unpack(formats[offset_size])
+      if(offset_size == 3) then
+        0.upto(@offsets.count-1) { |i| @offsets[i] = @offsets[i].to_i(16) }
+      end
+
+      @object_ref_size = object_ref_size
+      val = read_binary_object_at(file,fd,top_object)
+
+      fd.close
+      return val
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000019.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000019.html new file mode 100644 index 0000000..4c04709 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000019.html @@ -0,0 +1,65 @@ + + + + + + to_str (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 65
+    def to_str(opts={})
+      @unique_table = {}
+      @count_objects = 0
+      @string_size = 0
+      @int_size = 0
+      @misc_size = 0
+      @object_refs = 0
+
+      @written_object_count = 0
+      @object_table = []
+      @object_ref_size = 0
+
+      @offsets = []
+
+      binary_str = "bplist00"
+      unique_and_count_values(opts[:root])
+
+      @count_objects += @unique_table.count
+      @object_ref_size = Binary.bytes_needed(@count_objects)
+
+      file_size = @string_size + @int_size + @misc_size + @object_refs * @object_ref_size + 40
+      offset_size = Binary.bytes_needed(file_size)
+      table_offset = file_size - 32
+
+      @object_table = []
+      @written_object_count = 0
+      @unique_table = {} # we needed it to calculate several values, but now we need an empty table
+
+      opts[:root].to_binary(self)
+
+      object_offset = 8
+      offsets = []
+
+      0.upto(@object_table.count-1) do |i|
+        binary_str += @object_table[i]
+        offsets[i] = object_offset
+        object_offset += @object_table[i].bytesize
+      end
+
+      offsets.each do |offset|
+        binary_str += Binary.pack_it_with_size(offset_size,offset)
+      end
+
+      binary_str += [offset_size, @object_ref_size].pack("x6CC")
+      binary_str += [@count_objects].pack("x4N")
+      binary_str += [0].pack("x4N")
+      binary_str += [table_offset].pack("x4N")
+
+      return binary_str
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000020.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000020.html new file mode 100644 index 0000000..0c56dfe --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000020.html @@ -0,0 +1,25 @@ + + + + + + read_binary_null_type (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 117
+    def read_binary_null_type(length)
+      case length
+      when 0 then return 0 # null byte
+      when 8 then return CFBoolean.new(false)
+      when 9 then return CFBoolean.new(true)
+      when 15 then return 15 # fill type
+      end
+
+      raise CFFormatError.new("unknown null type: #{length}")
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000021.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000021.html new file mode 100644 index 0000000..8292949 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000021.html @@ -0,0 +1,40 @@ + + + + + + read_binary_int (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 130
+    def read_binary_int(fname,fd,length)
+      raise CFFormatError.new("Integer greater than 8 bytes: #{length}") if length > 3
+
+      nbytes = 1 << length
+
+      val = nil
+      buff = fd.read(nbytes)
+
+      case length
+      when 0 then
+        val = buff.unpack("C")
+        val = val[0]
+      when 1 then
+        val = buff.unpack("n")
+        val = val[0]
+      when 2 then
+        val = buff.unpack("N")
+        val = val[0]
+      when 3
+        hiword,loword = buff.unpack("NN")
+        val = hiword << 32 | loword
+      end
+
+      return CFInteger.new(val);
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000022.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000022.html new file mode 100644 index 0000000..d831bd4 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000022.html @@ -0,0 +1,37 @@ + + + + + + read_binary_real (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 158
+    def read_binary_real(fname,fd,length)
+      raise CFFormatError.new("Real greater than 8 bytes: #{length}") if length > 3
+
+      nbytes = 1 << length
+      val = nil
+      buff = fd.read(nbytes)
+
+      case length
+      when 0 then # 1 byte float? must be an error
+        raise CFFormatError.new("got #{length+1} byte float, must be an error!")
+      when 1 then # 2 byte float? must be an error
+        raise CFFormatError.new("got #{length+1} byte float, must be an error!")
+      when 2 then
+        val = buff.reverse.unpack("f")
+        val = val[0]
+      when 3 then
+        val = buff.reverse.unpack("d")
+        val = val[0]
+      end
+
+      return CFReal.new(val)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000023.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000023.html new file mode 100644 index 0000000..79c6f22 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000023.html @@ -0,0 +1,37 @@ + + + + + + read_binary_date (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 183
+    def read_binary_date(fname,fd,length)
+      raise CFFormatError.new("Date greater than 8 bytes: #{length}") if length > 3
+
+      nbytes = 1 << length
+      val = nil
+      buff = fd.read(nbytes)
+
+      case length
+      when 0 then # 1 byte CFDate is an error
+        raise CFFormatError.new("#{length+1} byte CFDate, error")
+      when 1 then # 2 byte CFDate is an error
+        raise CFFormatError.new("#{length+1} byte CFDate, error")
+      when 2 then
+        val = buff.reverse.unpack("f")
+        val = val[0]
+      when 3 then
+        val = buff.reverse.unpack("d")
+        val = val[0]
+      end
+
+      return CFDate.new(val,CFDate::TIMESTAMP_APPLE)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000024.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000024.html new file mode 100644 index 0000000..f6ada03 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000024.html @@ -0,0 +1,20 @@ + + + + + + read_binary_data (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 208
+    def read_binary_data(fname,fd,length)
+      buff = "";
+      buff = fd.read(length) if length > 0
+      return CFData.new(buff,CFData::DATA_RAW)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000025.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000025.html new file mode 100644 index 0000000..c1210ea --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000025.html @@ -0,0 +1,22 @@ + + + + + + read_binary_string (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 216
+    def read_binary_string(fname,fd,length)
+      buff = ""
+      buff = fd.read(length) if length > 0
+
+      @unique_table[buff] = true unless @unique_table.has_key?(buff)
+      return CFString.new(buff)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000026.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000026.html new file mode 100644 index 0000000..84071ea --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000026.html @@ -0,0 +1,19 @@ + + + + + + charset_convert (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 226
+    def Binary.charset_convert(str,from,to="UTF-8")
+      return str.clone.force_encoding(from).encode(to) if str.respond_to?("encode")
+      return Iconv.conv(to,from,str)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000027.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000027.html new file mode 100644 index 0000000..c1cbfd0 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000027.html @@ -0,0 +1,21 @@ + + + + + + charset_strlen (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 232
+    def Binary.charset_strlen(str,charset="UTF-8")
+      return str.length if str.respond_to?("encode")
+
+      str = Iconv.conv("UTF-8",charset,str) if charset != "UTF-8"
+      return str.scan(/./mu).size
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000028.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000028.html new file mode 100644 index 0000000..8d1ce7c --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000028.html @@ -0,0 +1,24 @@ + + + + + + read_binary_unicode_string (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 240
+    def read_binary_unicode_string(fname,fd,length)
+      # The problem is: we get the length of the string IN CHARACTERS;
+      # since a char in UTF-16 can be 16 or 32 bit long, we don't really know
+      # how long the string is in bytes
+      buff = fd.read(2*length)
+
+      @unique_table[buff] = true unless @unique_table.has_key?(buff)
+      return CFString.new(Binary.charset_convert(buff,"UTF-16BE","UTF-8"))
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000029.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000029.html new file mode 100644 index 0000000..4dd33e6 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000029.html @@ -0,0 +1,32 @@ + + + + + + read_binary_array (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 252
+    def read_binary_array(fname,fd,length)
+      ary = []
+
+      # first: read object refs
+      if(length != 0) then
+        buff = fd.read(length * @object_ref_size)
+        objects = buff.unpack(@object_ref_size == 1 ? "C*" : "n*")
+
+        # now: read objects
+        0.upto(length-1) do |i|
+          object = read_binary_object_at(fname,fd,objects[i])
+          ary.push object
+        end
+      end
+
+      return CFArray.new(ary)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000030.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000030.html new file mode 100644 index 0000000..e16589f --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000030.html @@ -0,0 +1,37 @@ + + + + + + read_binary_dict (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 272
+    def read_binary_dict(fname,fd,length)
+      dict = {}
+
+      # first: read keys
+      if(length != 0) then
+        buff = fd.read(length * @object_ref_size)
+        keys = buff.unpack(@object_ref_size == 1 ? "C*" : "n*")
+
+        # second: read object refs
+        buff = fd.read(length * @object_ref_size)
+        objects = buff.unpack(@object_ref_size == 1 ? "C*" : "n*")
+
+        # read real keys and objects
+        0.upto(length-1) do |i|
+          key = read_binary_object_at(fname,fd,keys[i])
+          object = read_binary_object_at(fname,fd,objects[i])
+          dict[key.value] = object
+        end
+      end
+
+      return CFDictionary.new(dict)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000031.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000031.html new file mode 100644 index 0000000..46e87a5 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000031.html @@ -0,0 +1,54 @@ + + + + + + read_binary_object (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 297
+    def read_binary_object(fname,fd)
+      # first: read the marker byte
+      buff = fd.read(1)
+
+      object_length = buff.unpack("C*")
+      object_length = object_length[0]  & 0xF
+
+      buff = buff.unpack("H*")
+      object_type = buff[0][0].chr
+
+      if(object_type != "0" && object_length == 15) then
+        object_length = read_binary_object(fname,fd)
+        object_length = object_length.value
+      end
+
+      retval = nil
+      case object_type
+      when '0' then # null, false, true, fillbyte
+        retval = read_binary_null_type(object_length)
+      when '1' then # integer
+        retval = read_binary_int(fname,fd,object_length)
+      when '2' then # real
+        retval = read_binary_real(fname,fd,object_length)
+      when '3' then # date
+        retval = read_binary_date(fname,fd,object_length)
+      when '4' then # data
+        retval = read_binary_data(fname,fd,object_length)
+      when '5' then # byte string, usually utf8 encoded
+        retval = read_binary_string(fname,fd,object_length)
+      when '6' then # unicode string (utf16be)
+        retval = read_binary_unicode_string(fname,fd,object_length)
+      when 'a' then # array
+        retval = read_binary_array(fname,fd,object_length)
+      when 'd' then # dictionary
+        retval = read_binary_dict(fname,fd,object_length)
+      end
+
+      return retval
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000032.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000032.html new file mode 100644 index 0000000..e102a02 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000032.html @@ -0,0 +1,20 @@ + + + + + + read_binary_object_at (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 339
+    def read_binary_object_at(fname,fd,pos)
+      position = @offsets[pos]
+      fd.seek(position,IO::SEEK_SET)
+      return read_binary_object(fname,fd)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000033.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000033.html new file mode 100644 index 0000000..dba7567 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000033.html @@ -0,0 +1,24 @@ + + + + + + bytes_size_int (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 347
+    def Binary.bytes_size_int(int)
+      nbytes = 0
+
+      nbytes += 2 if int > 0xE # 2 bytes int
+      nbytes += 2 if int > 0xFF # 3 bytes int
+      nbytes += 2 if int > 0xFFFF # 5 bytes int
+
+      return nbytes
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000034.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000034.html new file mode 100644 index 0000000..0d9e2f0 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000034.html @@ -0,0 +1,25 @@ + + + + + + bytes_int (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 358
+    def Binary.bytes_int(int)
+      nbytes = 1
+
+      nbytes += 1 if int > 0xFF # 2 byte int
+      nbytes += 2 if int > 0xFFFF # 4 byte int
+      nbytes += 4 if int > 0xFFFFFFFF # 8 byte int
+      nbytes += 7 if int < 0 # 8 byte int (since it is signed)
+
+      return nbytes + 1 # one „marker” byte
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000035.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000035.html new file mode 100644 index 0000000..a0c4130 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000035.html @@ -0,0 +1,25 @@ + + + + + + pack_it_with_size (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 370
+    def Binary.pack_it_with_size(nbytes,int)
+      format = ["C", "n", "N", "N"][nbytes-1]
+
+      if(nbytes == 3) then
+        val = [int].pack(format)
+        return val.slice(-3)
+      end
+
+      return [int].pack(format)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000036.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000036.html new file mode 100644 index 0000000..bcb14bd --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000036.html @@ -0,0 +1,25 @@ + + + + + + bytes_needed (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 382
+    def Binary.bytes_needed(count)
+      nbytes = 0
+
+      while count >= 1 do
+        nbytes += 1
+        count /= 256
+      end
+
+      return nbytes
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000037.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000037.html new file mode 100644 index 0000000..f8452ad --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000037.html @@ -0,0 +1,28 @@ + + + + + + int_bytes (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 394
+    def Binary.int_bytes(int)
+      intbytes = ""
+
+      if(int > 0xFFFF) then
+        intbytes = "\x12"+[int].pack("N") # 4 byte integer
+      elsif(int > 0xFF) then
+        intbytes = "\x11"+[int].pack("n") # 2 byte integer
+      else
+        intbytes = "\x10"+[int].pack("C") # 8 byte integer
+      end
+
+      return intbytes;
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000038.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000038.html new file mode 100644 index 0000000..07582cd --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000038.html @@ -0,0 +1,27 @@ + + + + + + type_bytes (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 409
+    def Binary.type_bytes(type,type_len)
+      optional_int = ""
+
+      if(type_len < 15) then
+        type += sprintf("%x",type_len)
+      else
+        type += "f"
+        optional_int = Binary.int_bytes(type_len)
+      end
+
+      return [type].pack("H*") + optional_int
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000039.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000039.html new file mode 100644 index 0000000..8e17b6c --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000039.html @@ -0,0 +1,86 @@ + + + + + + unique_and_count_values (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 424
+    def unique_and_count_values(value)
+      # no uniquing for other types than CFString and CFData
+      if(value.is_a?(CFInteger) || value.is_a?(CFReal)) then
+        val = value.value
+        if(value.is_a?(CFInteger)) then
+          @int_size += Binary.bytes_int(val)
+        else
+          @misc_size += 9 # 9 bytes (8 + marker byte) for real
+        end
+
+        @count_objects += 1
+        return
+      elsif(value.is_a?(CFDate)) then
+        @misc_size += 9
+        @count_objects += 1
+        return
+      elsif(value.is_a?(CFBoolean)) then
+        @count_objects += 1
+        @misc_size += 1
+        return
+      elsif(value.is_a?(CFArray)) then
+        cnt = 0
+
+        value.value.each do |v|
+          cnt += 1
+          unique_and_count_values(v)
+          @object_refs += 1 # each array member is a ref
+        end
+
+        @count_objects += 1
+        @int_size += Binary.bytes_size_int(cnt)
+        @misc_size += 1 # marker byte for array
+        return
+      elsif(value.is_a?(CFDictionary)) then
+        cnt = 0
+
+        value.value.each_pair do |k,v|
+          cnt += 1
+
+          if(!@unique_table.has_key?(k))
+            @unique_table[k] = 0
+            @string_size += Binary.binary_strlen(k) + 1
+            @int_size += Binary.bytes_size_int(Binary.charset_strlen(k,'UTF-8'))
+          end
+
+          @object_refs += 2 # both, key and value, are refs
+          @unique_table[k] += 1
+          unique_and_count_values(v)
+        end
+
+        @count_objects += 1
+        @misc_size += 1 # marker byte for dict
+        @int_size += Binary.bytes_size_int(cnt)
+        return
+      elsif(value.is_a?(CFData)) then
+        val = value.decoded_value
+        @int_size += Binary.bytes_size_int(val.length)
+        @misc_size += val.length
+        @count_objects += 1
+        return
+      end
+
+      val = value.value
+      if(!@unique_table.has_key?(val)) then
+        @unique_table[val] = 0
+        @string_size += Binary.binary_strlen(val) + 1
+        @int_size += Binary.bytes_size_int(Binary.charset_strlen(val,'UTF-8'))
+      end
+
+      @unique_table[val] += 1
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000040.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000040.html new file mode 100644 index 0000000..b2e80bb --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000040.html @@ -0,0 +1,25 @@ + + + + + + binary_strlen (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 498
+    def Binary.binary_strlen(val)
+      val.each_byte do |b|
+        if(b > 127) then
+          val = Binary.charset_convert(val, 'UTF-8', 'UTF-16BE')
+          return val.bytesize
+        end
+      end
+
+      return val.bytesize
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000041.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000041.html new file mode 100644 index 0000000..558b438 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000041.html @@ -0,0 +1,48 @@ + + + + + + string_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 510
+    def string_to_binary(val)
+      saved_object_count = -1
+
+      unless(@unique_table.has_key?(val)) then
+        saved_object_count = @written_object_count
+        @written_object_count += 1
+
+        @unique_table[val] = saved_object_count
+        utf16 = false
+
+        val.each_byte do |b|
+          if(b > 127) then
+            utf16 = true
+            break
+          end
+        end
+
+        if(utf16) then
+          bdata = Binary.type_bytes("6",Binary.charset_strlen(val,"UTF-8")) # 6 is 0110, unicode string (utf16be)
+          val = Binary.charset_convert(val,"UTF-8","UTF-16BE")
+
+          val.force_encoding("ASCII-8BIT") if val.respond_to?("encode")
+          @object_table[saved_object_count] = bdata + val
+        else
+          bdata = Binary.type_bytes("5",val.bytesize) # 5 is 0101 which is an ASCII string (seems to be ASCII encoded)
+          @object_table[saved_object_count] = bdata + val
+        end
+      else
+        saved_object_count = @unique_table[val]
+      end
+
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000042.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000042.html new file mode 100644 index 0000000..a0bfcf1 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000042.html @@ -0,0 +1,44 @@ + + + + + + int_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 545
+    def int_to_binary(value)
+      nbytes = 0
+      nbytes = 1 if value > 0xFF # 1 byte integer
+      nbytes += 1 if value > 0xFFFF # 4 byte integer
+      nbytes += 1 if value > 0xFFFFFFFF # 8 byte integer
+      nbytes = 3 if value < 0 # 8 byte integer, since signed
+
+      bdata = Binary.type_bytes("1", nbytes) # 1 is 0001, type indicator for integer
+      buff = ""
+
+      if(nbytes < 3) then
+        fmt = "N"
+
+        if(nbytes == 0) then
+          fmt = "C"
+        elsif(nbytes == 1)
+          fmt = "n"
+        end
+
+        buff = [value].pack(fmt)
+      else
+        # 64 bit signed integer; we need the higher and the lower 32 bit of the value
+        high_word = value >> 32
+        low_word = value & 0xFFFFFFFF
+        buff = [high_word,low_word].pack("NN")
+      end
+
+      return bdata + buff
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000043.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000043.html new file mode 100644 index 0000000..3e89d06 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000043.html @@ -0,0 +1,20 @@ + + + + + + real_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 576
+    def real_to_binary(val)
+      bdata = Binary.type_bytes("2",3) # 2 is 0010, type indicator for reals
+      buff = [val].pack("d")
+      return bdata + buff.reverse
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000044.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000044.html new file mode 100644 index 0000000..1949222 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000044.html @@ -0,0 +1,29 @@ + + + + + + num_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 583
+    def num_to_binary(value)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      val = ""
+      if(value.is_a?(CFInteger)) then
+        val = int_to_binary(value.value)
+      else
+        val = real_to_binary(value.value)
+      end
+
+      @object_table[saved_object_count] = val
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000045.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000045.html new file mode 100644 index 0000000..ab0d87c --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000045.html @@ -0,0 +1,26 @@ + + + + + + date_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 599
+    def date_to_binary(val)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      val = val.getutc.to_f - CFDate::DATE_DIFF_APPLE_UNIX # CFDate is a real, number of seconds since 01/01/2001 00:00:00 GMT
+
+      bdata = Binary.type_bytes("3", 3) # 3 is 0011, type indicator for date
+      @object_table[saved_object_count] = bdata + [val].pack("d").reverse
+
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000046.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000046.html new file mode 100644 index 0000000..94e0665 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000046.html @@ -0,0 +1,22 @@ + + + + + + bool_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 612
+    def bool_to_binary(val)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      @object_table[saved_object_count] = val ? "\x9" : "\x8" # 0x9 is 1001, type indicator for true; 0x8 is 1000, type indicator for false
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000047.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000047.html new file mode 100644 index 0000000..eeeee04 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000047.html @@ -0,0 +1,24 @@ + + + + + + data_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 621
+    def data_to_binary(val)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      bdata = Binary.type_bytes("4", val.bytesize) # a is 1000, type indicator for data
+      @object_table[saved_object_count] = bdata + val
+
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000048.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000048.html new file mode 100644 index 0000000..4645651 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000048.html @@ -0,0 +1,28 @@ + + + + + + array_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 632
+    def array_to_binary(val)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      bdata = Binary.type_bytes("a", val.value.count) # a is 1010, type indicator for arrays
+
+      val.value.each do |v|
+        bdata += Binary.pack_it_with_size(@object_ref_size,  v.to_binary(self));
+      end
+
+      @object_table[saved_object_count] = bdata
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000049.html b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000049.html new file mode 100644 index 0000000..fb49926 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/Binary.src/M000049.html @@ -0,0 +1,34 @@ + + + + + + dict_to_binary (CFPropertyList::Binary) + + + + +
# File rbBinaryCFPropertyList.rb, line 647
+    def dict_to_binary(val)
+      saved_object_count = @written_object_count
+      @written_object_count += 1
+
+      bdata = Binary.type_bytes("d",val.value.count) # d=1101, type indicator for dictionary
+
+      val.value.each_key do |k|
+        str = CFString.new(k)
+        key = str.to_binary(self)
+        bdata += Binary.pack_it_with_size(@object_ref_size,key)
+      end
+
+      val.value.each_value do |v|
+        bdata += Binary.pack_it_with_size(@object_ref_size,v.to_binary(self))
+      end
+
+      @object_table[saved_object_count] = bdata
+      return saved_object_count
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.html new file mode 100644 index 0000000..4f33d08 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.html @@ -0,0 +1,187 @@ + + + + + + Class: CFPropertyList::CFArray + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFArray
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class contains an array of values +

+ +
+ + +
+ +
+

Methods

+ +
+ new   + to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+create a new array CFType +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000010.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000010.html new file mode 100644 index 0000000..82e7707 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000010.html @@ -0,0 +1,18 @@ + + + + + + new (CFPropertyList::CFArray) + + + + +
# File rbCFTypes.rb, line 185
+    def initialize(val=[])
+      @value = val
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000011.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000011.html new file mode 100644 index 0000000..3b4acc0 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000011.html @@ -0,0 +1,24 @@ + + + + + + to_xml (CFPropertyList::CFArray) + + + + +
# File rbCFTypes.rb, line 190
+    def to_xml
+      n = LibXML::XML::Node.new('array')
+      @value.each do
+        |v|
+        n << v.to_xml
+      end
+
+      return n
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000012.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000012.html new file mode 100644 index 0000000..93b09cd --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFArray.src/M000012.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFArray) + + + + +
# File rbCFTypes.rb, line 201
+    def to_binary(bplist)
+      return bplist.array_to_binary(self)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.html new file mode 100644 index 0000000..e6c4155 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.html @@ -0,0 +1,166 @@ + + + + + + Class: CFPropertyList::CFBoolean + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFBoolean
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class contains a boolean value +

+ +
+ + +
+ +
+

Methods

+ +
+ to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000065.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000065.html new file mode 100644 index 0000000..447a870 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000065.html @@ -0,0 +1,18 @@ + + + + + + to_xml (CFPropertyList::CFBoolean) + + + + +
# File rbCFTypes.rb, line 140
+    def to_xml
+      return LibXML::XML::Node.new(@value ? 'true' : 'false')
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000066.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000066.html new file mode 100644 index 0000000..5171b28 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFBoolean.src/M000066.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFBoolean) + + + + +
# File rbCFTypes.rb, line 145
+    def to_binary(bplist)
+      return bplist.bool_to_binary(@value);
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.html new file mode 100644 index 0000000..70fb7b4 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.html @@ -0,0 +1,232 @@ + + + + + + Class: CFPropertyList::CFData + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFData
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class contains binary data values +

+ +
+ + +
+ +
+

Methods

+ +
+ decoded_value   + new   + to_binary   + to_xml   +
+
+ +
+ + + + +
+ + +
+

Constants

+ +
+ + + + + + + + + + + + + + + +
DATA_BASE64=0  +Base64 encoded data + +
DATA_RAW=1  +Raw data + +
+
+
+ + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+set value to defined state, either base64 encoded or raw +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+get base64 decoded value +

+
+
+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000052.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000052.html new file mode 100644 index 0000000..4af4429 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000052.html @@ -0,0 +1,22 @@ + + + + + + new (CFPropertyList::CFData) + + + + +
# File rbCFTypes.rb, line 158
+    def initialize(value=nil,format=DATA_BASE64)
+      if(format == DATA_RAW) then
+        @value = Base64.encode64(value)
+      else
+        @value = value
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000053.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000053.html new file mode 100644 index 0000000..2c0962e --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000053.html @@ -0,0 +1,18 @@ + + + + + + decoded_value (CFPropertyList::CFData) + + + + +
# File rbCFTypes.rb, line 167
+    def decoded_value
+      return Base64.decode64(@value)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000054.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000054.html new file mode 100644 index 0000000..1427bd9 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000054.html @@ -0,0 +1,18 @@ + + + + + + to_xml (CFPropertyList::CFData) + + + + +
# File rbCFTypes.rb, line 172
+    def to_xml
+      return LibXML::XML::Node.new('data') << LibXML::XML::Node.new_text(@value)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000055.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000055.html new file mode 100644 index 0000000..e95dd8b --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFData.src/M000055.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFData) + + + + +
# File rbCFTypes.rb, line 177
+    def to_binary(bplist)
+      return bplist.data_to_binary(decoded_value())
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.html new file mode 100644 index 0000000..795063b --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.html @@ -0,0 +1,285 @@ + + + + + + Class: CFPropertyList::CFDate + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFDate
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class holds Time values. While Apple uses seconds since 2001, the rest +of the world uses seconds since 1970. So if you access value directly, you +get the Time class. If you access via get_value you either geht the timestamp or +the Apple timestamp +

+ +
+ + +
+ +
+

Methods

+ +
+ date_string   + get_value   + new   + parse_date   + set_value   + to_binary   + to_xml   +
+
+ +
+ + + + +
+ + +
+

Constants

+ +
+ + + + + + + + + + + + + + + + +
TIMESTAMP_APPLE=0
TIMESTAMP_UNIX=1;
DATE_DIFF_APPLE_UNIX=978307200
+
+
+ + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+create a XML date strimg from a time object +

+
+
+ +
+ + + + +
+

+set value to defined state +

+
+
+ +
+ + + + +
+

+parse a XML date string +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+get timestamp, either UNIX or Apple timestamp +

+
+
+ +
+ + + + +
+

+set value with timestamp, either Apple or UNIX +

+
+
+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000071.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000071.html new file mode 100644 index 0000000..aa5bfcf --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000071.html @@ -0,0 +1,19 @@ + + + + + + date_string (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 86
+    def CFDate.date_string(val)
+      # 2009-05-13T20:23:43Z
+      val.getutc.strftime("%Y-%m-%dT%H:%M:%SZ")
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000072.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000072.html new file mode 100644 index 0000000..42ba1b7 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000072.html @@ -0,0 +1,21 @@ + + + + + + parse_date (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 92
+    def CFDate.parse_date(val)
+      # 2009-05-13T20:23:43Z
+      val =~ %r{^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$}
+      year,month,day,hour,min,sec = $1, $2, $3, $4, $5, $6
+      return Time.utc(year,month,day,hour,min,sec).getlocal
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000073.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000073.html new file mode 100644 index 0000000..9572d86 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000073.html @@ -0,0 +1,22 @@ + + + + + + new (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 100
+    def initialize(value = nil,format=CFDate::TIMESTAMP_UNIX)
+      if(value.is_a?(Time) || value.nil?) then
+        @value = value.nil? ? Time.now : value
+      else
+        set_value(value,format)
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000074.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000074.html new file mode 100644 index 0000000..34ee540 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000074.html @@ -0,0 +1,22 @@ + + + + + + set_value (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 109
+    def set_value(value,format=CFDate::TIMESTAMP_UNIX)
+      if(format == CFDate::TIMESTAMP_UNIX) then
+        @value = Time.at(value)
+      else
+        @value = Time.at(value + CFDate::DATE_DIFF_APPLE_UNIX)
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000075.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000075.html new file mode 100644 index 0000000..53bf0b6 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000075.html @@ -0,0 +1,22 @@ + + + + + + get_value (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 118
+    def get_value(format=CFDate::TIMESTAMP_UNIX)
+      if(format == CFDate::TIMESTAMP_UNIX) then
+        return @value.to_i
+      else
+        return @value.to_f - CFDate::DATE_DIFF_APPLE_UNIX
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000076.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000076.html new file mode 100644 index 0000000..e10a76f --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000076.html @@ -0,0 +1,18 @@ + + + + + + to_xml (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 127
+    def to_xml
+      return LibXML::XML::Node.new('date') << LibXML::XML::Node.new_text(CFDate::date_string(@value))
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000077.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000077.html new file mode 100644 index 0000000..0a9898d --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDate.src/M000077.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFDate) + + + + +
# File rbCFTypes.rb, line 132
+    def to_binary(bplist)
+      return bplist.date_to_binary(@value)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.html new file mode 100644 index 0000000..8e9877d --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.html @@ -0,0 +1,186 @@ + + + + + + Class: CFPropertyList::CFDictionary + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFDictionary
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+this class contains a hash of values +

+ +
+ + +
+ +
+

Methods

+ +
+ new   + to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+Create new CFDictonary type. +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000013.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000013.html new file mode 100644 index 0000000..ec7e609 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000013.html @@ -0,0 +1,18 @@ + + + + + + new (CFPropertyList::CFDictionary) + + + + +
# File rbCFTypes.rb, line 209
+    def initialize(value={})
+      @value = value
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000014.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000014.html new file mode 100644 index 0000000..d976e89 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000014.html @@ -0,0 +1,26 @@ + + + + + + to_xml (CFPropertyList::CFDictionary) + + + + +
# File rbCFTypes.rb, line 214
+    def to_xml
+      n = LibXML::XML::Node.new('dict')
+      @value.each_pair do
+        |key,value|
+        k = LibXML::XML::Node.new('key') << LibXML::XML::Node.new_text(key)
+        n << k
+        n << value.to_xml
+      end
+
+      return n
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000015.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000015.html new file mode 100644 index 0000000..b570f5c --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFDictionary.src/M000015.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFDictionary) + + + + +
# File rbCFTypes.rb, line 227
+    def to_binary(bplist)
+      return bplist.dict_to_binary(self)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.html new file mode 100644 index 0000000..dec44a6 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.html @@ -0,0 +1,166 @@ + + + + + + Class: CFPropertyList::CFInteger + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFInteger
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class holds integer/fixnum values +

+ +
+ + +
+ +
+

Methods

+ +
+ to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000067.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000067.html new file mode 100644 index 0000000..874f333 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000067.html @@ -0,0 +1,18 @@ + + + + + + to_xml (CFPropertyList::CFInteger) + + + + +
# File rbCFTypes.rb, line 53
+    def to_xml
+      return LibXML::XML::Node.new('integer') << LibXML::XML::Node.new_text(@value.to_s)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000068.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000068.html new file mode 100644 index 0000000..7c15599 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFInteger.src/M000068.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFInteger) + + + + +
# File rbCFTypes.rb, line 58
+    def to_binary(bplist)
+      return bplist.num_to_binary(self)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.html new file mode 100644 index 0000000..fd8bb0a --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.html @@ -0,0 +1,166 @@ + + + + + + Class: CFPropertyList::CFReal + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFReal
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class holds float values +

+ +
+ + +
+ +
+

Methods

+ +
+ to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000016.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000016.html new file mode 100644 index 0000000..97b27e4 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000016.html @@ -0,0 +1,18 @@ + + + + + + to_xml (CFPropertyList::CFReal) + + + + +
# File rbCFTypes.rb, line 66
+    def to_xml
+      return LibXML::XML::Node.new('real') << LibXML::XML::Node.new_text(@value.to_s)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000017.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000017.html new file mode 100644 index 0000000..731b260 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFReal.src/M000017.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFReal) + + + + +
# File rbCFTypes.rb, line 71
+    def to_binary(bplist)
+      return bplist.num_to_binary(self)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.html new file mode 100644 index 0000000..bfa3462 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.html @@ -0,0 +1,167 @@ + + + + + + Class: CFPropertyList::CFString + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFString
In: + + rbCFTypes.rb + +
+
Parent: + + CFType + +
+
+ + +
+ + + +
+ +
+

+This class holds string values, both, UTF-8 and UTF-16BE It will convert +the value to UTF-16BE if necessary (i.e. if non-ascii char contained) +

+ +
+ + +
+ +
+

Methods

+ +
+ to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+convert to binary +

+
+
+ +
+ + + + +
+

+convert to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000069.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000069.html new file mode 100644 index 0000000..3d4a83b --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000069.html @@ -0,0 +1,20 @@ + + + + + + to_xml (CFPropertyList::CFString) + + + + +
# File rbCFTypes.rb, line 38
+    def to_xml
+      n = LibXML::XML::Node.new('string')
+      n << LibXML::XML::Node.new_text(@value) unless @value.nil?
+      return n
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000070.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000070.html new file mode 100644 index 0000000..2d2e0af --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFString.src/M000070.html @@ -0,0 +1,18 @@ + + + + + + to_binary (CFPropertyList::CFString) + + + + +
# File rbCFTypes.rb, line 45
+    def to_binary(bplist)
+      return bplist.string_to_binary(@value);
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.html new file mode 100644 index 0000000..aea9dd8 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.html @@ -0,0 +1,201 @@ + + + + + + Class: CFPropertyList::CFType + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::CFType
In: + + rbCFTypes.rb + +
+
Parent: + Object +
+
+ + +
+ + + +
+ +
+

+This class defines the base class for all CFType +classes +

+ +
+ + +
+ +
+

Methods

+ +
+ new   + to_binary   + to_xml   +
+
+ +
+ + + + +
+ + + + + +
+

Attributes

+ +
+ + + + + + +
value [RW]  +value of the type + +
+
+
+ + + + +
+

Public Class methods

+ +
+ + + + +
+

+set internal value to parameter value by default +

+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+convert type to binary +

+
+
+ +
+ + + + +
+

+convert type to XML +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000003.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000003.html new file mode 100644 index 0000000..0f626dd --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000003.html @@ -0,0 +1,18 @@ + + + + + + new (CFPropertyList::CFType) + + + + +
# File rbCFTypes.rb, line 21
+    def initialize(value=nil)
+      @value = value
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000004.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000004.html new file mode 100644 index 0000000..120b553 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000004.html @@ -0,0 +1,17 @@ + + + + + + to_xml (CFPropertyList::CFType) + + + + +
# File rbCFTypes.rb, line 26
+    def to_xml
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000005.html b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000005.html new file mode 100644 index 0000000..9e9dd68 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/CFType.src/M000005.html @@ -0,0 +1,17 @@ + + + + + + to_binary (CFPropertyList::CFType) + + + + +
# File rbCFTypes.rb, line 30
+    def to_binary(bplist)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.html new file mode 100644 index 0000000..2bb11bb --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.html @@ -0,0 +1,412 @@ + + + + + + Class: CFPropertyList::List + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::List
In: + + rbCFPropertyList.rb + +
+
Parent: + Object +
+
+ + +
+ + + +
+ + + +
+ +
+

Methods

+ +
+ load   + load_binary   + load_binary_str   + load_str   + load_xml   + load_xml_str   + new   + save   + to_str   +
+
+ +
+ + + + +
+ + +
+

Constants

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
FORMAT_BINARY=1  +Format constant for binary format + +
FORMAT_XML=2  +Format constant for XML format + +
FORMAT_AUTO=0  +Format constant for automatic format recognizing + +
+
+
+ + + +
+

Attributes

+ +
+ + + + + + + + + + + + + + + + +
filename [RW]  +Path of PropertyList + +
format [RW]  +Path of PropertyList + +
value [RW]  +the root value in the plist file + +
+
+
+ + + + +
+

Public Class methods

+ +
+ + + + +
+
+
+ +

Public Instance methods

+ +
+ + + + +
+

+Read a plist file +

+ + + +
file = nil:The filename of the file to read. If nil, use filename instance +variable + +
format = nil:The format of the plist file. Auto-detect if nil + +
+
+
+ +
+ + + + +
+

+read a binary plist file +

+ + +
filename = nil:The filename to read from; if nil, read from the file defined by instance +variable filename + +
+
+
+ +
+ + + + +
+

+load a plist from a binary string +

+ + +
str:The string containing the plist + +
+
+
+ +
+ + + + +
+

+load a plist from a string +

+ + + +
str = nil:The string containing the plist + +
format = nil:The format of the plist + +
+
+
+ +
+ + + + +
+

+Load an XML PropertyList +

+ + +
filename = nil:The filename to read from; if nil, read from the file defined by instance +variable filename + +
+
+
+ +
+ + + + +
+

+load a plist from a XML string +

+ + +
str:The string containing the plist + +
+
+
+ +
+ + + + +
+

+Serialize CFPropertyList object to +specified format and write it to file +

+ + + +
file = nil:The filename of the file to write to. Uses filename instance +variable if nil + +
format = nil:The format to save in. Uses format +instance variable if nil + +
+
+
+ +
+ + + + +
+

+convert plist to string +

+ + + +
format = List::FORMAT_BINARY:The format to save the plist + +
opts={}:Pass parser options + +
+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000056.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000056.html new file mode 100644 index 0000000..f9a09f9 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000056.html @@ -0,0 +1,23 @@ + + + + + + new (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 158
+    def initialize(opts={})
+      @filename = opts[:file]
+      @format = opts[:format] || FORMAT_AUTO
+      @data = opts[:data]
+
+      load(@filename) unless @filename.nil?
+      load_str(@data) unless @data.nil?
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000057.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000057.html new file mode 100644 index 0000000..ad639d4 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000057.html @@ -0,0 +1,18 @@ + + + + + + load_xml (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 169
+    def load_xml(filename=nil)
+      load(filename,List::FORMAT_XML)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000058.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000058.html new file mode 100644 index 0000000..4affdad --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000058.html @@ -0,0 +1,18 @@ + + + + + + load_binary (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 175
+    def load_binary(filename=nil)
+      load(filename,List::FORMAT_BINARY)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000059.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000059.html new file mode 100644 index 0000000..cccbbb5 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000059.html @@ -0,0 +1,18 @@ + + + + + + load_xml_str (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 181
+    def load_xml_str(str=nil)
+      load_str(str,List::FORMAT_XML)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000060.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000060.html new file mode 100644 index 0000000..7fbac42 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000060.html @@ -0,0 +1,18 @@ + + + + + + load_binary_str (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 187
+    def load_binary_str(str=nil)
+      load_str(str,List::FORMAT_BINARY)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000061.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000061.html new file mode 100644 index 0000000..bef1599 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000061.html @@ -0,0 +1,40 @@ + + + + + + load_str (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 194
+    def load_str(str=nil,format=nil)
+      str = @data if str.nil?
+      format = @format if format.nil?
+
+      @value = {}
+      case format
+      when List::FORMAT_BINARY, List::FORMAT_XML then
+        prsr = @@parsers[format-1].new
+        @value = prsr.load({:data => str})
+
+      when List::FORMAT_AUTO then # what we now do is ugly, but neccessary to recognize the file format
+        filetype = str[0..5]
+        version = str[6..7]
+
+        prsr = nil
+        if filetype == "bplist" then
+          raise CFFormatError.new("Wong file version #{version}") unless version == "00"
+          prsr = Binary.new
+        else
+          prsr = XML.new
+        end
+
+        @value = prsr.load({:data => str})
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000062.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000062.html new file mode 100644 index 0000000..dcaf2da --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000062.html @@ -0,0 +1,43 @@ + + + + + + load (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 223
+    def load(file=nil,format=nil)
+      file = @filename if file.nil?
+      format = @format if format.nil?
+      @value = {}
+
+      raise IOError.new("File #{file} not readable!") unless File.readable? file
+
+      case format
+      when List::FORMAT_BINARY, List::FORMAT_XML then
+        prsr = @@parsers[format-1].new
+        @value = prsr.load({:file => file})
+
+      when List::FORMAT_AUTO then # what we now do is ugly, but neccessary to recognize the file format
+        magic_number = IO.read(file,8)
+        filetype = magic_number[0..5]
+        version = magic_number[6..7]
+
+        prsr = nil
+        if filetype == "bplist" then
+          raise CFFormatError.new("Wong file version #{version}") unless version == "00"
+          prsr = Binary.new
+        else
+          prsr = XML.new
+        end
+
+        @value = prsr.load({:file => file})
+      end
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000063.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000063.html new file mode 100644 index 0000000..173ed18 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000063.html @@ -0,0 +1,36 @@ + + + + + + save (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 255
+    def save(file=nil,format=nil,opts={})
+      format = @format if format.nil?
+      file = @filename if file.nil?
+
+      raise CFFormatError.new("Format #{format} not supported, use List::FORMAT_BINARY or List::FORMAT_XML") if format != FORMAT_BINARY && format != FORMAT_XML
+
+      if(!File.exists?(file)) then
+        raise IOError.new("File #{file} not writable!") unless File.writable?(File.dirname(file))
+      elsif(!File.writable?(file)) then
+        raise IOError.new("File #{file} not writable!")
+      end
+
+      opts[:root] = @value
+      prsr = @@parsers[format-1].new
+      content = prsr.to_str(opts)
+
+      File.open(file, 'wb') {
+        |fd|
+        fd.write content
+      }
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000064.html b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000064.html new file mode 100644 index 0000000..5e349ed --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/List.src/M000064.html @@ -0,0 +1,20 @@ + + + + + + to_str (CFPropertyList::List) + + + + +
# File rbCFPropertyList.rb, line 280
+    def to_str(format=List::FORMAT_BINARY,opts={})
+      prsr = @@parsers[format-1].new
+      opts[:root] = @value
+      return prsr.to_str(opts)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.html b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.html new file mode 100644 index 0000000..69ee338 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.html @@ -0,0 +1,164 @@ + + + + + + Class: CFPropertyList::ParserInterface + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::ParserInterface
In: + + rbCFPropertyList.rb + +
+
Parent: + Object +
+
+ + +
+ + + +
+ +
+

+interface class for PList parsers +

+ +
+ + +
+ +
+

Methods

+ +
+ load   + to_str   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+load a plist +

+
+
+ +
+ + + + +
+

+convert a plist to string +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000050.html b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000050.html new file mode 100644 index 0000000..7804231 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000050.html @@ -0,0 +1,18 @@ + + + + + + load (CFPropertyList::ParserInterface) + + + + +
# File rbCFPropertyList.rb, line 46
+    def load(opts={})
+      return ""
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000051.html b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000051.html new file mode 100644 index 0000000..0eb9cdc --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/ParserInterface.src/M000051.html @@ -0,0 +1,18 @@ + + + + + + to_str (CFPropertyList::ParserInterface) + + + + +
# File rbCFPropertyList.rb, line 51
+    def to_str(opts={})
+      return true
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/XML.html b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.html new file mode 100644 index 0000000..0c277e7 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.html @@ -0,0 +1,218 @@ + + + + + + Class: CFPropertyList::XML + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassCFPropertyList::XML
In: + + rbXMLCFPropertyList.rb + +
+
Parent: + + ParserInterface + +
+
+ + +
+ + + +
+ +
+

+XML parser +

+ +
+ + +
+ +
+

Methods

+ +
+ get_value   + import_xml   + load   + to_str   +
+
+ +
+ + + + +
+ + + + + + + + + +
+

Public Instance methods

+ +
+ + + + +
+

+read a XML file opts:: +

+
    +
  • :file - The filename of the file to load + +
  • +
  • :data - The data to parse + +
  • +
+
+
+ +
+ + + + +
+

+serialize CFPropertyList object to XML +

+ + +
opts = {}:Specify options: :formatted - Use indention and line breaks + +
+
+
+ +

Protected Instance methods

+ +
+ + + + +
+

+get the value of a DOM node +

+
+
+ +
+ + + + +
+

+import the XML values +

+
+
+ + +
+ + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000006.html b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000006.html new file mode 100644 index 0000000..9cf1b7f --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000006.html @@ -0,0 +1,25 @@ + + + + + + load (CFPropertyList::XML) + + + + +
# File rbXMLCFPropertyList.rb, line 16
+    def load(opts)
+      if(opts.has_key?(:file)) then
+        doc = LibXML::XML::Document.file(opts[:file],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
+      else
+        doc = LibXML::XML::Document.string(opts[:data],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
+      end
+
+      root = doc.root.first
+      return import_xml(root)
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000007.html b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000007.html new file mode 100644 index 0000000..1e30bc2 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000007.html @@ -0,0 +1,40 @@ + + + + + + to_str (CFPropertyList::XML) + + + + +
# File rbXMLCFPropertyList.rb, line 29
+    def to_str(opts={})
+      doc = LibXML::XML::Document.new
+
+      doc.root = LibXML::XML::Node.new('plist')
+      doc.encoding = LibXML::XML::Encoding::UTF_8
+
+      doc.root['version'] = '1.0'
+      doc.root << opts[:root].to_xml()
+
+      # ugly hack, but there's no other possibility I know
+      str = doc.to_s(:indent => opts[:formatted])
+      str1 = String.new
+      first = false
+      str.each_line do
+        |line|
+        str1 << line
+        unless(first) then
+          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/
+        end
+
+        first = true
+      end
+
+      return str1
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000008.html b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000008.html new file mode 100644 index 0000000..679a206 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000008.html @@ -0,0 +1,19 @@ + + + + + + get_value (CFPropertyList::XML) + + + + +
# File rbXMLCFPropertyList.rb, line 58
+    def get_value(n)
+      return n.first.content if n.children?
+      return n.content
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000009.html b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000009.html new file mode 100644 index 0000000..4457947 --- /dev/null +++ b/lib/cfpropertylist/doc/classes/CFPropertyList/XML.src/M000009.html @@ -0,0 +1,69 @@ + + + + + + import_xml (CFPropertyList::XML) + + + + +
# File rbXMLCFPropertyList.rb, line 64
+    def import_xml(node)
+      ret = nil
+
+      case node.name
+      when 'dict'
+        hsh = Hash.new
+        key = nil
+
+        if node.children? then
+          node.children.each do
+            |n|
+
+            if n.name == "key" then
+              key = get_value(n)
+            else
+              raise CFFormatError.new("Format error!") if key.nil?
+              hsh[key] = import_xml(n)
+              key = nil
+            end
+          end
+        end
+
+        ret = CFDictionary.new(hsh)
+
+      when 'array'
+        ary = Array.new
+
+        if node.children? then
+          node.children.each do
+            |n|
+            ary.push import_xml(n)
+          end
+        end
+
+        ret = CFArray.new(ary)
+
+      when 'true'
+        ret = CFBoolean.new(true)
+      when 'false'
+        ret = CFBoolean.new(false)
+      when 'real'
+        ret = CFReal.new(get_value(node).to_f)
+      when 'integer'
+        ret = CFInteger.new(get_value(node).to_i)
+      when 'string'
+        ret = CFString.new(get_value(node))
+      when 'data'
+        ret = CFData.new(get_value(node))
+      when 'date'
+        ret = CFDate.new(CFDate.parse_date(get_value(node)))
+      end
+
+      return ret
+    end
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/created.rid b/lib/cfpropertylist/doc/created.rid new file mode 100644 index 0000000..495074c --- /dev/null +++ b/lib/cfpropertylist/doc/created.rid @@ -0,0 +1 @@ +Tue, 02 Mar 2010 18:22:40 +0100 diff --git a/lib/cfpropertylist/doc/files/rbBinaryCFPropertyList_rb.html b/lib/cfpropertylist/doc/files/rbBinaryCFPropertyList_rb.html new file mode 100644 index 0000000..c4bd200 --- /dev/null +++ b/lib/cfpropertylist/doc/files/rbBinaryCFPropertyList_rb.html @@ -0,0 +1,120 @@ + + + + + + File: rbBinaryCFPropertyList.rb + + + + + + + + + + +
+

rbBinaryCFPropertyList.rb

+ + + + + + + + + +
Path:rbBinaryCFPropertyList.rb +
Last Update:Tue Mar 02 18:22:30 +0100 2010
+
+ + +
+ + + +
+ +
+

+CFPropertyList implementation +parser class to read, manipulate and write binary property list files +(plist(5)) as defined by Apple +

+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2010 + +
License:Distributes under the same terms as Ruby + +
+ +
+ + +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/files/rbCFFormatError_rb.html b/lib/cfpropertylist/doc/files/rbCFFormatError_rb.html new file mode 100644 index 0000000..38e0ea8 --- /dev/null +++ b/lib/cfpropertylist/doc/files/rbCFFormatError_rb.html @@ -0,0 +1,118 @@ + + + + + + File: rbCFFormatError.rb + + + + + + + + + + +
+

rbCFFormatError.rb

+ + + + + + + + + +
Path:rbCFFormatError.rb +
Last Update:Tue Mar 02 18:22:30 +0100 2010
+
+ + +
+ + + +
+ +
+

+CFFormatError implementation +

+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2010 + +
License:MIT License + +
+ +
+ + +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/files/rbCFPropertyList_rb.html b/lib/cfpropertylist/doc/files/rbCFPropertyList_rb.html new file mode 100644 index 0000000..01a1c56 --- /dev/null +++ b/lib/cfpropertylist/doc/files/rbCFPropertyList_rb.html @@ -0,0 +1,157 @@ + + + + + + File: rbCFPropertyList.rb + + + + + + + + + + +
+

rbCFPropertyList.rb

+ + + + + + + + + +
Path:rbCFPropertyList.rb +
Last Update:Tue Mar 02 18:22:30 +0100 2010
+
+ + +
+ + + +
+ +
+

+CFPropertyList implementation +class to read, manipulate and write both XML and binary property list files +(plist(5)) as defined by Apple +

+

Example

+
+  # create a arbitrary data structure of basic data types
+  data = {
+    'name' => 'John Doe',
+    'missing' => true,
+    'last_seen' => Time.now,
+    'friends' => ['Jane Doe','Julian Doe'],
+    'likes' => {
+      'me' => false
+    }
+  }
+
+  # create CFPropertyList::List object
+  plist = CFPropertyList::List.new
+
+  # call CFPropertyList.guess() to create corresponding CFType values
+  # pass in optional :convert_unknown_to_string => true to convert things like symbols into strings.
+  plist.value = CFPropertyList.guess(data)
+
+  # write plist to file
+  plist.save("example.plist", CFPropertyList::List::FORMAT_BINARY)
+
+  # … later, read it again
+  plist = CFPropertyList::List.new({:file => "example.plist"})
+  data = CFPropertyList.native_types(plist.value)
+
+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2010 + +
License:Distributes under the same terms as Ruby + +
+ +
+ +
+

Required files

+ +
+ libxml   + kconv   + date   + iconv   +
+
+ +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/files/rbCFTypes_rb.html b/lib/cfpropertylist/doc/files/rbCFTypes_rb.html new file mode 100644 index 0000000..b0ba87d --- /dev/null +++ b/lib/cfpropertylist/doc/files/rbCFTypes_rb.html @@ -0,0 +1,125 @@ + + + + + + File: rbCFTypes.rb + + + + + + + + + + +
+

rbCFTypes.rb

+ + + + + + + + + +
Path:rbCFTypes.rb +
Last Update:Tue Mar 02 18:22:30 +0100 2010
+
+ + +
+ + + +
+ +
+

+CFTypes, e.g. CFString, CFInteger needed to create unambiguous plists +

+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2009 + +
License:Distributes under the same terms as Ruby + +
+ +
+ +
+

Required files

+ +
+ base64   +
+
+ +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/files/rbXMLCFPropertyList_rb.html b/lib/cfpropertylist/doc/files/rbXMLCFPropertyList_rb.html new file mode 100644 index 0000000..6ce1616 --- /dev/null +++ b/lib/cfpropertylist/doc/files/rbXMLCFPropertyList_rb.html @@ -0,0 +1,120 @@ + + + + + + File: rbXMLCFPropertyList.rb + + + + + + + + + + +
+

rbXMLCFPropertyList.rb

+ + + + + + + + + +
Path:rbXMLCFPropertyList.rb +
Last Update:Tue Mar 02 18:22:30 +0100 2010
+
+ + +
+ + + +
+ +
+

+CFPropertyList implementation +parser class to read, manipulate and write XML property list files +(plist(5)) as defined by Apple +

+ + + + +
Author:Christian Kruse (cjk@wwwtech.de) + +
Copyright:Copyright (c) 2010 + +
License:Distributes under the same terms as Ruby + +
+ +
+ + +
+ + +
+ + + + +
+ + + + + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/fr_class_index.html b/lib/cfpropertylist/doc/fr_class_index.html new file mode 100644 index 0000000..9041ba9 --- /dev/null +++ b/lib/cfpropertylist/doc/fr_class_index.html @@ -0,0 +1,41 @@ + + + + + + + + Classes + + + + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/fr_file_index.html b/lib/cfpropertylist/doc/fr_file_index.html new file mode 100644 index 0000000..6bcde51 --- /dev/null +++ b/lib/cfpropertylist/doc/fr_file_index.html @@ -0,0 +1,31 @@ + + + + + + + + Files + + + + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/fr_method_index.html b/lib/cfpropertylist/doc/fr_method_index.html new file mode 100644 index 0000000..d0fb0ca --- /dev/null +++ b/lib/cfpropertylist/doc/fr_method_index.html @@ -0,0 +1,103 @@ + + + + + + + + Methods + + + + + +
+

Methods

+
+ array_to_binary (CFPropertyList::Binary)
+ binary_strlen (CFPropertyList::Binary)
+ bool_to_binary (CFPropertyList::Binary)
+ bytes_int (CFPropertyList::Binary)
+ bytes_needed (CFPropertyList::Binary)
+ bytes_size_int (CFPropertyList::Binary)
+ charset_convert (CFPropertyList::Binary)
+ charset_strlen (CFPropertyList::Binary)
+ data_to_binary (CFPropertyList::Binary)
+ date_string (CFPropertyList::CFDate)
+ date_to_binary (CFPropertyList::Binary)
+ decoded_value (CFPropertyList::CFData)
+ dict_to_binary (CFPropertyList::Binary)
+ get_value (CFPropertyList::CFDate)
+ get_value (CFPropertyList::XML)
+ guess (CFPropertyList)
+ import_xml (CFPropertyList::XML)
+ int_bytes (CFPropertyList::Binary)
+ int_to_binary (CFPropertyList::Binary)
+ load (CFPropertyList::List)
+ load (CFPropertyList::ParserInterface)
+ load (CFPropertyList::Binary)
+ load (CFPropertyList::XML)
+ load_binary (CFPropertyList::List)
+ load_binary_str (CFPropertyList::List)
+ load_str (CFPropertyList::List)
+ load_xml (CFPropertyList::List)
+ load_xml_str (CFPropertyList::List)
+ native_types (CFPropertyList)
+ new (CFPropertyList::CFDate)
+ new (CFPropertyList::CFType)
+ new (CFPropertyList::CFData)
+ new (CFPropertyList::CFArray)
+ new (CFPropertyList::CFDictionary)
+ new (CFPropertyList::List)
+ num_to_binary (CFPropertyList::Binary)
+ pack_it_with_size (CFPropertyList::Binary)
+ parse_date (CFPropertyList::CFDate)
+ read_binary_array (CFPropertyList::Binary)
+ read_binary_data (CFPropertyList::Binary)
+ read_binary_date (CFPropertyList::Binary)
+ read_binary_dict (CFPropertyList::Binary)
+ read_binary_int (CFPropertyList::Binary)
+ read_binary_null_type (CFPropertyList::Binary)
+ read_binary_object (CFPropertyList::Binary)
+ read_binary_object_at (CFPropertyList::Binary)
+ read_binary_real (CFPropertyList::Binary)
+ read_binary_string (CFPropertyList::Binary)
+ read_binary_unicode_string (CFPropertyList::Binary)
+ real_to_binary (CFPropertyList::Binary)
+ save (CFPropertyList::List)
+ set_value (CFPropertyList::CFDate)
+ string_to_binary (CFPropertyList::Binary)
+ to_binary (CFPropertyList::CFString)
+ to_binary (CFPropertyList::CFData)
+ to_binary (CFPropertyList::CFInteger)
+ to_binary (CFPropertyList::CFBoolean)
+ to_binary (CFPropertyList::CFReal)
+ to_binary (CFPropertyList::CFType)
+ to_binary (CFPropertyList::CFDictionary)
+ to_binary (CFPropertyList::CFArray)
+ to_binary (CFPropertyList::CFDate)
+ to_str (CFPropertyList::ParserInterface)
+ to_str (CFPropertyList::List)
+ to_str (CFPropertyList::XML)
+ to_str (CFPropertyList::Binary)
+ to_xml (CFPropertyList::CFReal)
+ to_xml (CFPropertyList::CFData)
+ to_xml (CFPropertyList::CFString)
+ to_xml (CFPropertyList::CFInteger)
+ to_xml (CFPropertyList::CFArray)
+ to_xml (CFPropertyList::CFBoolean)
+ to_xml (CFPropertyList::CFType)
+ to_xml (CFPropertyList::CFDate)
+ to_xml (CFPropertyList::CFDictionary)
+ type_bytes (CFPropertyList::Binary)
+ unique_and_count_values (CFPropertyList::Binary)
+
+
+ + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/index.html b/lib/cfpropertylist/doc/index.html new file mode 100644 index 0000000..bf38061 --- /dev/null +++ b/lib/cfpropertylist/doc/index.html @@ -0,0 +1,24 @@ + + + + + + + RDoc Documentation + + + + + + + + + + + \ No newline at end of file diff --git a/lib/cfpropertylist/doc/rdoc-style.css b/lib/cfpropertylist/doc/rdoc-style.css new file mode 100644 index 0000000..44c7b3d --- /dev/null +++ b/lib/cfpropertylist/doc/rdoc-style.css @@ -0,0 +1,208 @@ + +body { + font-family: Verdana,Arial,Helvetica,sans-serif; + font-size: 90%; + margin: 0; + margin-left: 40px; + padding: 0; + background: white; +} + +h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; } +h1 { font-size: 150%; } +h2,h3,h4 { margin-top: 1em; } + +a { background: #eef; color: #039; text-decoration: none; } +a:hover { background: #039; color: #eef; } + +/* Override the base stylesheet's Anchor inside a table cell */ +td > a { + background: transparent; + color: #039; + text-decoration: none; +} + +/* and inside a section title */ +.section-title > a { + background: transparent; + color: #eee; + text-decoration: none; +} + +/* === Structural elements =================================== */ + +div#index { + margin: 0; + margin-left: -40px; + padding: 0; + font-size: 90%; +} + + +div#index a { + margin-left: 0.7em; +} + +div#index .section-bar { + margin-left: 0px; + padding-left: 0.7em; + background: #ccc; + font-size: small; +} + + +div#classHeader, div#fileHeader { + width: auto; + color: white; + padding: 0.5em 1.5em 0.5em 1.5em; + margin: 0; + margin-left: -40px; + border-bottom: 3px solid #006; +} + +div#classHeader a, div#fileHeader a { + background: inherit; + color: white; +} + +div#classHeader td, div#fileHeader td { + background: inherit; + color: white; +} + + +div#fileHeader { + background: #057; +} + +div#classHeader { + background: #048; +} + + +.class-name-in-header { + font-size: 180%; + font-weight: bold; +} + + +div#bodyContent { + padding: 0 1.5em 0 1.5em; +} + +div#description { + padding: 0.5em 1.5em; + background: #efefef; + border: 1px dotted #999; +} + +div#description h1,h2,h3,h4,h5,h6 { + color: #125;; + background: transparent; +} + +div#validator-badges { + text-align: center; +} +div#validator-badges img { border: 0; } + +div#copyright { + color: #333; + background: #efefef; + font: 0.75em sans-serif; + margin-top: 5em; + margin-bottom: 0; + padding: 0.5em 2em; +} + + +/* === Classes =================================== */ + +table.header-table { + color: white; + font-size: small; +} + +.type-note { + font-size: small; + color: #DEDEDE; +} + +.xxsection-bar { + background: #eee; + color: #333; + padding: 3px; +} + +.section-bar { + color: #333; + border-bottom: 1px solid #999; + margin-left: -20px; +} + + +.section-title { + background: #79a; + color: #eee; + padding: 3px; + margin-top: 2em; + margin-left: -30px; + border: 1px solid #999; +} + +.top-aligned-row { vertical-align: top } +.bottom-aligned-row { vertical-align: bottom } + +/* --- Context section classes ----------------------- */ + +.context-row { } +.context-item-name { font-family: monospace; font-weight: bold; color: black; } +.context-item-value { font-size: small; color: #448; } +.context-item-desc { color: #333; padding-left: 2em; } + +/* --- Method classes -------------------------- */ +.method-detail { + background: #efefef; + padding: 0; + margin-top: 0.5em; + margin-bottom: 1em; + border: 1px dotted #ccc; +} +.method-heading { + color: black; + background: #ccc; + border-bottom: 1px solid #666; + padding: 0.2em 0.5em 0 0.5em; +} +.method-signature { color: black; background: inherit; } +.method-name { font-weight: bold; } +.method-args { font-style: italic; } +.method-description { padding: 0 0.5em 0 0.5em; } + +/* --- Source code sections -------------------- */ + +a.source-toggle { font-size: 90%; } +div.method-source-code { + background: #262626; + color: #ffdead; + margin: 1em; + padding: 0.5em; + border: 1px dashed #999; + overflow: hidden; +} + +div.method-source-code pre { color: #ffdead; overflow: hidden; } + +/* --- Ruby keyword styles --------------------- */ + +.standalone-code { background: #221111; color: #ffdead; overflow: hidden; } + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } \ No newline at end of file diff --git a/lib/cfpropertylist/example.plist b/lib/cfpropertylist/example.plist new file mode 100644 index 0000000000000000000000000000000000000000..754e11fc69d55f8876ec845c30fd6511d91b3295 GIT binary patch literal 152 zcmYc)$jK}&F)+Bw$i&RT%Er#Y$rF;7n421&n^|0(nU@}!lUQ65U!0nn7oJv>nVOeU z9Ga7vomw2>m7kHP;F6!pY3#W1(33qA8hI9RaYuM1=B0u}qr6IUG84fHF7omP<)(6Q f2umnv8Cf_wdHaPYrDiaI0V5-XX5fd?Fe(!OnVTr8 literal 0 HcmV?d00001 diff --git a/lib/cfpropertylist/rbBinaryCFPropertyList.rb b/lib/cfpropertylist/rbBinaryCFPropertyList.rb new file mode 100644 index 0000000..61da05c --- /dev/null +++ b/lib/cfpropertylist/rbBinaryCFPropertyList.rb @@ -0,0 +1,669 @@ +# -*- coding: utf-8 -*- +# +# CFPropertyList implementation +# parser class to read, manipulate and write binary property list files (plist(5)) as defined by Apple +# +# Author:: Christian Kruse (mailto:cjk@wwwtech.de) +# Copyright:: Copyright (c) 2010 +# License:: Distributes under the same terms as Ruby + +module CFPropertyList + class Binary + # Read a binary plist file + def load(opts) + @unique_table = {} + @count_objects = 0 + @string_size = 0 + @int_size = 0 + @misc_size = 0 + @object_refs = 0 + + @written_object_count = 0 + @object_table = [] + @object_ref_size = 0 + + @offsets = [] + + fd = nil + if(opts.has_key?(:file)) then + fd = File.open(opts[:file],"rb") + file = opts[:file] + else + fd = StringIO.new(opts[:data],"rb") + file = "" + end + + # first, we read the trailer: 32 byte from the end + fd.seek(-32,IO::SEEK_END) + buff = fd.read(32) + + offset_size, object_ref_size, number_of_objects, top_object, table_offset = buff.unpack "x6CCx4Nx4Nx4N" + + # after that, get the offset table + fd.seek(table_offset, IO::SEEK_SET) + coded_offset_table = fd.read(number_of_objects * offset_size) + raise CFFormatError.new("#{file}: Format error!") unless coded_offset_table.bytesize == number_of_objects * offset_size + + @count_objects = number_of_objects + + # decode offset table + formats = ["","C*","n*","(H6)*","N*"] + @offsets = coded_offset_table.unpack(formats[offset_size]) + if(offset_size == 3) then + 0.upto(@offsets.count-1) { |i| @offsets[i] = @offsets[i].to_i(16) } + end + + @object_ref_size = object_ref_size + val = read_binary_object_at(file,fd,top_object) + + fd.close + return val + end + + + # Convert CFPropertyList to binary format; since we have to count our objects we simply unique CFDictionary and CFArray + def to_str(opts={}) + @unique_table = {} + @count_objects = 0 + @string_size = 0 + @int_size = 0 + @misc_size = 0 + @object_refs = 0 + + @written_object_count = 0 + @object_table = [] + @object_ref_size = 0 + + @offsets = [] + + binary_str = "bplist00" + unique_and_count_values(opts[:root]) + + @count_objects += @unique_table.count + @object_ref_size = Binary.bytes_needed(@count_objects) + + file_size = @string_size + @int_size + @misc_size + @object_refs * @object_ref_size + 40 + offset_size = Binary.bytes_needed(file_size) + table_offset = file_size - 32 + + @object_table = [] + @written_object_count = 0 + @unique_table = {} # we needed it to calculate several values, but now we need an empty table + + opts[:root].to_binary(self) + + object_offset = 8 + offsets = [] + + 0.upto(@object_table.count-1) do |i| + binary_str += @object_table[i] + offsets[i] = object_offset + object_offset += @object_table[i].bytesize + end + + offsets.each do |offset| + binary_str += Binary.pack_it_with_size(offset_size,offset) + end + + binary_str += [offset_size, @object_ref_size].pack("x6CC") + binary_str += [@count_objects].pack("x4N") + binary_str += [0].pack("x4N") + binary_str += [table_offset].pack("x4N") + + return binary_str + end + + # read a „null” type (i.e. null byte, marker byte, bool value) + def read_binary_null_type(length) + case length + when 0 then return 0 # null byte + when 8 then return CFBoolean.new(false) + when 9 then return CFBoolean.new(true) + when 15 then return 15 # fill type + end + + raise CFFormatError.new("unknown null type: #{length}") + end + protected :read_binary_null_type + + # read a binary int value + def read_binary_int(fname,fd,length) + raise CFFormatError.new("Integer greater than 8 bytes: #{length}") if length > 3 + + nbytes = 1 << length + + val = nil + buff = fd.read(nbytes) + + case length + when 0 then + val = buff.unpack("C") + val = val[0] + when 1 then + val = buff.unpack("n") + val = val[0] + when 2 then + val = buff.unpack("N") + val = val[0] + when 3 + hiword,loword = buff.unpack("NN") + val = hiword << 32 | loword + end + + return CFInteger.new(val); + end + protected :read_binary_int + + # read a binary real value + def read_binary_real(fname,fd,length) + raise CFFormatError.new("Real greater than 8 bytes: #{length}") if length > 3 + + nbytes = 1 << length + val = nil + buff = fd.read(nbytes) + + case length + when 0 then # 1 byte float? must be an error + raise CFFormatError.new("got #{length+1} byte float, must be an error!") + when 1 then # 2 byte float? must be an error + raise CFFormatError.new("got #{length+1} byte float, must be an error!") + when 2 then + val = buff.reverse.unpack("f") + val = val[0] + when 3 then + val = buff.reverse.unpack("d") + val = val[0] + end + + return CFReal.new(val) + end + protected :read_binary_real + + # read a binary date value + def read_binary_date(fname,fd,length) + raise CFFormatError.new("Date greater than 8 bytes: #{length}") if length > 3 + + nbytes = 1 << length + val = nil + buff = fd.read(nbytes) + + case length + when 0 then # 1 byte CFDate is an error + raise CFFormatError.new("#{length+1} byte CFDate, error") + when 1 then # 2 byte CFDate is an error + raise CFFormatError.new("#{length+1} byte CFDate, error") + when 2 then + val = buff.reverse.unpack("f") + val = val[0] + when 3 then + val = buff.reverse.unpack("d") + val = val[0] + end + + return CFDate.new(val,CFDate::TIMESTAMP_APPLE) + end + protected :read_binary_date + + # Read a binary data value + def read_binary_data(fname,fd,length) + buff = ""; + buff = fd.read(length) if length > 0 + return CFData.new(buff,CFData::DATA_RAW) + end + protected :read_binary_data + + # Read a binary string value + def read_binary_string(fname,fd,length) + buff = "" + buff = fd.read(length) if length > 0 + + @unique_table[buff] = true unless @unique_table.has_key?(buff) + return CFString.new(buff) + end + protected :read_binary_string + + # Convert the given string from one charset to another + def Binary.charset_convert(str,from,to="UTF-8") + return str.clone.force_encoding(from).encode(to) if str.respond_to?("encode") + return Iconv.conv(to,from,str) + end + + # Count characters considering character set + def Binary.charset_strlen(str,charset="UTF-8") + return str.length if str.respond_to?("encode") + + str = Iconv.conv("UTF-8",charset,str) if charset != "UTF-8" + return str.scan(/./mu).size + end + + # Read a unicode string value, coded as UTF-16BE + def read_binary_unicode_string(fname,fd,length) + # The problem is: we get the length of the string IN CHARACTERS; + # since a char in UTF-16 can be 16 or 32 bit long, we don't really know + # how long the string is in bytes + buff = fd.read(2*length) + + @unique_table[buff] = true unless @unique_table.has_key?(buff) + return CFString.new(Binary.charset_convert(buff,"UTF-16BE","UTF-8")) + end + protected :read_binary_unicode_string + + # Read an binary array value, including contained objects + def read_binary_array(fname,fd,length) + ary = [] + + # first: read object refs + if(length != 0) then + buff = fd.read(length * @object_ref_size) + objects = buff.unpack(@object_ref_size == 1 ? "C*" : "n*") + + # now: read objects + 0.upto(length-1) do |i| + object = read_binary_object_at(fname,fd,objects[i]) + ary.push object + end + end + + return CFArray.new(ary) + end + protected :read_binary_array + + # Read a dictionary value, including contained objects + def read_binary_dict(fname,fd,length) + dict = {} + + # first: read keys + if(length != 0) then + buff = fd.read(length * @object_ref_size) + keys = buff.unpack(@object_ref_size == 1 ? "C*" : "n*") + + # second: read object refs + buff = fd.read(length * @object_ref_size) + objects = buff.unpack(@object_ref_size == 1 ? "C*" : "n*") + + # read real keys and objects + 0.upto(length-1) do |i| + key = read_binary_object_at(fname,fd,keys[i]) + object = read_binary_object_at(fname,fd,objects[i]) + dict[key.value] = object + end + end + + return CFDictionary.new(dict) + end + protected :read_binary_dict + + # Read an object type byte, decode it and delegate to the correct reader function + def read_binary_object(fname,fd) + # first: read the marker byte + buff = fd.read(1) + + object_length = buff.unpack("C*") + object_length = object_length[0] & 0xF + + buff = buff.unpack("H*") + object_type = buff[0][0].chr + + if(object_type != "0" && object_length == 15) then + object_length = read_binary_object(fname,fd) + object_length = object_length.value + end + + retval = nil + case object_type + when '0' then # null, false, true, fillbyte + retval = read_binary_null_type(object_length) + when '1' then # integer + retval = read_binary_int(fname,fd,object_length) + when '2' then # real + retval = read_binary_real(fname,fd,object_length) + when '3' then # date + retval = read_binary_date(fname,fd,object_length) + when '4' then # data + retval = read_binary_data(fname,fd,object_length) + when '5' then # byte string, usually utf8 encoded + retval = read_binary_string(fname,fd,object_length) + when '6' then # unicode string (utf16be) + retval = read_binary_unicode_string(fname,fd,object_length) + when 'a' then # array + retval = read_binary_array(fname,fd,object_length) + when 'd' then # dictionary + retval = read_binary_dict(fname,fd,object_length) + end + + return retval + end + protected :read_binary_object + + # Read an object type byte at position $pos, decode it and delegate to the correct reader function + def read_binary_object_at(fname,fd,pos) + position = @offsets[pos] + fd.seek(position,IO::SEEK_SET) + return read_binary_object(fname,fd) + end + protected :read_binary_object_at + + # calculate the bytes needed for a size integer value + def Binary.bytes_size_int(int) + nbytes = 0 + + nbytes += 2 if int > 0xE # 2 bytes int + nbytes += 2 if int > 0xFF # 3 bytes int + nbytes += 2 if int > 0xFFFF # 5 bytes int + + return nbytes + end + + # Calculate the byte needed for a „normal” integer value + def Binary.bytes_int(int) + nbytes = 1 + + nbytes += 1 if int > 0xFF # 2 byte int + nbytes += 2 if int > 0xFFFF # 4 byte int + nbytes += 4 if int > 0xFFFFFFFF # 8 byte int + nbytes += 7 if int < 0 # 8 byte int (since it is signed) + + return nbytes + 1 # one „marker” byte + end + + # pack an +int+ of +nbytes+ with size + def Binary.pack_it_with_size(nbytes,int) + format = ["C", "n", "N", "N"][nbytes-1] + + if(nbytes == 3) then + val = [int].pack(format) + return val.slice(-3) + end + + return [int].pack(format) + end + + # calculate how many bytes are needed to save +count+ + def Binary.bytes_needed(count) + nbytes = 0 + + while count >= 1 do + nbytes += 1 + count /= 256 + end + + return nbytes + end + + # create integer bytes of +int+ + def Binary.int_bytes(int) + intbytes = "" + + if(int > 0xFFFF) then + intbytes = "\x12"+[int].pack("N") # 4 byte integer + elsif(int > 0xFF) then + intbytes = "\x11"+[int].pack("n") # 2 byte integer + else + intbytes = "\x10"+[int].pack("C") # 8 byte integer + end + + return intbytes; + end + + # Create a type byte for binary format as defined by apple + def Binary.type_bytes(type,type_len) + optional_int = "" + + if(type_len < 15) then + type += sprintf("%x",type_len) + else + type += "f" + optional_int = Binary.int_bytes(type_len) + end + + return [type].pack("H*") + optional_int + end + + # „unique” and count values. „Unique” means, several objects (e.g. strings) + # will only be saved once and referenced later + def unique_and_count_values(value) + # no uniquing for other types than CFString and CFData + if(value.is_a?(CFInteger) || value.is_a?(CFReal)) then + val = value.value + if(value.is_a?(CFInteger)) then + @int_size += Binary.bytes_int(val) + else + @misc_size += 9 # 9 bytes (8 + marker byte) for real + end + + @count_objects += 1 + return + elsif(value.is_a?(CFDate)) then + @misc_size += 9 + @count_objects += 1 + return + elsif(value.is_a?(CFBoolean)) then + @count_objects += 1 + @misc_size += 1 + return + elsif(value.is_a?(CFArray)) then + cnt = 0 + + value.value.each do |v| + cnt += 1 + unique_and_count_values(v) + @object_refs += 1 # each array member is a ref + end + + @count_objects += 1 + @int_size += Binary.bytes_size_int(cnt) + @misc_size += 1 # marker byte for array + return + elsif(value.is_a?(CFDictionary)) then + cnt = 0 + + value.value.each_pair do |k,v| + cnt += 1 + + if(!@unique_table.has_key?(k)) + @unique_table[k] = 0 + @string_size += Binary.binary_strlen(k) + 1 + @int_size += Binary.bytes_size_int(Binary.charset_strlen(k,'UTF-8')) + end + + @object_refs += 2 # both, key and value, are refs + @unique_table[k] += 1 + unique_and_count_values(v) + end + + @count_objects += 1 + @misc_size += 1 # marker byte for dict + @int_size += Binary.bytes_size_int(cnt) + return + elsif(value.is_a?(CFData)) then + val = value.decoded_value + @int_size += Binary.bytes_size_int(val.length) + @misc_size += val.length + @count_objects += 1 + return + end + + val = value.value + if(!@unique_table.has_key?(val)) then + @unique_table[val] = 0 + @string_size += Binary.binary_strlen(val) + 1 + @int_size += Binary.bytes_size_int(Binary.charset_strlen(val,'UTF-8')) + end + + @unique_table[val] += 1 + end + protected :unique_and_count_values + + # Counts the number of bytes the string will have when coded; utf-16be if non-ascii characters are present. + def Binary.binary_strlen(val) + val.each_byte do |b| + if(b > 127) then + val = Binary.charset_convert(val, 'UTF-8', 'UTF-16BE') + return val.bytesize + end + end + + return val.bytesize + end + + # Uniques and transforms a string value to binary format and adds it to the object table + def string_to_binary(val) + saved_object_count = -1 + + unless(@unique_table.has_key?(val)) then + saved_object_count = @written_object_count + @written_object_count += 1 + + @unique_table[val] = saved_object_count + utf16 = false + + val.each_byte do |b| + if(b > 127) then + utf16 = true + break + end + end + + if(utf16) then + bdata = Binary.type_bytes("6",Binary.charset_strlen(val,"UTF-8")) # 6 is 0110, unicode string (utf16be) + val = Binary.charset_convert(val,"UTF-8","UTF-16BE") + + val.force_encoding("ASCII-8BIT") if val.respond_to?("encode") + @object_table[saved_object_count] = bdata + val + else + bdata = Binary.type_bytes("5",val.bytesize) # 5 is 0101 which is an ASCII string (seems to be ASCII encoded) + @object_table[saved_object_count] = bdata + val + end + else + saved_object_count = @unique_table[val] + end + + return saved_object_count + end + + # Codes an integer to binary format + def int_to_binary(value) + nbytes = 0 + nbytes = 1 if value > 0xFF # 1 byte integer + nbytes += 1 if value > 0xFFFF # 4 byte integer + nbytes += 1 if value > 0xFFFFFFFF # 8 byte integer + nbytes = 3 if value < 0 # 8 byte integer, since signed + + bdata = Binary.type_bytes("1", nbytes) # 1 is 0001, type indicator for integer + buff = "" + + if(nbytes < 3) then + fmt = "N" + + if(nbytes == 0) then + fmt = "C" + elsif(nbytes == 1) + fmt = "n" + end + + buff = [value].pack(fmt) + else + # 64 bit signed integer; we need the higher and the lower 32 bit of the value + high_word = value >> 32 + low_word = value & 0xFFFFFFFF + buff = [high_word,low_word].pack("NN") + end + + return bdata + buff + end + + # Codes a real value to binary format + def real_to_binary(val) + bdata = Binary.type_bytes("2",3) # 2 is 0010, type indicator for reals + buff = [val].pack("d") + return bdata + buff.reverse + end + + # Converts a numeric value to binary and adds it to the object table + def num_to_binary(value) + saved_object_count = @written_object_count + @written_object_count += 1 + + val = "" + if(value.is_a?(CFInteger)) then + val = int_to_binary(value.value) + else + val = real_to_binary(value.value) + end + + @object_table[saved_object_count] = val + return saved_object_count + end + + # Convert date value (apple format) to binary and adds it to the object table + def date_to_binary(val) + saved_object_count = @written_object_count + @written_object_count += 1 + + val = val.getutc.to_f - CFDate::DATE_DIFF_APPLE_UNIX # CFDate is a real, number of seconds since 01/01/2001 00:00:00 GMT + + bdata = Binary.type_bytes("3", 3) # 3 is 0011, type indicator for date + @object_table[saved_object_count] = bdata + [val].pack("d").reverse + + return saved_object_count + end + + # Convert a bool value to binary and add it to the object table + def bool_to_binary(val) + saved_object_count = @written_object_count + @written_object_count += 1 + + @object_table[saved_object_count] = val ? "\x9" : "\x8" # 0x9 is 1001, type indicator for true; 0x8 is 1000, type indicator for false + return saved_object_count + end + + # Convert data value to binary format and add it to the object table + def data_to_binary(val) + saved_object_count = @written_object_count + @written_object_count += 1 + + bdata = Binary.type_bytes("4", val.bytesize) # a is 1000, type indicator for data + @object_table[saved_object_count] = bdata + val + + return saved_object_count + end + + # Convert array to binary format and add it to the object table + def array_to_binary(val) + saved_object_count = @written_object_count + @written_object_count += 1 + + bdata = Binary.type_bytes("a", val.value.count) # a is 1010, type indicator for arrays + + val.value.each do |v| + bdata += Binary.pack_it_with_size(@object_ref_size, v.to_binary(self)); + end + + @object_table[saved_object_count] = bdata + return saved_object_count + end + + # Convert dictionary to binary format and add it to the object table + def dict_to_binary(val) + saved_object_count = @written_object_count + @written_object_count += 1 + + bdata = Binary.type_bytes("d",val.value.count) # d=1101, type indicator for dictionary + + val.value.each_key do |k| + str = CFString.new(k) + key = str.to_binary(self) + bdata += Binary.pack_it_with_size(@object_ref_size,key) + end + + val.value.each_value do |v| + bdata += Binary.pack_it_with_size(@object_ref_size,v.to_binary(self)) + end + + @object_table[saved_object_count] = bdata + return saved_object_count + end + end +end + +# eof diff --git a/lib/cfpropertylist/rbCFFormatError.rb b/lib/cfpropertylist/rbCFFormatError.rb new file mode 100644 index 0000000..25337f6 --- /dev/null +++ b/lib/cfpropertylist/rbCFFormatError.rb @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# +# CFFormatError implementation +# +# Author:: Christian Kruse (mailto:cjk@wwwtech.de) +# Copyright:: Copyright (c) 2010 +# License:: MIT License + + +# Exception thrown when format errors occur +class CFFormatError < Exception +end + +# eof diff --git a/lib/cfpropertylist/rbCFPropertyList.rb b/lib/cfpropertylist/rbCFPropertyList.rb new file mode 100644 index 0000000..3029c45 --- /dev/null +++ b/lib/cfpropertylist/rbCFPropertyList.rb @@ -0,0 +1,288 @@ +# -*- coding: utf-8 -*- +# +# CFPropertyList implementation +# class to read, manipulate and write both XML and binary property list +# files (plist(5)) as defined by Apple +# +# == Example +# +# # create a arbitrary data structure of basic data types +# data = { +# 'name' => 'John Doe', +# 'missing' => true, +# 'last_seen' => Time.now, +# 'friends' => ['Jane Doe','Julian Doe'], +# 'likes' => { +# 'me' => false +# } +# } +# +# # create CFPropertyList::List object +# plist = CFPropertyList::List.new +# +# # call CFPropertyList.guess() to create corresponding CFType values +# # pass in optional :convert_unknown_to_string => true to convert things like symbols into strings. +# plist.value = CFPropertyList.guess(data) +# +# # write plist to file +# plist.save("example.plist", CFPropertyList::List::FORMAT_BINARY) +# +# # … later, read it again +# plist = CFPropertyList::List.new({:file => "example.plist"}) +# data = CFPropertyList.native_types(plist.value) +# +# Author:: Christian Kruse (mailto:cjk@wwwtech.de) +# Copyright:: Copyright (c) 2010 +# License:: Distributes under the same terms as Ruby + +require 'libxml' +require 'kconv' +require 'date' + +module CFPropertyList + # interface class for PList parsers + class ParserInterface + # load a plist + def load(opts={}) + return "" + end + + # convert a plist to string + def to_str(opts={}) + return true + end + end +end + +dirname = File.dirname(__FILE__) +require dirname + '/rbCFFormatError.rb' +require dirname + '/rbCFTypes.rb' +require dirname + '/rbXMLCFPropertyList.rb' +require dirname + '/rbBinaryCFPropertyList.rb' + +require 'iconv' unless "".respond_to?("encode") + +module CFPropertyList + # Create CFType hierarchy by guessing the correct CFType, e.g. + # + # x = { + # 'a' => ['b','c','d'] + # } + # cftypes = CFPropertyList.guess(x) + def guess(object, options = {}) + return if object.nil? + + if(object.is_a?(Fixnum) || object.is_a?(Integer)) then + return CFInteger.new(object) + elsif(object.is_a?(Float)) then + return CFReal.new(object) + elsif(object.is_a?(TrueClass) || object.is_a?(FalseClass)) then + return CFBoolean.new(object) + elsif(object.is_a?(String)) then + return CFString.new(object) + elsif(object.is_a?(Time) || object.is_a?(DateTime)) then + return CFDate.new(object) + elsif(object.is_a?(IO)) then + return CFData.new(object.read, CFData::DATA_RAW) + elsif(object.is_a?(Array)) then + ary = Array.new + object.each do + |o| + ary.push CFPropertyList.guess(o, options) + end + + return CFArray.new(ary) + elsif(object.is_a?(Hash)) then + hsh = Hash.new + object.each_pair do + |k,v| + k = k.to_s if k.is_a?(Symbol) + hsh[k] = CFPropertyList.guess(v, options) + end + + return CFDictionary.new(hsh) + elsif options[:convert_unknown_to_string] + return CFString.new(object.to_s) + end + end + + # Converts a CFType hiercharchy to native Ruby types + def native_types(object,keys_as_symbols=false) + return if object.nil? + + if(object.is_a?(CFDate) || object.is_a?(CFString) || object.is_a?(CFInteger) || object.is_a?(CFReal) || object.is_a?(CFBoolean)) then + return object.value + elsif(object.is_a?(CFData)) then + return object.decoded_value + elsif(object.is_a?(CFArray)) then + ary = [] + object.value.each do + |v| + ary.push CFPropertyList.native_types(v) + end + + return ary + elsif(object.is_a?(CFDictionary)) then + hsh = {} + object.value.each_pair do + |k,v| + k = k.to_sym if keys_as_symbols + hsh[k] = CFPropertyList.native_types(v) + end + + return hsh + end + end + + module_function :guess, :native_types + + class List + # Format constant for binary format + FORMAT_BINARY = 1 + + # Format constant for XML format + FORMAT_XML = 2 + + # Format constant for automatic format recognizing + FORMAT_AUTO = 0 + + @@parsers = [Binary,XML] + + # Path of PropertyList + attr_accessor :filename + # Path of PropertyList + attr_accessor :format + # the root value in the plist file + attr_accessor :value + + def initialize(opts={}) + @filename = opts[:file] + @format = opts[:format] || FORMAT_AUTO + @data = opts[:data] + + load(@filename) unless @filename.nil? + load_str(@data) unless @data.nil? + end + + # Load an XML PropertyList + # filename = nil:: The filename to read from; if nil, read from the file defined by instance variable +filename+ + def load_xml(filename=nil) + load(filename,List::FORMAT_XML) + end + + # read a binary plist file + # filename = nil:: The filename to read from; if nil, read from the file defined by instance variable +filename+ + def load_binary(filename=nil) + load(filename,List::FORMAT_BINARY) + end + + # load a plist from a XML string + # str:: The string containing the plist + def load_xml_str(str=nil) + load_str(str,List::FORMAT_XML) + end + + # load a plist from a binary string + # str:: The string containing the plist + def load_binary_str(str=nil) + load_str(str,List::FORMAT_BINARY) + end + + # load a plist from a string + # str = nil:: The string containing the plist + # format = nil:: The format of the plist + def load_str(str=nil,format=nil) + str = @data if str.nil? + format = @format if format.nil? + + @value = {} + case format + when List::FORMAT_BINARY, List::FORMAT_XML then + prsr = @@parsers[format-1].new + @value = prsr.load({:data => str}) + + when List::FORMAT_AUTO then # what we now do is ugly, but neccessary to recognize the file format + filetype = str[0..5] + version = str[6..7] + + prsr = nil + if filetype == "bplist" then + raise CFFormatError.new("Wong file version #{version}") unless version == "00" + prsr = Binary.new + else + prsr = XML.new + end + + @value = prsr.load({:data => str}) + end + end + + # Read a plist file + # file = nil:: The filename of the file to read. If nil, use +filename+ instance variable + # format = nil:: The format of the plist file. Auto-detect if nil + def load(file=nil,format=nil) + file = @filename if file.nil? + format = @format if format.nil? + @value = {} + + raise IOError.new("File #{file} not readable!") unless File.readable? file + + case format + when List::FORMAT_BINARY, List::FORMAT_XML then + prsr = @@parsers[format-1].new + @value = prsr.load({:file => file}) + + when List::FORMAT_AUTO then # what we now do is ugly, but neccessary to recognize the file format + magic_number = IO.read(file,8) + filetype = magic_number[0..5] + version = magic_number[6..7] + + prsr = nil + if filetype == "bplist" then + raise CFFormatError.new("Wong file version #{version}") unless version == "00" + prsr = Binary.new + else + prsr = XML.new + end + + @value = prsr.load({:file => file}) + end + end + + # Serialize CFPropertyList object to specified format and write it to file + # file = nil:: The filename of the file to write to. Uses +filename+ instance variable if nil + # format = nil:: The format to save in. Uses +format+ instance variable if nil + def save(file=nil,format=nil,opts={}) + format = @format if format.nil? + file = @filename if file.nil? + + raise CFFormatError.new("Format #{format} not supported, use List::FORMAT_BINARY or List::FORMAT_XML") if format != FORMAT_BINARY && format != FORMAT_XML + + if(!File.exists?(file)) then + raise IOError.new("File #{file} not writable!") unless File.writable?(File.dirname(file)) + elsif(!File.writable?(file)) then + raise IOError.new("File #{file} not writable!") + end + + opts[:root] = @value + prsr = @@parsers[format-1].new + content = prsr.to_str(opts) + + File.open(file, 'wb') { + |fd| + fd.write content + } + end + + # convert plist to string + # format = List::FORMAT_BINARY:: The format to save the plist + # opts={}:: Pass parser options + def to_str(format=List::FORMAT_BINARY,opts={}) + prsr = @@parsers[format-1].new + opts[:root] = @value + return prsr.to_str(opts) + end + end +end + +# eof diff --git a/lib/cfpropertylist/rbCFTypes.rb b/lib/cfpropertylist/rbCFTypes.rb new file mode 100644 index 0000000..21edfd7 --- /dev/null +++ b/lib/cfpropertylist/rbCFTypes.rb @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- +# +# CFTypes, e.g. CFString, CFInteger +# needed to create unambiguous plists +# +# Author:: Christian Kruse (mailto:cjk@wwwtech.de) +# Copyright:: Copyright (c) 2009 +# License:: Distributes under the same terms as Ruby + +require 'base64' + +module CFPropertyList + # This class defines the base class for all CFType classes + # + class CFType + # value of the type + attr_accessor :value + + + # set internal value to parameter value by default + def initialize(value=nil) + @value = value + end + + # convert type to XML + def to_xml + end + + # convert type to binary + def to_binary(bplist) + end + end + + # This class holds string values, both, UTF-8 and UTF-16BE + # It will convert the value to UTF-16BE if necessary (i.e. if non-ascii char contained) + class CFString < CFType + # convert to XML + def to_xml + n = LibXML::XML::Node.new('string') + n << LibXML::XML::Node.new_text(@value) unless @value.nil? + return n + end + + # convert to binary + def to_binary(bplist) + return bplist.string_to_binary(@value); + end + end + + # This class holds integer/fixnum values + class CFInteger < CFType + # convert to XML + def to_xml + return LibXML::XML::Node.new('integer') << LibXML::XML::Node.new_text(@value.to_s) + end + + # convert to binary + def to_binary(bplist) + return bplist.num_to_binary(self) + end + end + + # This class holds float values + class CFReal < CFType + # convert to XML + def to_xml + return LibXML::XML::Node.new('real') << LibXML::XML::Node.new_text(@value.to_s) + end + + # convert to binary + def to_binary(bplist) + return bplist.num_to_binary(self) + end + end + + # This class holds Time values. While Apple uses seconds since 2001, + # the rest of the world uses seconds since 1970. So if you access value + # directly, you get the Time class. If you access via get_value you either + # geht the timestamp or the Apple timestamp + class CFDate < CFType + TIMESTAMP_APPLE = 0 + TIMESTAMP_UNIX = 1; + DATE_DIFF_APPLE_UNIX = 978307200 + + # create a XML date strimg from a time object + def CFDate.date_string(val) + # 2009-05-13T20:23:43Z + val.getutc.strftime("%Y-%m-%dT%H:%M:%SZ") + end + + # parse a XML date string + def CFDate.parse_date(val) + # 2009-05-13T20:23:43Z + val =~ %r{^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$} + year,month,day,hour,min,sec = $1, $2, $3, $4, $5, $6 + return Time.utc(year,month,day,hour,min,sec).getlocal + end + + # set value to defined state + def initialize(value = nil,format=CFDate::TIMESTAMP_UNIX) + if(value.is_a?(Time) || value.nil?) then + @value = value.nil? ? Time.now : value + else + set_value(value,format) + end + end + + # set value with timestamp, either Apple or UNIX + def set_value(value,format=CFDate::TIMESTAMP_UNIX) + if(format == CFDate::TIMESTAMP_UNIX) then + @value = Time.at(value) + else + @value = Time.at(value + CFDate::DATE_DIFF_APPLE_UNIX) + end + end + + # get timestamp, either UNIX or Apple timestamp + def get_value(format=CFDate::TIMESTAMP_UNIX) + if(format == CFDate::TIMESTAMP_UNIX) then + return @value.to_i + else + return @value.to_f - CFDate::DATE_DIFF_APPLE_UNIX + end + end + + # convert to XML + def to_xml + return LibXML::XML::Node.new('date') << LibXML::XML::Node.new_text(CFDate::date_string(@value)) + end + + # convert to binary + def to_binary(bplist) + return bplist.date_to_binary(@value) + end + end + + # This class contains a boolean value + class CFBoolean < CFType + # convert to XML + def to_xml + return LibXML::XML::Node.new(@value ? 'true' : 'false') + end + + # convert to binary + def to_binary(bplist) + return bplist.bool_to_binary(@value); + end + end + + # This class contains binary data values + class CFData < CFType + # Base64 encoded data + DATA_BASE64 = 0 + # Raw data + DATA_RAW = 1 + + # set value to defined state, either base64 encoded or raw + def initialize(value=nil,format=DATA_BASE64) + if(format == DATA_RAW) then + @value = Base64.encode64(value) + else + @value = value + end + end + + # get base64 decoded value + def decoded_value + return Base64.decode64(@value) + end + + # convert to XML + def to_xml + return LibXML::XML::Node.new('data') << LibXML::XML::Node.new_text(@value) + end + + # convert to binary + def to_binary(bplist) + return bplist.data_to_binary(decoded_value()) + end + end + + # This class contains an array of values + class CFArray < CFType + # create a new array CFType + def initialize(val=[]) + @value = val + end + + # convert to XML + def to_xml + n = LibXML::XML::Node.new('array') + @value.each do + |v| + n << v.to_xml + end + + return n + end + + # convert to binary + def to_binary(bplist) + return bplist.array_to_binary(self) + end + end + + # this class contains a hash of values + class CFDictionary < CFType + # Create new CFDictonary type. + def initialize(value={}) + @value = value + end + + # convert to XML + def to_xml + n = LibXML::XML::Node.new('dict') + @value.each_pair do + |key,value| + k = LibXML::XML::Node.new('key') << LibXML::XML::Node.new_text(key) + n << k + n << value.to_xml + end + + return n + end + + # convert to binary + def to_binary(bplist) + return bplist.dict_to_binary(self) + end + end +end + +# eof diff --git a/lib/cfpropertylist/rbXMLCFPropertyList.rb b/lib/cfpropertylist/rbXMLCFPropertyList.rb new file mode 100644 index 0000000..dfd066e --- /dev/null +++ b/lib/cfpropertylist/rbXMLCFPropertyList.rb @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# CFPropertyList implementation +# parser class to read, manipulate and write XML property list files (plist(5)) as defined by Apple +# +# Author:: Christian Kruse (mailto:cjk@wwwtech.de) +# Copyright:: Copyright (c) 2010 +# License:: Distributes under the same terms as Ruby + +module CFPropertyList + # XML parser + class XML < ParserInterface + # read a XML file + # opts:: + # * :file - The filename of the file to load + # * :data - The data to parse + def load(opts) + if(opts.has_key?(:file)) then + doc = LibXML::XML::Document.file(opts[:file],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT) + else + doc = LibXML::XML::Document.string(opts[:data],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT) + end + + root = doc.root.first + return import_xml(root) + end + + # serialize CFPropertyList object to XML + # opts = {}:: Specify options: :formatted - Use indention and line breaks + def to_str(opts={}) + doc = LibXML::XML::Document.new + + doc.root = LibXML::XML::Node.new('plist') + doc.encoding = LibXML::XML::Encoding::UTF_8 + + doc.root['version'] = '1.0' + doc.root << opts[:root].to_xml() + + # ugly hack, but there's no other possibility I know + str = doc.to_s(:indent => opts[:formatted]) + str1 = String.new + first = false + str.each_line do + |line| + str1 << line + unless(first) then + str1 << "\n" if line =~ /^\s*<\?xml/ + end + + first = true + end + + return str1 + end + + protected + + # get the value of a DOM node + def get_value(n) + return n.first.content if n.children? + return n.content + end + + # import the XML values + def import_xml(node) + ret = nil + + case node.name + when 'dict' + hsh = Hash.new + key = nil + + if node.children? then + node.children.each do + |n| + + if n.name == "key" then + key = get_value(n) + else + raise CFFormatError.new("Format error!") if key.nil? + hsh[key] = import_xml(n) + key = nil + end + end + end + + ret = CFDictionary.new(hsh) + + when 'array' + ary = Array.new + + if node.children? then + node.children.each do + |n| + ary.push import_xml(n) + end + end + + ret = CFArray.new(ary) + + when 'true' + ret = CFBoolean.new(true) + when 'false' + ret = CFBoolean.new(false) + when 'real' + ret = CFReal.new(get_value(node).to_f) + when 'integer' + ret = CFInteger.new(get_value(node).to_i) + when 'string' + ret = CFString.new(get_value(node)) + when 'data' + ret = CFData.new(get_value(node)) + when 'date' + ret = CFDate.new(CFDate.parse_date(get_value(node))) + end + + return ret + end + end +end + +# eof diff --git a/lib/plistifier/plist_encoding.rb b/lib/plistifier/plist_encoding.rb new file mode 100644 index 0000000..7414410 --- /dev/null +++ b/lib/plistifier/plist_encoding.rb @@ -0,0 +1,115 @@ +require "cfpropertylist/rbCFPropertyList" + +module Plistifier #:nodoc: + module PlistEncoding + def to_plist(options = {}) + options[:plist_format] ||= CFPropertyList::List::FORMAT_BINARY + + hashifier = PlistHashifier.new(self, options) + + plist = CFPropertyList::List.new + plist.value = CFPropertyList.guess(hashifier.to_hash) + plist.to_str(options[:plist_format]) + end + + def to_hash(options = {}) + hashifier = PlistHashifier.new(self, options) + hashifier.to_hash + end + + class PlistHashifier #:nodoc: + attr_reader :options + + def initialize(record, options = {}) + @record, @options = record, options.dup + end + + # Outputs AR record instance method as a hash that can be easily + # encoded as Plist. + def to_hash + hash = {} + + hash.merge!(simple_attributes) + hash.merge!(method_attributes) + hash.merge!(association_attributes) + + hash + end + + # Returns 1st level attributes as a hash. + def simple_attributes + attribute_names = @record.attribute_names + + if options[:only] + options.delete(:except) + attribute_names = attribute_names & Array(options[:only]).collect(&:to_s) + else + options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column) + attribute_names = attribute_names - options[:except].collect(&:to_s) + end + + attribute_names.reject! { |n| binary_attribute?(n) } # Don't Plist-ify binary fields! + + + attrs = {} + attribute_names.each do |name| + attrs[name] = @record.read_attribute(name) + end + attrs + # @record.attributes(:only => attribute_names) + end + + # Returns 1st level methods as a hash. + def method_attributes + Array(options[:methods]).inject({}) do |method_attributes, name| + method_attributes.merge!({ name.to_s => @record.send(name.to_s) }) if @record.respond_to?(name.to_s) + method_attributes + end + end + + # Returns 1st level associations as a hash. Recursively "hashifies" + # associations so that nth level associations are converted to Plist as well. + def association_attributes + hash = {} + + if include_associations = options.delete(:include) + base_only_or_except = { :except => options[:except], + :only => options[:only] } + + include_has_options = include_associations.is_a?(Hash) + + for association in include_has_options ? include_associations.keys : Array(include_associations) + association_options = include_has_options ? include_associations[association] : base_only_or_except + + opts = options.merge(association_options) + + case @record.class.reflect_on_association(association).macro + when :has_many, :has_and_belongs_to_many + records = @record.send(association).to_a + unless records.empty? + hash[association] = records.collect { |r| PlistHashifier.new(r, opts).to_hash } + end + when :has_one, :belongs_to + if record = @record.send(association) + hash[association] = PlistHashifier.new(record, opts).to_hash + end + end + end + + options[:include] = include_associations + end + + hash + end + + protected + + def binary_attribute?(name) + !@record.class.serialized_attributes.has_key?(name) && @record.class.columns_hash[name].type == :binary + end + end + + end +end + +ActiveRecord::Base.send(:include, Plistifier::PlistEncoding) \ No newline at end of file diff --git a/lib/rails_extensions.rb b/lib/rails_extensions.rb new file mode 100644 index 0000000..0e8783e --- /dev/null +++ b/lib/rails_extensions.rb @@ -0,0 +1,47 @@ +require "cfpropertylist/rbCFPropertyList" + +class Array + def to_plist(options = {}) + options[:plist_format] ||= CFPropertyList::List::FORMAT_BINARY + + array = [] + self.each do |a| + if a.is_a? ActiveRecord::Base + array << a.to_hash(options) + else + array << a + end + end + + plist = CFPropertyList::List.new + plist.value = CFPropertyList.guess(array) + plist.to_str(options[:plist_format]) + end +end + +module ActionController + class Base + def render_with_plist(options = nil, extra_options = {}, &block) + if plist = options[:plist] + + if plist.is_a? Array + filename = plist.first.class.name + else + filename = "#{plist.class.name}-#{plist.id}" + end + + send_data( + plist.to_plist(options), + :type => Mime::PLIST, + :filename => "#{filename}.plist", + :disposition => 'inline' + ) + + else + render_without_plist(options, extra_options, &block) + end + end + + alias_method_chain :render, :plist + end +end \ No newline at end of file diff --git a/tasks/plistifier_tasks.rake b/tasks/plistifier_tasks.rake new file mode 100644 index 0000000..87a0624 --- /dev/null +++ b/tasks/plistifier_tasks.rake @@ -0,0 +1,4 @@ +# desc "Explaining what the task does" +# task :plistifier do +# # Task goes here +# end diff --git a/test/plistifier_test.rb b/test/plistifier_test.rb new file mode 100644 index 0000000..e74a4f4 --- /dev/null +++ b/test/plistifier_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class PlistifierTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..cf148b8 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,3 @@ +require 'rubygems' +require 'active_support' +require 'active_support/test_case' \ No newline at end of file diff --git a/uninstall.rb b/uninstall.rb new file mode 100644 index 0000000..9738333 --- /dev/null +++ b/uninstall.rb @@ -0,0 +1 @@ +# Uninstall hook code here