Hello community,

here is the log from the commit of package perl-Mac-PropertyList for 
openSUSE:Factory checked in at 2013-06-06 15:26:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Mac-PropertyList (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Mac-PropertyList.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Mac-PropertyList"

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/perl-Mac-PropertyList/perl-Mac-PropertyList.changes  
    2012-10-03 08:46:56.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Mac-PropertyList.new/perl-Mac-PropertyList.changes
 2013-06-06 15:26:29.000000000 +0200
@@ -1,0 +2,6 @@
+Wed Jun  5 14:31:27 UTC 2013 - [email protected]
+
+- updated to 1.38
+     Wim Lewis <[email protected]> added WriteBinary. Great work!
+
+-------------------------------------------------------------------

Old:
----
  Mac-PropertyList-1.37.tar.gz

New:
----
  Mac-PropertyList-1.38.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Mac-PropertyList.spec ++++++
--- /var/tmp/diff_new_pack.R1zmkc/_old  2013-06-06 15:26:32.000000000 +0200
+++ /var/tmp/diff_new_pack.R1zmkc/_new  2013-06-06 15:26:32.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package perl-Mac-PropertyList
 #
-# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,20 +17,31 @@
 
 
 Name:           perl-Mac-PropertyList
-Version:        1.37
+Version:        1.38
 Release:        0
 %define cpan_name Mac-PropertyList
 Summary:        Work with Mac plists at a low level
-License:        GPL-1.0+ or Artistic-1.0
+License:        Artistic-1.0 or GPL-1.0+
 Group:          Development/Libraries/Perl
 Url:            http://search.cpan.org/dist/Mac-PropertyList/
 Source:         
http://www.cpan.org/authors/id/B/BD/BDFOY/%{cpan_name}-%{version}.tar.gz
-BuildRequires:  perl >= 5.10.0
+BuildArch:      noarch
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+BuildRequires:  perl
 BuildRequires:  perl-macros
 BuildRequires:  perl(XML::Entities)
+BuildRequires:  perl(parent)
+#BuildRequires: perl(File::Find::Rule)
+#BuildRequires: perl(JSON::Any)
+#BuildRequires: perl(Mac::PropertyList)
+#BuildRequires: perl(Mac::PropertyList::Boolean)
+#BuildRequires: perl(Mac::PropertyList::Container)
+#BuildRequires: perl(Mac::PropertyList::Item)
+#BuildRequires: perl(Mac::PropertyList::ReadBinary)
+#BuildRequires: perl(Mac::PropertyList::Scalar)
+#BuildRequires: perl(Mac::PropertyList::Source)
 Requires:       perl(XML::Entities)
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildArch:      noarch
+Requires:       perl(parent)
 %{perl_requires}
 
 %description
@@ -50,22 +61,19 @@
 %setup -q -n %{cpan_name}-%{version}
 
 %build
-perl Makefile.PL INSTALLDIRS=vendor
-make %{?_smp_mflags}
+%{__perl} Makefile.PL INSTALLDIRS=vendor
+%{__make} %{?_smp_mflags}
 
 %check
-make test
+%{__make} test
 
 %install
 %perl_make_install
 %perl_process_packlist
 %perl_gen_filelist
 
-%clean
-rm -rf %{buildroot}
-
 %files -f %{name}.files
 %defattr(-,root,root,755)
-%doc Changes examples LICENSE README
+%doc Changes examples LICENSE MYMETA.json MYMETA.yml README
 
 %changelog

++++++ Mac-PropertyList-1.37.tar.gz -> Mac-PropertyList-1.38.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/Changes 
new/Mac-PropertyList-1.38/Changes
--- old/Mac-PropertyList-1.37/Changes   2012-08-30 18:40:07.000000000 +0200
+++ new/Mac-PropertyList-1.38/Changes   2012-10-23 22:45:08.000000000 +0200
@@ -1,8 +1,10 @@
-
 1.37 - Thu Aug 30 11:39:39 2012
        * fix plist_as_perl to be the same as as_perl (and as
        documented)
 
+1.38 - Tue Oct 23 15:44:26 2012
+       Wim Lewis <[email protected]> added WriteBinary. Great work!
+
 1.36 - Sat Jun 16 16:10:01 2012
        * Update the docs, and make the previous dev releases official
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/MANIFEST 
new/Mac-PropertyList-1.38/MANIFEST
--- old/Mac-PropertyList-1.37/MANIFEST  2012-08-30 18:40:08.000000000 +0200
+++ new/Mac-PropertyList-1.38/MANIFEST  2012-10-23 22:45:09.000000000 +0200
@@ -8,9 +8,12 @@
 hacks/plist.pl
 lib/Mac/PropertyList.pm
 lib/Mac/PropertyList/ReadBinary.pm
+lib/Mac/PropertyList/WriteBinary.pm
 LICENSE
 Makefile.PL
 MANIFEST
+MYMETA.json
+MYMETA.yml
 plists/binary.plist
 plists/com.apple.iPhoto.plist
 plists/com.apple.iTunes.plist
@@ -40,4 +43,6 @@
 t/test_manifest
 t/time.t
 t/write.t
-META.yml                                 Module meta-data (added by MakeMaker)
+t/write_binary.t
+META.yml                                 Module YAML meta-data (added by 
MakeMaker)
+META.json                                Module JSON meta-data (added by 
MakeMaker)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/META.json 
new/Mac-PropertyList-1.38/META.json
--- old/Mac-PropertyList-1.37/META.json 1970-01-01 01:00:00.000000000 +0100
+++ new/Mac-PropertyList-1.38/META.json 2012-10-23 22:45:09.000000000 +0200
@@ -0,0 +1,47 @@
+{
+   "abstract" : "work with Mac plists at a low level",
+   "author" : [
+      "brian d foy <[email protected]>"
+   ],
+   "dynamic_config" : 1,
+   "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter 
version 2.112150",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec";,
+      "version" : "2"
+   },
+   "name" : "Mac-PropertyList",
+   "no_index" : {
+      "directory" : [
+         "t",
+         "inc"
+      ]
+   },
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : 0
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : 0
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "MIME::Base64" : 0,
+            "Math::BigInt" : 0,
+            "Scalar::Util" : "1.11",
+            "Test::More" : 0,
+            "Time::Local" : 0,
+            "XML::Entities" : 0,
+            "parent" : 0
+         }
+      }
+   },
+   "release_status" : "stable",
+   "version" : "1.38"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/META.yml 
new/Mac-PropertyList-1.38/META.yml
--- old/Mac-PropertyList-1.37/META.yml  2012-08-30 18:40:08.000000000 +0200
+++ new/Mac-PropertyList-1.38/META.yml  2012-10-23 22:45:09.000000000 +0200
@@ -1,26 +1,28 @@
---- #YAML:1.0
-name:               Mac-PropertyList
-version:            1.37
-abstract:           work with Mac plists at a low level
+---
+abstract: 'work with Mac plists at a low level'
 author:
