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]