-    - brian d foy <[email protected]>
-license:            perl
-distribution_type:  module
-configure_requires:
-    ExtUtils::MakeMaker:  0
+  - 'brian d foy <[email protected]>'
 build_requires:
-    ExtUtils::MakeMaker:  0
-requires:
-    Math::BigInt:   0
-    MIME::Base64:   0
-    parent:         0
-    Test::More:     0
-    XML::Entities:  0
-no_index:
-    directory:
-        - t
-        - inc
-generated_by:       ExtUtils::MakeMaker version 6.55_02
+  ExtUtils::MakeMaker: 0
+configure_requires:
+  ExtUtils::MakeMaker: 0
+dynamic_config: 1
+generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 
2.112150'
+license: perl
 meta-spec:
-    url:      http://module-build.sourceforge.net/META-spec-v1.4.html
-    version:  1.4
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
+name: Mac-PropertyList
+no_index:
+  directory:
+    - t
+    - inc
+requires:
+  MIME::Base64: 0
+  Math::BigInt: 0
+  Scalar::Util: 1.11
+  Test::More: 0
+  Time::Local: 0
+  XML::Entities: 0
+  parent: 0
+version: 1.38
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/MYMETA.json 
new/Mac-PropertyList-1.38/MYMETA.json
--- old/Mac-PropertyList-1.37/MYMETA.json       1970-01-01 01:00:00.000000000 
+0100
+++ new/Mac-PropertyList-1.38/MYMETA.json       2012-10-23 22:45:09.000000000 
+0200
@@ -0,0 +1,47 @@
+{
+   "abstract" : "work with Mac plists at a low level",
+   "author" : [
+      "brian d foy <[email protected]>"
+   ],
+   "dynamic_config" : 0,
+   "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter 
version 2.112150",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec";,
+      "version" : "2"
+   },
+   "name" : "Mac-PropertyList",
+   "no_index" : {
+      "directory" : [
+         "t",
+         "inc"
+      ]
+   },
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : 0
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : 0
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "MIME::Base64" : 0,
+            "Math::BigInt" : 0,
+            "Scalar::Util" : "1.11",
+            "Test::More" : 0,
+            "Time::Local" : 0,
+            "XML::Entities" : 0,
+            "parent" : 0
+         }
+      }
+   },
+   "release_status" : "stable",
+   "version" : "1.38"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/MYMETA.yml 
new/Mac-PropertyList-1.38/MYMETA.yml
--- old/Mac-PropertyList-1.37/MYMETA.yml        1970-01-01 01:00:00.000000000 
+0100
+++ new/Mac-PropertyList-1.38/MYMETA.yml        2012-10-23 22:45:09.000000000 
+0200
@@ -0,0 +1,28 @@
+---
+abstract: 'work with Mac plists at a low level'
+author:
+  - 'brian d foy <[email protected]>'
+build_requires:
+  ExtUtils::MakeMaker: 0
+configure_requires:
+  ExtUtils::MakeMaker: 0
+dynamic_config: 0
+generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 
2.112150'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
+name: Mac-PropertyList
+no_index:
+  directory:
+    - t
+    - inc
+requires:
+  MIME::Base64: 0
+  Math::BigInt: 0
+  Scalar::Util: 1.11
+  Test::More: 0
+  Time::Local: 0
+  XML::Entities: 0
+  parent: 0
+version: 1.38
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/Makefile.PL 
new/Mac-PropertyList-1.38/Makefile.PL
--- old/Mac-PropertyList-1.37/Makefile.PL       2012-08-30 18:40:07.000000000 
+0200
+++ new/Mac-PropertyList-1.38/Makefile.PL       2012-10-23 22:45:08.000000000 
+0200
@@ -16,6 +16,8 @@
                'Math::BigInt'  => '0',
                'MIME::Base64'  => '0',
                'Test::More'    => '0',
+               'Time::Local'   => '0',
+               'Scalar::Util'  => '1.11',
                'XML::Entities' => '0',
                'parent'        => '0',
                },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mac-PropertyList-1.37/lib/Mac/PropertyList/ReadBinary.pm 
new/Mac-PropertyList-1.38/lib/Mac/PropertyList/ReadBinary.pm
--- old/Mac-PropertyList-1.37/lib/Mac/PropertyList/ReadBinary.pm        
2012-08-30 18:40:07.000000000 +0200
+++ new/Mac-PropertyList-1.38/lib/Mac/PropertyList/ReadBinary.pm        
2012-10-23 22:45:08.000000000 +0200
@@ -13,7 +13,7 @@
 use POSIX             qw(SEEK_END SEEK_SET);
 use XML::Entities     ();
 
-$VERSION = '1.37';
+$VERSION = '1.38';
 
 __PACKAGE__->_run( @ARGV ) unless caller;
 
@@ -391,7 +391,7 @@
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright (c) 2004-2012 brian d foy.  All rights reserved.
+Copyright © 2004-2012 brian d foy.  All rights reserved.
 
 This program is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mac-PropertyList-1.37/lib/Mac/PropertyList/WriteBinary.pm 
new/Mac-PropertyList-1.38/lib/Mac/PropertyList/WriteBinary.pm
--- old/Mac-PropertyList-1.37/lib/Mac/PropertyList/WriteBinary.pm       
1970-01-01 01:00:00.000000000 +0100
+++ new/Mac-PropertyList-1.38/lib/Mac/PropertyList/WriteBinary.pm       
2012-10-23 22:45:08.000000000 +0200
@@ -0,0 +1,459 @@
+package Mac::PropertyList::WriteBinary;
+use strict;
+use warnings;
+
+use vars qw( $VERSION @EXPORT_OK );
+
+use Encode              ();
+use Mac::PropertyList   ();
+use base                qw(Exporter);
+
+=encoding utf8
+
+=head1 NAME
+
+Mac::PropertyList::WriteBinary - pack data into a Mac "binary property list"
+
+=head1 SYNOPSIS
+
+    use Mac::PropertyList::WriteBinary;
+
+    my $data = new Mac::PropertyList::dict({ ... => ... });
+    my $buf = Mac::PropertyList::WriteBinary::as_string($data);
+
+=head1 DESCRIPTION
+
+The C<as_string> function converts a property list structure
+(composed of instances of C<Mac::PropertyList::dict>,
+C<Mac::PropertyList::integer>, etc.)  into a binary format compatible
+with the Apple CoreFoundation binary property list functions.
+
+It takes a single argument, the top-level object to write, and returns
+a byte string.
+
+The property list can contain the following perl objects:
+
+=over 4
+
+=item C<Mac::PropertyList> value objects
+
+These are written according to their class.
+
+=item Unblessed references to Perl lists and hashes
+
+These are written as arrays and dictionaries, respectively.
+
+=item Perl scalars
+
+All Perl scalars are written as strings; this is similar to the behavior
+of writing an oldstyle OpenStep property list, which does not
+distinguish between numbers and strings, and then reading it using
+CoreFoundation functions.
+
+=item C<undef>
+
+This is written as the null object. CoreFoundation will read this as
+C<kCFNull>, but appears to be unable to write it.
+
+=back
+
+Strings are uniqued (two equal strings will be written as references
+to the same object). If the same reference appears more than once in
+the structure, it will likewise only be represented once in the
+output. Although the bplist format can represent circular data
+structures, they cannot be written by this module (they will be
+detected and result in an error — they wouldn't be read correctly by
+CoreFoundation anyway, so you aren't missing much).
+
+=head1 BUGS
+
+C<Mac::PropertyList::date> objects are not handled yet.
+
+Objects other than strings (and null) are not uniqued by value,
+only by reference equality. This may change in a future version.
+
+Perl's dictionary keys can only be strings, but a bplist's can be
+any scalar object.
+
+There is no way to write the C<UID> objects used by the keyed archiver.
+
+Perls that do not use IEEE-754 format internally for floating point
+numbers will produce incorrect output.
+
+=cut
+
+use constant {
+    header       => 'bplist00',
+
+    tagInteger   => 0x10,
+    tagFloat     => 0x20,
+    tagDate      => 0x30,
+    tagData      => 0x40,
+    tagASCII     => 0x50,
+    tagUTF16     => 0x60,
+    tagUID       => 0x80,
+    tagArray     => 0xA0,
+    tagSet       => 0xC0,
+    tagDict      => 0xD0,
+
+    # If we can actually represent an integer close to 2^64 with full
+    # precision and pack it with 'Q', then we can use that
+    havePack64   => ( eval { pack('Q>', 1153202979583557643) eq 
"\x10\x01\0\0\0\0\0\x0B" } ? 1 : 0 ),
+};
+
+$VERSION = '1.38';
+@EXPORT_OK = qw( as_string );
+
+sub as_string {
+    my($value) = @_;
+    my($ctxt) = _create_fragments($value);
+    my(@offsets, $xref_offset, $offset_size);
+
+    # The header (magic number and version, which is 00)
+    my($buf) = header;
+
+    # Write each fragment, making note of its offset in the file
+    foreach my $objid (0 .. $ctxt->{nextid}-1) {
+        $offsets[$objid] = length $buf;
+        $buf .= $ctxt->{fragments}->{$objid};
+    }
+
+    # ... and the offset of the beginning of the offsets table
+    $xref_offset = length $buf;
+
+    # Figure out how many bytes to use to represent file offsets,
+    # and append the offset table
+    if ($xref_offset < 256) {
+        $buf .= pack('C*', @offsets);
+        $offset_size = 1;
+    } elsif ($xref_offset < 65536) {
+        $buf .= pack('n*', @offsets);
+        $offset_size = 2;
+    } else {
+        $buf .= pack('N*', @offsets);
+        $offset_size = 4;
+    }
+
+    # Write the file trailer
+    $buf .= pack('x5 CCC ' . ( havePack64? 'Q>' : 'x4N' ) x 3,
+                 0, $offset_size, $ctxt->{objref_size},
+                 $ctxt->{nextid}, $ctxt->{rootid}, $xref_offset);
+
+    $buf;
+}
+
+# sub to_file {
+#   To consider:
+#   It might be useful to have a version of &as_string which writes
+#   the fragments directly to a file handle without having to build a
+#   single large buffer in RAM. This would be more efficient for
+#   larger structures. On the other hand, if you're writing large
+#   structures with this module, you're already suffering needlessly,
+#   so perhaps it's not worth optimizing overmuch for that case.
+# }
+
+
+# _assign_id is the workhorse function which recursively
+# descends the data structure and assigns object ids to each node,
+# as well as creating fragments of the final file.
+sub _assign_id {
+    my($context, $value) = @_;
+
+    # The type of this value
+    my($tp) = ref $value;
+
+    # Unblessed scalars are either strings or undef.
+    if ($tp eq '') {
+        if (!defined $value) {
+            $context->{nullid} = $context->{nextid} ++
+                unless defined $context->{nullid};
+            return $context->{nullid};
+        } else {
+            $context->{strings}->{$value} = $context->{nextid} ++
+                unless exists $context->{strings}->{$value};
+            return $context->{strings}->{$value};
+        }
+    }
+
+    # If we reach here we know that $value is a ref. Keep a table of
+    # stringified refs, so that we can re-use the id of an object
+    # we've seen before.
+    if(exists $context->{refs}{$value}) {
+        my($thisid) = $context->{refs}->{$value};
+        die "Recursive data structure\n" unless defined $thisid;
+        return $thisid;
+    }
+    $context->{refs}->{$value} = undef;
+
+    # Serialize the object into $fragment if possible. Since we
+    # don't yet know how many bytes we will use to represent object
+    # ids in the final file, don't serialize those yet--- keep them
+    # as a list of integers for now.
+    my($fragment, @objrefs);
+
+    if($tp eq 'ARRAY') {
+        $fragment = _counted_header(tagArray, scalar @$value);
+        @objrefs = map { $context->_assign_id($_) } @$value;
+    } elsif($tp eq 'HASH') {
+        my(@ks) = sort (CORE::keys %$value);
+        $fragment = _counted_header(tagDict, scalar @ks);
+        @objrefs = ( ( map { $context->_assign_id($_) } @ks ),
+                     ( map { $context->_assign_id($value->{$_}) } @ks ) );
+    } elsif(UNIVERSAL::can($tp, '_as_bplist_fragment')) {
+        ($fragment, @objrefs) = $value->_as_bplist_fragment($context);
+    } else {
+        die "Cannot serialize type '$tp'\n";
+    }
+
+    # As a special case, a fragment of 'undef' indicates that
+    # the object ID was already assigned.
+    return $objrefs[0] if !defined $fragment;
+
+    # Assign the next object ID to this object.
+    my($thisid) = $context->{nextid} ++;
+    $context->{refs}->{$value} = $thisid;
+
+    # Store the fragment and unpacked object references (if any).
+    $context->{fragments}->{$thisid} = $fragment;
+    $context->{objrefs}->{$thisid} = \@objrefs if @objrefs;
+
+    return $thisid;
+}
+
+sub _create_fragments {
+    my ($value) = @_;
+
+    # Set up the state needed by _assign_id
+
+    my ($ctxt) = bless({
+        nextid => 0,       # The next unallocated object ID
+        nullid => undef,   # The object id of 'null'
+        strings => { },    # Maps string values to object IDs
+        refs => { },       # Maps stringified refs to object IDs
+        fragments => { },  # Maps object IDs to bplist fragments, except 
object lists
+        objrefs => { },    # Maps object IDs to objref lists
+    });
+
+    # Traverse the data structure, and remember the id of the root object
+    $ctxt->{rootid} = $ctxt->_assign_id($value);
+
+    # Figure out how many bytes to use to represent an object id.
+    my ($objref_pack);
+    if ($ctxt->{nextid} < 256) {
+        $objref_pack = 'C*';
+        $ctxt->{objref_size} = 1;
+    } elsif ($ctxt->{nextid} < 65536) {
+        $objref_pack = 'n*';
+        $ctxt->{objref_size} = 2;
+    } else {
+        $objref_pack = 'N*';
+        $ctxt->{objref_size} = 4;
+    }
+
+    my($objid, $reflist, $stringval);
+
+    # Append the unformatted object ids to their corresponding fragments,
+    # now that we know how to pack them.
+    while (($objid, $reflist) = each %{$ctxt->{objrefs}}) {
+        $ctxt->{fragments}->{$objid} .= pack($objref_pack, @$reflist);
+    }
+    delete $ctxt->{objrefs};
+
+    # Create fragments for all the strings.
+    # TODO: If &to_file is written, it would be worth
+    # breaking this out so that the conversion can be done on the
+    # fly without keeping all of the converted strings in memory.
+    {
+        my($ascii) = Encode::find_encoding('ascii');
+        my($utf16be) = Encode::find_encoding('UTF-16BE');
+
+        while (($stringval, $objid) = each %{$ctxt->{strings}}) {
+            my($fragment);
+
+            # Strings may be stored as ASCII (7 bits) or UTF-16-bigendian.
+            if ($stringval =~ /\A[\x01-\x7E]*\z/s) {
+                # The string is representable in ASCII.
+                $fragment = $ascii->encode($stringval);
+                $fragment = _counted_header(tagASCII, length $fragment) . 
$fragment;
+            } else {
+                $fragment = $utf16be->encode($stringval);
+                $fragment = _counted_header(tagUTF16, (length $fragment)/2) . 
$fragment;
+            }
+
+            $ctxt->{fragments}->{$objid} = $fragment;
+        }
+    }
+
+    # If there's a <null> in the file, create its fragment.
+    $ctxt->{fragments}->{$ctxt->{nullid}} = "\x00"
+        if defined $ctxt->{nullid};
+
+    $ctxt;
+}
+
+sub _counted_header {
+    my ($typebyte, $count) = @_;
+
+    # Datas, strings, and container objects have a count/size encoded
+    # in the lower 4 bits of their type byte. If the count doesn't fit
+    # in 4 bits, the bits are set to all-1s and the actual value
+    # follows, encoded as an integer (including the integer's
+    # own type byte).
+
+    if ($count < 15) {
+        return pack('C',    $typebyte + $count);
+    } else {
+        return pack('C',    $typebyte + 15) . &_pos_integer($count);
+    }
+}
+
+sub _pos_integer {
+    my($count) = @_;
+
+    if ($count < 256) {
+        return pack('CC',  tagInteger + 0, $count);
+    } elsif ($count < 65536) {
+        return pack('CS>', tagInteger + 1, $count);
+    } elsif (havePack64 && ($count > 4294967295)) {
+        return pack('Cq>', tagInteger + 3, $count);
+    } else {
+        return pack('CN',  tagInteger + 2, $count);
+    }
+}
+
+package Mac::PropertyList::array;
+
+sub _as_bplist_fragment {
+    my($context, @items) = ( $_[1], $_[0]->value );
+    @items = map { $context->_assign_id($_) } @items;
+
+    return ( 
Mac::PropertyList::WriteBinary::_counted_header(Mac::PropertyList::WriteBinary::tagArray,
 scalar @items),
+             @items );
+}
+
+package Mac::PropertyList::dict;
+
+sub _as_bplist_fragment {
+    my($self, $context) = @_;
+    my($value) = scalar $self->value;  # Returns a ref in scalar context
+    my(@keys) = sort (CORE::keys %$value);
+
+    return ( 
Mac::PropertyList::WriteBinary::_counted_header(Mac::PropertyList::WriteBinary::tagDict,
 scalar @keys),
+             ( map { $context->_assign_id($_) } @keys ),
+             ( map { $context->_assign_id($value->{$_}) } @keys ));
+
+}
+
+package Mac::PropertyList::date;
+
+use Scalar::Util ( 'looks_like_number' );
+use Time::Local  ( 'timegm' );
+
+sub _as_bplist_fragment {
+    my($value) = scalar $_[0]->value;
+    my($posixval);
+
+    if (looks_like_number($value)) {
+        $posixval = $value;
+    } elsif ($value =~ 
/\A(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d)\:(\d\d)\:(\d\d(?:\.\d+)?)Z\z/) {
+        $posixval = timegm($6, $5, $4, $3, $2 - 1, $1);
+    } else {
+        die "Invalid plist date '$value'\n";
+    }
+
+    # Dates are simply stored as floating-point numbers (seconds since the
+    # start of the CoreFoundation epoch) with a different tag value.
+    # See the notes in Mac::PropertyList::real on float format.
+    return pack('Cd>', Mac::PropertyList::WriteBinary::tagDate + 3,
+                $posixval - 978307200);
+}
+
+package Mac::PropertyList::real;
+
+# Here we're assuming that the 'd' format for pack produces
+# an IEEE-754 double-precision (64-bit) floating point
+# representation, because ... it does on practically every
+# system. However, this will not be portable to systems which
+# don't natively use IEEE-754 format!
+
+sub _as_bplist_fragment {
+    my($self) = shift;
+
+    return pack('Cd>', Mac::PropertyList::WriteBinary::tagFloat + 3, 
$self->value);
+}
+
+package Mac::PropertyList::integer;
+
+use constant tagInteger => 0x10;
+
+sub _as_bplist_fragment {
+    my($value) = $_[0]->value;
+
+    # Per comments in CFBinaryPList.c, only 8-byte integers (and
+    # 16-byte integers, if they're supported, which they're not) are
+    # interpreted as signed. Shorter integers are always unsigned.
+    # Therefore all negative numbers must be written as 8-byte
+    # integers.
+
+    if ($value < 0) {
+        if (Mac::PropertyList::WriteBinary::havePack64) {
+            return pack('Cq>', tagInteger + 3, $value);
+        } else {
+            return pack('CSSl>', tagInteger + 3, 65535, 65535, $value);
+        }
+    } else {
+        return Mac::PropertyList::WriteBinary::_pos_integer($value);
+    }
+}
+
+package Mac::PropertyList::string;
+
+sub _as_bplist_fragment {
+    # Returning a fragment of 'undef' indicates we've already assigned
+    # an object ID.
+    return ( undef, $_[1]->_assign_id($_[0]->value) );
+}
+
+package Mac::PropertyList::ustring;
+
+sub _as_bplist_fragment {
+    # Returning a fragment of 'undef' indicates we've already assigned
+    # an object ID.
+    return ( undef, $_[1]->_assign_id($_[0]->value) );
+}
+
+package Mac::PropertyList::data;
+
+sub _as_bplist_fragment {
+    my($value) = $_[0]->value;
+    return 
(&Mac::PropertyList::WriteBinary::_counted_header(Mac::PropertyList::WriteBinary::tagData,
 length $value) .
+            $value);
+}
+
+package Mac::PropertyList::true;
+
+sub _as_bplist_fragment { return "\x09"; }
+
+package Mac::PropertyList::false;
+
+sub _as_bplist_fragment { return "\x08"; }
+
+=head1 AUTHOR
+
+Wim Lewis, C<< <[email protected]> >>
+
+Copyright E<copy> 2012 Wim Lewis.  All rights reserved.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Mac::PropertyList::ReadBinary> for the inverse operation.
+
+Apple's partial published CoreFoundation source code:
+L<http://opensource.apple.com/source/CF/>
+
+=cut
+
+"One more thing";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/lib/Mac/PropertyList.pm 
new/Mac-PropertyList-1.38/lib/Mac/PropertyList.pm
--- old/Mac-PropertyList-1.37/lib/Mac/PropertyList.pm   2012-08-30 
18:40:07.000000000 +0200
+++ new/Mac-PropertyList-1.38/lib/Mac/PropertyList.pm   2012-10-23 
22:45:08.000000000 +0200
@@ -24,7 +24,7 @@
        'all' => \@EXPORT_OK,
        );
 
-$VERSION = '1.37';
+$VERSION = '1.38';
 
 =encoding utf8
 
@@ -840,7 +840,7 @@
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright (c) 2004-2012 brian d foy.  All rights reserved.
+Copyright © 2004-2012 brian d foy.  All rights reserved.
 
 This program is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/t/test_manifest 
new/Mac-PropertyList-1.38/t/test_manifest
--- old/Mac-PropertyList-1.37/t/test_manifest   2012-08-30 18:40:07.000000000 
+0200
+++ new/Mac-PropertyList-1.38/t/test_manifest   2012-10-23 22:45:08.000000000 
+0200
@@ -16,4 +16,5 @@
 false_key.t
 basic_types.t
 read_binary.t
+write_binary.t
 as_perl.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mac-PropertyList-1.37/t/write_binary.t 
new/Mac-PropertyList-1.38/t/write_binary.t
--- old/Mac-PropertyList-1.37/t/write_binary.t  1970-01-01 01:00:00.000000000 
+0100
+++ new/Mac-PropertyList-1.38/t/write_binary.t  2012-10-23 22:45:08.000000000 
+0200
@@ -0,0 +1,209 @@
+use strict;
+use warnings;
+use utf8;
+
+use Data::Dumper;
+$Data::Dumper::Useqq = 1;
+
+our($val, $expect);
+
+use Test::More tests => 38;
+
+BEGIN {
+    my $class = 'Mac::PropertyList::WriteBinary';
+    
+    use_ok( $class, qw( as_string ) );
+    can_ok( $class, qw( as_string ) );
+}
+
+use Mac::PropertyList ();
+
+# Test basic (scalar) data types. Make a single-object plist
+# containing each one and compare it to the expected representation.
+sub testrep {
+    my($tp, $arg, $frag) = @_;
+    my ($pkg, $fn, $ln) = caller;
+
+    my($val) = "Mac::PropertyList::$tp"->new($arg);
+    my($bplist) = as_string($val);
+    my($expected) = "bplist00" . $frag . 
+        pack('C x6 CC x4N x4N x4N',
+             8,    # Offset table: offset of only object
+             1, 1, # Byte sizes of offsets and of object IDs
+             1,    # Number of objects
+             0,    # ID of root (only) object
+             8 + length($frag)  # Start offset of offset table
+        );
+ 
+     is($bplist, $expected, "basic datatype '$tp', line $ln")
+         || diag ( Data::Dumper->Dump([$val, $bplist, $expected], ['value', 
'got', 'exp']) );
+}
+
+# The fragments here were generated by the Mac OS X 'plutil' command.
+
+&testrep( real => 1,    "\x23\x3f\xf0\x00\x00\x00\x00\x00\x00" );
+&testrep( real => 0.5,  "\x23\x3f\xe0\x00\x00\x00\x00\x00\x00" );
+&testrep( real => 2,    "\x23\x40\x00\x00\x00\x00\x00\x00\x00" );
+&testrep( real => -256, "\x23\xC0\x70\x00\x00\x00\x00\x00\x00" );
+&testrep( real => -257, "\x23\xC0\x70\x10\x00\x00\x00\x00\x00" );
+
+&testrep( integer => 0,      "\x10\x00" );
+&testrep( integer => 1,      "\x10\x01" );
+&testrep( integer => 255,    "\x10\xFF" );
+&testrep( integer => 256,    "\x11\x01\x00" );
+&testrep( integer => 65535,  "\x11\xFF\xFF" );
+&testrep( integer => 65536,  "\x12\x00\x01\x00\x00" );
+&testrep( integer => -1,     "\x13\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" );
+&testrep( integer => -255,   "\x13\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01" );
+
+&testrep( string => "Hi!",   "\x53\x48\x69\x21" );
+&testrep( string => "",      "\x50" );
+&testrep( string => 'FifteenCharLong',
+                             "\x5F\x10\x0FFifteenCharLong" );
+&testrep( string => "Uni\x{2013}Code",
+                             "\x68\0U\0n\0i\x20\x13\0C\0o\0d\0e" );
+
+# Dates: test the respective epochs
+&testrep( date => '1970-01-01T00:00:00Z', 
"\x33\xC1\xCD\x27\xE4\x40\x00\x00\x00");
+&testrep( date => '2001-01-01T00:00:00Z', 
"\x33\x00\x00\x00\x00\x00\x00\x00\x00");
+# and a few more dates for good measure
+&testrep( date => '2010-07-01T22:33:44Z', 
"\x33\x41\xB1\xDD\x4F\x48\x00\x00\x00");
+&testrep( date => 987654321,              
"\x33\x41\x61\xd4\x06\x20\x00\x00\x00");
+
+&testrep( data => '',        "\x40" );
+&testrep( data => "\0\xFF",  "\x42\x00\xFF" );
+&testrep( data => 'Fourteen Chars',
+                             "\x4EFourteen\x20Chars" );
+
+&testrep( true  => 1,        "\x09" );
+&testrep( false => 0,        "\x08" );
+
+&testrep( array => [],       "\xA0" );
+&testrep( dict => {},        "\xD0" );
+
+# The null object is part of the specification but rarely if ever used;
+# Apple's CFBinaryPList implementation of it appears to never have
+# been finished anyway.
+is( as_string(undef),
+    "bplist00\x00\x08".
+    "\0\0\0\0\0\0\x01\x01".
+    "\0\0\0\0\0\0\0\x01".
+    "\0\0\0\0\0\0\0\0".
+    "\0\0\0\0\0\0\0\x09",
+    'the null object' );
+
+##
+# Slightly more complex data structures. There is a lot of arbitrariness
+# in the bplist format (e.g., object IDs can be assigned in any order
+# without affecting the represented structure), so we're just testing
+# against one of possibly many equally good representations.
+
+sub ints {
+    map { Mac::PropertyList::integer->new($_) } @_;
+}
+
+$val = as_string([ &ints(1, 10, 100) ]);
+$expect = 'bplist00' .            # header
+          "\x10\x01" .            # int 1
+          "\x10\x0A" .            # int 10
+          "\x10\x64" .            # int 100
+          "\xA3\x00\x01\x02" .    # array
+          "\x08\x0A\x0C\x0E" .    # offsets
+          "\0\0\0\0\0\0\x01\x01" .  # sizes
+          "\0\0\0\0\0\0\0\x04" .  # object count
+          "\0\0\0\0\0\0\0\x03" .  # rootid
+          "\0\0\0\0\0\0\0\x12";   # offset-offset
+
+is($val, $expect, 'simple arrayref') || diag Dumper([$val, $expect]);
+
+$val = as_string({ 'Foo' => Mac::PropertyList::integer->new(108),
+                   'Z'   => 'Foo' });
+$expect = 'bplist00' .            # header
+          "\x53Foo" .             # string Foo
+          "\x51Z" .               # string Z
+          "\x10\x6C" .            # int 108
+          "\xD2\x00\x01\x02\x00" . # dict (0,1)=>(2,0)
+          "\x08\x0C\x0E\x10" .    # offsets
+          "\0\0\0\0\0\0\x01\x01" .  # sizes
+          "\0\0\0\0\0\0\0\x04" .  # object count
+          "\0\0\0\0\0\0\0\x03" .  # rootid
+          "\0\0\0\0\0\0\0\x15";   # offset-offset
+is($val, $expect, 'simple hashref') || diag Dumper([$val, $expect]);
+
+$val = as_string( Mac::PropertyList::dict->new({
+    'Foo' => Mac::PropertyList::integer->new(108),
+    'Z'   => 'Foo'
+                                                   }));
+is($val, $expect, 'simple dict') || diag Dumper([$val, $expect]);
+
+
+{
+    my($d1) = Mac::PropertyList::dict->new({ 'A' => &ints(1),
+                                             'B' => &ints(2) });
+    my($t)  = Mac::PropertyList::true->new();
+    my($d2) = Mac::PropertyList::dict->new({ 'A' => [ $t, $t, undef ],
+                                             'B' => $d1 });
+
+    $val = as_string( Mac::PropertyList::array->new([$d1, $d2, $d2]) );
+}
+$expect = 'bplist00' .            # header
+          "\x51A" .               # string A
+          "\x51B" .               # string B
+          "\x10\x01" .            # int 1
+          "\x10\x02" .            # int 2
+          "\xD2\x00\x01\x02\x03" . # dict (0,1)=>(2,3)
+          "\x09" .                # true
+          "\x00" .                # null
+          "\xA3\x05\x05\x06" .    # array (5,5,6)
+          "\xD2\x00\x01\x07\x04". # dict (0,1)=>(7,4)
+          "\xA3\x04\x08\x08".     # array (4,8,8)
+          "\x08\x0A\x0C\x0E\x10\x15\x16\x17\x1B\x20" .    # offsets
+          "\0\0\0\0\0\0\x01\x01" .  # sizes
+          "\0\0\0\0\0\0\0\x0A" .  # object count
+          "\0\0\0\0\0\0\0\x09" .  # rootid
+          "\0\0\0\0\0\0\0\x24";   # offset-offset
+is($val, $expect, 'more complex structure') || diag Dumper([$val, $expect]);
+
+{
+    # Testing items which are long enough to require 2-byte
+    # offsets. WriteBinary will currently use 4-byte offsets,
+    # although 3-byte offsets are valid and presumably better.
+    my($s1) = Mac::PropertyList::string->new( ( 'π' x 128 ) . ( 'p' x 128 ) );
+    my($s2) = Mac::PropertyList::string->new( ( '¢' x 128 ) );
+    my($bplist) = as_string([ $s1, $s2 ]);
+    my($expected) = 'bplist00'.
+                    "\x6F\x11\x01\x00" .   # 256 characters in this string
+                    ( "\x03\xC0" x 128 ) .
+                    ( "\x00\x70" x 128 ) .
+                    "\x6F\x10\x80" .       # 128 characters in this string
+                    ( "\x00\xA2" x 128 ) .
+                    "\xA2\x00\x01" .       # 2-element array
+                    "\x00\x08\x02\x0C\x03\x0F" .  # offsets table
+                    "\0\0\0\0\0\0\x02\x01" . # sizes
+                    "\0\0\0\0\0\0\x00\x03" . # count
+                    "\0\0\0\0\0\0\x00\x02" . # root object
+                    "\0\0\0\0\0\0\x03\x12";  # offset of offset table
+    is($bplist, $expected, "large (>256byte) object offsets")
+        || diag Dumper([$bplist, $expected]);
+}
+
+##
+# Test some unwritable structures.
+#
+
+eval {
+    $val = as_string( [ sub { 32; } ] );
+};
+isnt($@, '', "writing a subroutine reference should fail");
+
+{
+    my($d1) = { 'A' => 'aye', 'B' => 'bee' };
+    my($d2) = { 'A' => 'aye', 'B' => $d1 };
+    $d1->{B} = $d2;
+    
+    eval { $val = as_string($d1); };
+    like($@, qr/Recursive/, "recursive data structure should fail");
+}
+
+
+1;

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to