Palm-1.400/0000755000175000017500000000000012501047366010517 5ustar cjmcjmPalm-1.400/xt/0000755000175000017500000000000012501047366011152 5ustar cjmcjmPalm-1.400/xt/release/0000755000175000017500000000000012501047366012572 5ustar cjmcjmPalm-1.400/xt/release/pod-coverage.t0000644000175000017500000000033412501047366015332 0ustar cjmcjm#!perl # This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests. use Test::Pod::Coverage 1.08; use Pod::Coverage::TrustPod; all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); Palm-1.400/xt/release/pod-syntax.t0000644000175000017500000000022012501047366015057 0ustar cjmcjm#!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Palm-1.400/examples/0000755000175000017500000000000012501047366012335 5ustar cjmcjmPalm-1.400/examples/add-memo0000644000175000017500000000436312501047366013751 0ustar cjmcjm#!/usr/bin/perl # $Id: add-memo,v 3.1 2002/02/08 13:55:59 arensb Exp $ use strict; use Palm::Memo; use vars qw( $category $fname $pdb $cat_id $memo_text ); # Set default values $category = undef; # Default category to add to: "Unfiled" $cat_id = 0; # Default category index is 0 $fname = "$ENV{HOME}/.palm/backup/MemoDB.pdb"; # Default file to modify # Parse command-line arguments # XXX - Ought to read ~/.add-memo.args or some such: this should # contain the default command-line arguments. read it, split into # arguments, and prepend to @ARGV. Then continue as below. while ($ARGV[0] =~ /^-./) { my $arg = shift; if ($arg eq "-h" or $arg eq "-help" or $arg eq "--help") { &usage; exit 0; } if ($arg eq "-c") # Set category { $category = shift; if (!defined($category)) { print STDERR "Error: -c argument requires an argument.\n"; &usage; exit 1; } next; } if ($arg eq "-f") # Specify PDB file { $fname = shift; if (!defined($fname)) { print STDERR "Error: -f argument requires an argument.\n"; &usage; exit 1; } next; } } $pdb = new Palm::PDB; $pdb->Load($fname); # Given a category name, set $cat_id to its index. if ($category eq "") { # No category specified. Default to "Unfiled" $cat_id = 0; } else { # Find the named category my $i; for ($i = 0; $i <= 16; $i++) { if ($pdb->{appinfo}{categories}[$i]{name} eq $category) { $cat_id = $i; last; } } if ($i >= 16) { # No such category print STDERR "Warning: can't find category \"$category\".\n", "Defaulting to \"Unfiled\".\n"; } } $memo_text = ""; # This loop might iterate over several files while (<>) { # XXX - If input file is STDIN, perhaps ought to print a # message saying to hit at EOF. Then again, that's # not the Unix way. $memo_text .= $_; if (eof(ARGV)) { # End of current file. Append the current record to # the PDB, and reset $memo_text for the next file. my $record; $record = $pdb->append_Record; $record->{data} = $memo_text; $record->{category} = $cat_id; $memo_text = ""; } } $pdb->Write($fname); # usage # Print a usage message sub usage { print < Load (e.g., -MPalm::Address) EOT #' exit 0; } elsif ($arg =~ /^-M/) { eval "use $';"; } elsif ($arg eq "-nohex") { $hexdump = 0; } else { die "Unrecognized option: $arg\n"; } } my $fname = shift; die "No such file: $fname\n" if ! -f $fname; my $EPOCH_1904 = 2082844800; # Difference between Palm's # epoch (Jan. 1, 1904) and # Unix's epoch (Jan. 1, 1970), # in seconds. my $HeaderLen = 32+2+2+(9*4); # Size of database header my $RecIndexHeaderLen = 6; # Size of record index header my $IndexRecLen = 8; # Length of record index entry my $IndexRsrcLen = 10; # Length of resource index entry #%PDBHandlers = (); # Record handler map #%PRCHandlers = (); # Resource handler map #&Palm::PDB::rawread($fname); &rawread($fname); #package Palm::PDB; # XXX - Gross hack! sub rawread { my $self = new Palm::Raw; my $fname = shift; # Filename to read from my $buf; # Buffer into which to read stuff # Open database file open PDB, "< $fname" or die "Can't open \"$fname\": $!\n"; binmode PDB; # Parse as binary file under MS-DOS # Get the size of the file. It'll be useful later seek PDB, 0, 2; # 2 == SEEK_END. Seek to the end. $self->{_size} = tell PDB; print "File size: $self->{_size}\n"; seek PDB, 0, 0; # 0 == SEEK_START. Rewind to the beginning. # Read header my $name; my $attributes; my $version; my $ctime; my $mtime; my $baktime; my $modnum; my $appinfo_offset; my $sort_offset; my $type; my $creator; my $uniqueIDseed; read PDB, $buf, $HeaderLen; # Read the PDB header print "Database header:\n"; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # Split header into its component fields ($name, $attributes, $version, $ctime, $mtime, $baktime, $modnum, $appinfo_offset, $sort_offset, $type, $creator, $uniqueIDseed) = unpack "a32 n n N N N N N N a4 a4 N", $buf; ($self->{name} = $name) =~ s/\0*$//; $self->{attributes}{resource} = 1 if $attributes & 0x0001; $self->{attributes}{"read-only"} = 1 if $attributes & 0x0002; $self->{attributes}{"AppInfo dirty"} = 1 if $attributes & 0x0004; $self->{attributes}{backup} = 1 if $attributes & 0x0008; $self->{attributes}{"OK newer"} = 1 if $attributes & 0x0010; $self->{attributes}{reset} = 1 if $attributes & 0x0020; $self->{attributes}{open} = 1 if $attributes & 0x0040; $self->{attributes}{launchable} = 1 if $attributes & 0x0200; $self->{version} = $version; $self->{ctime} = $ctime - $EPOCH_1904; $self->{mtime} = $mtime - $EPOCH_1904; $self->{baktime} = $baktime - $EPOCH_1904; $self->{modnum} = $modnum; # _appinfo_offset and _sort_offset are private fields $self->{_appinfo_offset} = $appinfo_offset; $self->{_sort_offset} = $sort_offset; $self->{type} = $type; $self->{creator} = $creator; $self->{uniqueIDseed} = $uniqueIDseed; print <{attributes}{launchable}; print " OPEN" if $self->{attributes}{open}; print " RESET" if $self->{attributes}{reset}; print " OKNEWER" if $self->{attributes}{"OK newer"}; print " BACKUP" if $self->{attributes}{backup}; print " APPINFO-DIRTY" if $self->{attributes}{"AppInfo dirty"}; print " READ-ONLY" if $self->{attributes}{"read-only"}; print " RESOURCE" if $self->{attributes}{resource}; print "\n"; print <{attributes}{resource}) { # Look among resource handlers $handler = $PRCHandlers{$self->{creator}}{$self->{type}} || $PRCHandlers{undef}{$self->{type}} || $PRCHandlers{$self->{creator}}{""} || $PRCHandlers{""}{""}; } else { # Look among record handlers $handler = $PDBHandlers{$self->{creator}}{$self->{type}} || $PDBHandlers{""}{$self->{type}} || $PDBHandlers{$self->{creator}}{""} || $PDBHandlers{""}{""}; } if (defined($handler)) { bless $self, $handler; } else { # XXX - This should probably return 'undef' or something, # rather than die. die "No handler defined for creator \"$creator\", type \"$type\"\n"; } ## Read record/resource index # Read index header read PDB, $buf, $RecIndexHeaderLen; print "Record/resource index header:\n"; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } my $next_index; my $numrecs; ($next_index, $numrecs) = unpack "N n", $buf; $self->{_numrecs} = $numrecs; print <{attributes}{resource}) { &_load_rsrc_index($self, \*PDB); } else { &_load_rec_index($self, \*PDB); } # Ignore the two NUL bytes that are usually here. We'll seek() # around them later. # Read AppInfo block, if it exists if ($self->{_appinfo_offset} != 0) { &_load_appinfo_block($self, \*PDB); } # Read sort block, if it exists if ($self->{_sort_offset} != 0) { &_load_sort_block($self, \*PDB); } # Read record/resource list if ($self->{attributes}{resource}) { &_load_resources($self, \*PDB); } else { &_load_records($self, \*PDB); } # These keys were needed for parsing the file, but are not # needed any longer. Delete them. delete $self->{_index}; delete $self->{_numrecs}; delete $self->{_appinfo_offset}; delete $self->{_sort_offset}; delete $self->{_size}; close PDB; } # _load_rec_index # Private function. Read the record index, for a record database sub _load_rec_index { my $pdb = shift; my $fh = shift; # Input file handle my $i; my $lastoffset = 0; print "Record index:\n"; # Read each record index entry in turn for ($i = 0; $i < $pdb->{_numrecs}; $i++) { my $buf; # Input buffer print " Record index entry $i\n"; # Read the next record index entry my $offset; my $attributes; my @id; # Raw ID my $id; # Numerical ID my $entry = {}; # Parsed index entry read $fh, $buf, $IndexRecLen; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # The ID field is a bit weird: it's represented as 3 # bytes, but it's really a double word (long) value. ($offset, $attributes, @id) = unpack "N C C3", $buf; if ($offset == $lastoffset) { print STDERR "Record $i has same offset as previous one: $offset\n"; } $lastoffset = $offset; $entry->{offset} = $offset; $entry->{attributes}{expunged} = 1 if $attributes & 0x80; $entry->{attributes}{dirty} = 1 if $attributes & 0x40; $entry->{attributes}{deleted} = 1 if $attributes & 0x20; $entry->{attributes}{private} = 1 if $attributes & 0x10; $entry->{id} = ($id[0] << 16) | ($id[1] << 8) | $id[2]; # The lower 4 bits of the attributes field are # overloaded: If the record has been deleted and/or # expunged, then bit 0x08 indicates whether the record # should be archived. Otherwise (if it's an ordinary, # non-deleted record), the lower 4 bits specify the # category that the record belongs in. if (($attributes & 0xa0) == 0) { $entry->{category} = $attributes & 0x0f; } else { $entry->{attributes}{archive} = 1 if $attributes & 0x08; } print <{attributes}}]} Category: $entry->{category} ID: @{[sprintf("0x%02x%02x%02x", @id)]} EOT # Put this information on a temporary array push @{$pdb->{_index}}, $entry; } } # XXX - Make this print out debugging information # _load_rsrc_index # Private function. Read the resource index, for a resource database sub _load_rsrc_index { my $pdb = shift; my $fh = shift; # Input file handle my $i; print "Resource index:\n"; # Read each resource index entry in turn for ($i = 0; $i < $pdb->{_numrecs}; $i++) { my $buf; # Input buffer print " Resource index entry $i\n"; # Read the next resource index entry my $type; my $id; my $offset; my $entry = {}; # Parsed index entry read $fh, $buf, $IndexRsrcLen; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } ($type, $id, $offset) = unpack "a4 n N", $buf; $entry->{type} = $type; $entry->{id} = $id; $entry->{offset} = $offset; print <{_index}}, $entry; } } # _load_appinfo_block # Private function. Read the AppInfo block sub _load_appinfo_block { my $pdb = shift; my $fh = shift; # Input file handle my $len; # Length of AppInfo block my $buf; # Input buffer print "AppInfo block:\n"; # Sanity check: make sure we're positioned at the beginning of # the AppInfo block if (tell($fh) > $pdb->{_appinfo_offset}) { die "Bad AppInfo offset: expected ", sprintf("0x%08x", $pdb->{_appinfo_offset}), ", but I'm at ", tell($fh), "\n"; } # Seek to the right place, if necessary if (tell($fh) != $pdb->{_appinfo_offset}) { seek PDB, $pdb->{_appinfo_offset}, 0; } # There's nothing that explicitly gives the size of the # AppInfo block. Rather, it has to be inferred from the offset # of the AppInfo block (previously recorded in # $pdb->{_appinfo_offset}) and whatever's next in the file. # That's either the sort block, the first data record, or the # end of the file. if ($pdb->{_sort_offset}) { # The next thing in the file is the sort block $len = $pdb->{_sort_offset} - $pdb->{_appinfo_offset}; } elsif ((defined $pdb->{_index}) && @{$pdb->{_index}}) { # There's no sort block; the next thing in the file is # the first data record $len = $pdb->{_index}[0]{offset} - $pdb->{_appinfo_offset}; } else { # There's no sort block and there are no records. The # AppInfo block goes to the end of the file. $len = $pdb->{_size} - $pdb->{_appinfo_offset}; } # Read the AppInfo block read $fh, $buf, $len; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # Tell the real class to parse the AppInfo block $pdb->{appinfo} = $pdb->ParseAppInfoBlock($buf); # Print out the parsed values if (ref($pdb->{appinfo}) ne "") { &dumphash($pdb->{appinfo}, "\t"); print "\n"; } } # _load_sort_block # Private function. Read the sort block. sub _load_sort_block { my $pdb = shift; my $fh = shift; # Input file handle my $len; # Length of sort block my $buf; # Input buffer print "Sort block:\n"; # Sanity check: make sure we're positioned at the beginning of # the sort block if (tell($fh) > $pdb->{_sort_offset}) { die "Bad sort block offset: expected ", sprintf("0x%08x", $pdb->{_sort_offset}), ", but I'm at ", tell($fh), "\n"; } # Seek to the right place, if necessary if (tell($fh) != $pdb->{_sort_offset}) { seek PDB, $pdb->{_sort_offset}, 0; } # There's nothing that explicitly gives the size of the sort # block. Rather, it has to be inferred from the offset of the # sort block (previously recorded in $pdb->{_sort_offset}) # and whatever's next in the file. That's either the first # data record, or the end of the file. if (defined($pdb->{_index})) { # The next thing in the file is the first data record $len = $pdb->{_index}[0]{offset} - $pdb->{_sort_offset}; } else { # There are no records. The sort block goes to the end # of the file. $len = $pdb->{_size} - $pdb->{_sort_offset}; } # Read the AppInfo block read $fh, $buf, $len; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # XXX - Check to see if the sort block has some predefined # structure. If so, it might be a good idea to parse the sort # block here. # Tell the real class to parse the sort block $pdb->{sort} = $pdb->ParseSortBlock($buf); } # _load_records # Private function. Load the actual data records, for a record database # (PDB) sub _load_records { my $pdb = shift; my $fh = shift; # Input file handle my $i; print "Records:\n"; # Read each record in turn for ($i = 0; $i < $pdb->{_numrecs}; $i++) { my $len; # Length of record my $buf; # Input buffer print " Record $i\n"; # Sanity check: make sure we're where we think we # should be. if (tell($fh) > $pdb->{_index}[$i]{offset}) { # XXX - The two NULs are really optional. # die "Bad offset for record $i: expected ", # sprintf("0x%08x", # $pdb->{_index}[$i]{offset}), # " but it's at ", # sprintf("[0x%08x]", tell($fh)), "\n"; } # Seek to the right place, if necessary if (tell($fh) != $pdb->{_index}[$i]{offset}) { seek PDB, $pdb->{_index}[$i]{offset}, 0; } # Compute the length of the record: the last record # extends to the end of the file. The others extend to # the beginning of the next record. if ($i == $pdb->{_numrecs} - 1) { # This is the last record $len = $pdb->{_size} - $pdb->{_index}[$i]{offset}; } else { # This is not the last record $len = $pdb->{_index}[$i+1]{offset} - $pdb->{_index}[$i]{offset}; } # Read the record read $fh, $buf, $len; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # Tell the real class to parse the record data. Pass # &ParseRecord all of the information from the index, # plus a "data" field with the raw record data. my $record; $record = $pdb->ParseRecord( %{$pdb->{_index}[$i]}, "data" => $buf, ); push @{$pdb->{records}}, $record; # Print out the parsed values &dumphash($record, "\t"); print "\n"; } } # _load_resources # Private function. Load the actual data resources, for a resource database # (PRC) sub _load_resources { my $pdb = shift; my $fh = shift; # Input file handle my $i; print "Resources:\n"; # Read each resource in turn for ($i = 0; $i < $pdb->{_numrecs}; $i++) { my $len; # Length of record my $buf; # Input buffer print " Resource $i\n"; # Sanity check: make sure we're where we think we # should be. if (tell($fh) > $pdb->{_index}[$i]{offset}) { die "Bad offset for resource $i: expected ", sprintf("0x%08x", $pdb->{_index}[$i]{offset}), " but it's at ", sprintf("0x%08x", tell($fh)), "\n"; } # Seek to the right place, if necessary if (tell($fh) != $pdb->{_index}[$i]{offset}) { seek PDB, $pdb->{_index}[$i]{offset}, 0; } # Compute the length of the resource: the last # resource extends to the end of the file. The others # extend to the beginning of the next resource. if ($i == $pdb->{_numrecs} - 1) { # This is the last resource $len = $pdb->{_size} - $pdb->{_index}[$i]{offset}; } else { # This is not the last resource $len = $pdb->{_index}[$i+1]{offset} - $pdb->{_index}[$i]{offset}; } # Read the resource read $fh, $buf, $len; if ($hexdump) { &hexdump(" ", $buf); print "\n"; } # Tell the real class to parse the resource data. Pass # &ParseResource all of the information from the # index, plus a "data" field with the raw resource # data. my $resource; $resource = $pdb->ParseResource( %{$pdb->{_index}[$i]}, "data" => $buf, ); push @{$pdb->{resources}}, $resource; # Print out the parsed values &dumphash($resource, "\t"); print "\n"; } } sub hexdump { my $prefix = shift; # What to print in front of each line my $data = shift; # The data to dump my $maxlines = shift; # Max # of lines to dump my $offset; # Offset of current chunk for ($offset = 0; $offset < length($data); $offset += 16) { my $hex; # Hex values of the data my $ascii; # ASCII values of the data my $chunk; # Current chunk of data last if defined($maxlines) && ($offset >= ($maxlines * 16)); $chunk = substr($data, $offset, 16); ($hex = $chunk) =~ s/./sprintf "%02x ", ord($&)/ges; ($ascii = $chunk) =~ y/\040-\176/./c; printf "%s %-48s|%-16s|\n", $prefix, $hex, $ascii; } } # XXX - Ought to have a &dumparray as well. The two can call each other # recursively. sub dumphash { my $hash = shift; my $indent = shift; my $key; my $value; while (($key, $value) = each %{$hash}) { if (ref($value) eq "HASH") { print $indent, $key, ":\n"; &dumphash($value, $indent . "\t"); } elsif (ref($value) eq "ARRAY") { my($i,$j); print $indent, $key, ":\n"; for ($i = 0; $i <= $#{$value}; $i++) { if (ref($value->[$i]) eq "HASH") { print $indent, " $i:\n"; &dumphash($value->[$i], $indent . "\t"); } elsif (ref($value->[$i]) eq "ARRAY") { my @v2 = @{$value->[$i]}; for ($j = 0; $j <= $#v2; $j++) { print $indent, "\t$i-$j: [$v2[$j]]\n"; } }else { print $indent, "\t$i: [$value->[$i]]\n"; } } } else { print $indent, $key, " -> [", $value, "]\n"; } } } __END__ =head1 NAME pdbdump - Print the contents of a Palm PDB file =head1 VERSION This document describes version 1.400 of C, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS C I<[options]> F =head1 DESCRIPTION C reads a S F<.pdb> file, parses it, and prints its contents. This includes both a hex dump of the raw data of each piece, and a human-readable list of the various values, insofar as possible. The aim of C is to allow one to verify whether a particular file is a well-formed S database file and if not, where the error lies. If the database is of a known type, C parses the AppInfo block and records. Otherwise, it simply prints out a hex dump of their contents. C includes, by default, support for most of the built-in applications. Other helper modules may be loaded with the C<-M> option. =head1 OPTIONS =over 4 =item -h -help --help Print a usage message and exit. =item -nohex Don't print the hex dump of the various parts. =item -MI C the named module. This can be useful for loading additional helper modules. =back =head1 SEE ALSO L =head1 CONFIGURATION AND ENVIRONMENT main requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS C only recognizes record databases (C<.pdb> files), not resource databases (C<.prc> files). =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/examples/copydb0000644000175000017500000000043312501047366013540 0ustar cjmcjm#!/usr/bin/perl # Utility to copy the contents of a PDB. # $Id: copydb,v 1.2 1999/11/18 05:21:01 arensb Exp $ use strict; use Palm::Raw; use Palm::Memo; use Palm::Address; use Palm::Datebook; use Palm::Mail; my $pdb = new Palm::PDB; $pdb->Load($ARGV[0]); $pdb->Write("foo.pdb"); Palm-1.400/Makefile.PL0000644000175000017500000000233112501047366012470 0ustar cjmcjm # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.029. use strict; use warnings; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Read & write Palm OS databases (both PDB and PRC)", "AUTHOR" => "Christopher J. Madsen ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "Palm", "EXE_FILES" => [], "LICENSE" => "perl", "NAME" => "Palm", "PREREQ_PM" => { "Exporter" => 0, "POSIX" => 0, "Palm::Raw" => 0, "constant" => 0, "vars" => 0 }, "TEST_REQUIRES" => { "Palm::PDB" => 0, "Test::More" => 0 }, "VERSION" => "1.400", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Exporter" => 0, "ExtUtils::MakeMaker" => 0, "POSIX" => 0, "Palm::PDB" => 0, "Palm::Raw" => 0, "Test::More" => 0, "constant" => 0, "vars" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); Palm-1.400/lib/0000755000175000017500000000000012501047366011265 5ustar cjmcjmPalm-1.400/lib/Palm/0000755000175000017500000000000012501047366012156 5ustar cjmcjmPalm-1.400/lib/Palm/StdAppInfo.pm0000644000175000017500000004352312501047366014532 0ustar cjmcjmpackage Palm::StdAppInfo; # # ABSTRACT: Handle standard AppInfo blocks in Palm OS PDBs # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); # Don't harass me about these variables use vars qw( $VERSION @ISA $error ); # $error acts like $! in that it reports the error that occurred # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::Raw ); #' use constant APPINFO_PADDING => 1; # Whether to add the padding byte at # the end of the AppInfo block. # Note that this might be considered a hack: # this relies on the fact that 'use constant' # defines a function with no arguments; that # therefore this can be called as an instance # method, with full inheritance. That is, if # the handler class doesn't define it, Perl # will find the constant in the parent. If # this ever changes, the code below that uses # $self->APPINFO_PADDING will need to be # changed. use constant numCategories => 16; # Number of categories in AppInfo block use constant categoryLength => 16; # Length of category names use constant stdAppInfoSize => # Length of a standard AppInfo block 2 + (categoryLength * numCategories) + numCategories + 1 + 1; # The padding byte at the end may # be omitted sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "", "" ], ); } # seed_StdAppInfo # *** THIS IS NOT A METHOD *** # Given a reference to an appinfo hash, creates all of the fields for # a new AppInfo block. sub seed_StdAppInfo { my $appinfo = shift; my $i; $appinfo->{categories} = []; # Create array of categories # Initialize the categories # Note that all of the IDs are initialized to $i. There's no # real good reason for doing it this way, except that that's # what the Palm appears to do with new category lists. for ($i = 0; $i < numCategories; $i++) { $appinfo->{categories}[$i] = {}; $appinfo->{categories}[$i]{renamed} = 0; $appinfo->{categories}[$i]{name} = undef; $appinfo->{categories}[$i]{id} = $i; } # The only fixed category is "Unfiled". Initialize it now $appinfo->{categories}[0]{name} = "Unfiled"; $appinfo->{categories}[0]{id} = 0; # I'm not sure what this is, but let's initialize it. # The Palm appears to initialize this to numCategories - 1. $appinfo->{lastUniqueID} = numCategories - 1; } sub newStdAppInfo { my $class = shift; my $retval = {}; &seed_StdAppInfo($retval); return $retval; } #' sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. # Initialize the AppInfo block $self->{appinfo} = &newStdAppInfo(); return $self; } #' # parse_StdAppInfo # *** THIS IS NOT A METHOD *** # # Reads the raw data from $data, parses it as a standard AppInfo # block, and fills in the corresponding fields in %$appinfo. Returns # the number of bytes parsed. sub parse_StdAppInfo { my $appinfo = shift; # A reference to hash, to fill in my $data = shift; # Raw data to read my $nopadding = shift; # Optional: no padding byte at end my $unpackstr; # First argument to unpack() my $renamed; # Bitmap of renamed categories my @labels; # Array of category labels my @uniqueIDs; # Array of category IDs my $lastUniqueID; # Not sure what this is return undef if length $data < 4+(categoryLength*numCategories)+numCategories; if (!defined($nopadding)) { $nopadding = 0; } # Make sure $appinfo contains all of the requisite fields &seed_StdAppInfo($appinfo); # The argument to unpack() isn't hard to understand, it's just # hard to write in a readable fashion. $unpackstr = # Argument to unpack(), since it's hairy "n" . # Renamed categories ("a" . categoryLength) x numCategories . # Category labels "C" x numCategories . # Category IDs "C" . # Last unique ID "x"; # Unpack the data ($renamed, @labels[0..(numCategories-1)], @uniqueIDs[0..(numCategories-1)], $lastUniqueID) = unpack $unpackstr, $data; # Clean this stuff up a bit for (@labels) { s/\0.*$//; # Trim at NUL } # Now put the data into $appinfo my $i; for ($i = 0; $i < numCategories; $i++) { $appinfo->{categories}[$i]{renamed} = ($renamed & (1 << $i) ? 1 : 0); $appinfo->{categories}[$i]{name} = $labels[$i]; $appinfo->{categories}[$i]{id} = $uniqueIDs[$i]; } $appinfo->{lastUniqueID} = $lastUniqueID; # There might be other stuff in the AppInfo block other than # the standard categories. Put everything else in # $appinfo->{other}. $appinfo->{other} = substr($data, stdAppInfoSize - ($nopadding ? 1 : 0)); return ($nopadding ? stdAppInfoSize - 1 : stdAppInfoSize); } #' sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $appinfo = {}; &parse_StdAppInfo($appinfo, $data, $self->APPINFO_PADDING); return $appinfo; } #' # pack_StdAppInfo # *** THIS IS NOT A METHOD *** # # Given a reference to a hash containing an AppInfo block (such as # that initialized by parse_StdAppInfo()), returns a packed string # that can be written to the PDB file. sub pack_StdAppInfo { my $appinfo = shift; my $nopadding = shift; my $retval; my $i; $nopadding = 0 if !defined($nopadding); # Create the bitfield of renamed categories my $renamed; $renamed = 0; for ($i = 0; $i < numCategories; $i++) { if ($appinfo->{categories}[$i]{renamed}) { $renamed |= (1 << $i); } } $retval = pack("n", $renamed); # There have to be exactly 16 categories in the AppInfo block, # even though $appinfo->{categories} may have been mangled # by a naive (or clever) user or broken program. for ($i = 0; $i < numCategories; $i++) { my $name; # Category name # This is mainly to stop Perl 5.6 from complaining if # the category name is undefined. if ((!defined($appinfo->{categories}[$i]{name})) || $appinfo->{categories}[$i]{name} eq "") { $name = ""; } else { $name = $appinfo->{categories}[$i]{name}; } $retval .= pack("a" . categoryLength, $name); } # Ditto for category IDs for ($i = 0; $i < numCategories; $i++) { $retval .= pack("C", $appinfo->{categories}[$i]{id}); } # Last unique ID, and alignment padding $retval .= pack("Cx", $appinfo->{lastUniqueID}); $retval .= $appinfo->{other} if defined($appinfo->{other}); return $retval; } #' sub PackAppInfoBlock { my $self = shift; return &pack_StdAppInfo($self->{appinfo}, $self->{APPINFO_PADDING}); } #' # XXX - When choosing a new category ID, should pick them from the # range 128-255. sub addCategory { my $self = shift; # PDB my $name = shift; # Category name my $id = shift; # Category ID (optional) my $renamed = $#_ >= 0 ? $_[0] : 1; # Flag: was the category renamed (optional) # This initialization may look weird, # but it's this way so that it'll # default to true if omitted. my $categories = $self->{appinfo}{categories}; my $i; my %used; # Category IDs in use # Collect all the IDs in the current list for (@{$categories}) { next if !defined($_->{name}) || $_->{name} eq ""; $used{$_->{id}} = 1; } if (defined($id)) { # Sanity check: make sure this ID isn't already in use if (defined($used{$id})) { $error = "Category ID already in use"; return undef; } } else { # Find an unused category number, if none was specified for ($id = 128; $id < 256; $id++) { last if !defined($used{$id}); } } # Go through the list of categories, looking for an unused slot for ($i = 0; $i < numCategories; $i++) { # Ignore named categories next unless !defined($categories->[$i]{name}) or $categories->[$i]{name} eq ""; # Found an empty slot $categories->[$i]{name} = $name; $categories->[$i]{id} = $id; $categories->[$i]{renamed} = $renamed; return 1; } # If we get this far, there are no empty category slots $error = "No unused categories"; return undef; } #' sub deleteCategory { my $self = shift; my $name = shift; # Category name for (@{$self->{appinfo}{categories}}) { # Find the category named $name next if $_->{name} ne $name; # Erase this category $_->{name} = ""; # You'd think it would make sense to set the "renamed" # field here, but the Palm doesn't do that. } } #' # XXX - This doesn't behave the same way as the Palm: the Palm also # picks a new category ID. sub renameCategory { my $self = shift; my $oldname = shift; my $newname = shift; for (@{$self->{appinfo}{categories}}) { # Look for a category named $oldname next if !defined($_->{name}) || $_->{name} ne $oldname; # Found it. Rename it and mark it as renamed. $_->{name} = $newname; $_->{renamed} = 1; return 1; } $error = "No such category"; return undef; } 1; __END__ =head1 NAME Palm::StdAppInfo - Handle standard AppInfo blocks in Palm OS PDBs =head1 VERSION This document describes version 1.400 of Palm::StdAppInfo, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS Usually: package MyPDBHandler; use Palm::StdAppInfo(); # Note the parentheses @ISA = qw( Palm::StdAppInfo ); use constant APPINFO_PADDING = 1; sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $appinfo = {}; &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $app_specific_data = $appinfo->{other}; } sub PackAppInfoBlock { my $self = shift; my $retval; $self->{appinfo}{other} = ; $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } Or as a standalone C helper class: use Palm::StdAppInfo; =head1 DESCRIPTION Many Palm applications use a common format for keeping track of categories. The C class deals with this common format: $pdb = new Palm::PDB; $pdb->Load("myfile.pdb"); @categories = @{ $pdb->{appinfo}{categories} }; $lastUniqueID = $pdb->{appinfo}{lastUniqueID}; $other = $pdb->{appinfo}{other}; where: C<@categories> is an array of references-to-hash: =over 4 =item C<$cat = $categories[0];> =item C<$cat-E{name}> The name of the category, a string of at most 16 characters. =item C<$cat-E{id}> The category ID, an integer in the range 0-255. Each category has a unique ID. By convention, 0 is reserved for the "Unfiled" category; IDs assigned by the Palm are in the range 1-127, and IDs assigned by the desktop are in the range 128-255. =item C<$cat-E{renamed}> A boolean. This field is true iff the category has been renamed since the last sync. =back C<$lastUniqueID> is (I think) the last category ID that was assigned. C<$other> is any data that follows the category list in the AppInfo block. If you're writing a helper class for a PDB that includes a category list, you should parse this field to get any data that follows the category list; you should also make sure that this field is initialized before you call C<&Palm::StdAppInfo::pack_AppInfo>. =head2 APPINFO_PADDING Normally, the AppInfo block includes a byte of padding at the end, to bring its length to an even number. However, some databases use this byte for data. If your database uses the padding byte for data, then your C<&ParseAppInfoBlock> method (see L<"SYNOPSIS">) should call C<&parse_StdAppInfo> with a true $nopadding argument. If, for whatever reason, you wish to inherit C<&StdAppInfo::ParseAppInfoBlock>, then add use constant APPINFO_PADDING => 0; to your handler package, to tell it that the padding byte is really data. =head1 FUNCTIONS =head2 seed_StdAppInfo &Palm::StdAppInfo::seed_StdAppInfo(\%appinfo); Creates the standard fields in an existing AppInfo hash. Usually used to ensure that a newly-created AppInfo block contains an initialized category array: my $appinfo = {}; &Palm::StdAppInfo::seed_StdAppInfo($appinfo); Note: this is not a method. =head2 newStdAppInfo $appinfo = Palm::StdAppInfo->newStdAppInfo; Like C, but creates an AppInfo hash and returns a reference to it. =head2 new $pdb = new Palm::StdAppInfo; Create a new PDB, initialized with nothing but a standard AppInfo block. There are very few reasons to use this, and even fewer good ones. If you're writing a helper class to parse some PDB format that contains a category list, then you should make that helper class a subclass of C. =head2 parse_StdAppInfo $len = &Palm::StdAppInfo::parse_StdAppInfo(\%appinfo, $data, $nopadding); This function (this is not a method) is intended to be called from within a PDB helper class's C method. C parses a standard AppInfo block from the raw data C<$data> and fills in the fields in C<%appinfo>. It returns the number of bytes parsed. C<$nopadding> is optional, and defaults to false. Normally, the AppInfo block includes a padding byte at the end. If C<$nopadding> is true, then C<&parse_StdAppInfo> assumes that the padding byte is application data, and includes it in C<$appinfo{'other'}>, so that the caller can parse it. =head2 ParseAppInfoBlock $pdb = new Palm::StdAppInfo; $pdb->ParseAppInfoBlock($data); If your application's AppInfo block contains standard category support and nothing else, you may choose to just inherit this method instead of writing your own C method. Otherwise, see the example in L<"SYNOPSIS">. =head2 pack_StdAppInfo $data = &Palm::StdAppInfo::pack_StdAppInfo(\%appinfo); This function (this is not a method) is intended to be called from within a PDB helper class's C method. C takes an AppInfo hash and packs it as a string of raw data that can be written to a PDB. Note that if you're using this inside a helper class's C method, you should make sure that C<$appinfo{other}> is properly initialized before you call C<&Palm::StdAppInfo::pack_StdAppInfo>. C<$nopadding> is optional, and defaults to false. Normally, the AppInfo block includes a byte of padding at the end. If C<$nopadding> is true, then C<&pack_StdAppInfo> doesn't include this byte of padding, so that the application can use it. =head2 PackAppInfoBlock $pdb = new Palm::StdAppInfo; $data = $pdb->PackAppInfoBlock(); If your application's AppInfo block contains standard category support and nothing else, you may choose to just inherit this method instead of writing your own C method. Otherwise, see the example in L<"SYNOPSIS">. =head2 addCategory $pdb->addCategory($name [, $id [, $renamed]]); Adds a category to $pdb. The $name argument specifies the new category's name. The optional $id argument specifies the new category's numeric ID; if omitted or undefined, &addCategory will pick one. The optional $renamed argument is a boolean value indicating whether the new category should be marked as having been modified. This defaults to true since, conceptually, &addCategory doesn't really add a category: it finds one whose name happens to be empty, and renames it. Returns a true value if successful, false otherwise. In case of failure, &addCategory sets $Palm::StdAppInfo::error to an error message. =head2 deleteCategory $pdb->deleteCategory($name); Deletes the category with name $name. Actually, though, it doesn't delete the category: it just changes its name to the empty string, and marks the category as renamed. =head2 renameCategory $pdb->renameCategory($oldname, $newname); Renames the category named $oldname to $newname. If successful, returns a true value. If there is no category named $oldname, returns a false value and sets $Palm::StdAppInfo::error to an error message. =head1 SEE ALSO L =head1 CONFIGURATION AND ENVIRONMENT Palm::StdAppInfo requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/ZirePhoto.pm0000644000175000017500000002007412501047366014442 0ustar cjmcjmpackage Palm::ZirePhoto; # # ABSTRACT: Handler for Palm Zire71 Photo thumbnail database # # Copyright (C) 2003, Alessandro Zummo. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); #' sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "Foto", "Foto" ], ); } sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. $self->{name} = "PhotosDB-Foto"; # Default $self->{creator} = "Foto"; $self->{type} = "Foto"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing. # Give the PDB an empty list of records $self->{records} = []; return $self; } sub ParseRecord { my $self = shift; my %record = @_; my $data = $record{'data'}; delete $record{offset}; # This is useless delete $record{data}; # No longer necessary # when Photo thumbnail records are deleted/archived/whatever, the data section is # actually set to zero length. Presumably this is so that thumbnails take up # minimum space until a sync purges the records. return \%record unless length $data > 36; @record{ 'width', 'height', 'time1_secs', 'size', 'nameSize', 'time2_secs', 'thumb', 'name' } = unpack "xxxx n n N N x5 n x5 N x4 N/a a*", $data; $record{'thumbSize'} = length($record{'thumb'}); $record{'time1'} = $record{'time1_secs'} - 2082844800; $record{'time2'} = $record{'time2_secs'} - 2082844800; $record{'name'} = substr($record{'name'}, 0, $record{'nameSize'}); return \%record; } sub ParseNote { return ($_[0] =~ /NOTE.{8}([^\0]+)\0*ARCPHOTOBASE.{8}$/so) ? $1 : undef; } sub ParseAlbum { my $album = shift; # make sure it's an expected record format. return undef unless $album =~ /^DBFH/o; my @records; # skip .db file's initial 16 byte header, then grab 292 byte records for( my $pos = 16; $pos < length($album); $pos += 292 ) { my $buf = substr( $album, $pos, 292 ); last if length($buf) < 292; my %record; @record{ 'name', 'time1_secs', 'time2_secs', 'size', 'width', 'height' } = unpack('a256 x4 N N N x8 n n x8', $buf); $record{name} =~ s/\0+$//o; $record{time1} = $record{time1_secs} - 2082844800; $record{time2} = $record{time2_secs} - 2082844800; $record{'thumbSize'} = 0; $record{'thumb'} = ''; $record{'nameSize'} = length $record{name}; push @records, \%record; } return @records; } 1; __END__ =head1 NAME Palm::ZirePhoto - Handler for Palm Zire71 Photo thumbnail database =head1 VERSION This document describes version 1.400 of Palm::ZirePhoto, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::ZirePhoto; =head1 DESCRIPTION The Zire71 PDB handler is a helper class for the L package. It parses Zire71 Photo thumbnail databases (and, hopefully, Tungsten Photo databases). Actual photos are separate databases and must be processed separately. This database is currently only capable of reading. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. =head2 Records Records may contain no data fields. This occurs when the record has been marked deleted on the Palm, presumably in order to save space (Photo has no provision for archiving when deleting and the separate database storage for the actual images would make it pointless anyways). $record = $pdb->{records}[N] $record->{'width'} $record->{'height'} $record->{'size'} The actual JPEG images dimensions and (compressed) file size. $record->{'thumb'} The thumbnail is a very small (max size approx 84x84) JPEG format image. $record->{'name'} Image name. Appending C<.jpg> to this will give the database name of the actual image data. $record->{'time1'} $record->{'time2'} Unix epoch time of when the image was last modified (C) and when it was created (C). =head2 Photo Databases Actual photos are stored in separate databases. Each record is preceded by an 8 byte header that describes it a) as a data block (B) and b) the size of the block. Records are generally 4k, except for the last. To convert a Photo database to a JPEG image, one would do something like: use Palm::Raw; my $pdb = new Palm::PDB; $pdb->Load( "image.jpg.pdb" ); open F, ">image.jpg"; for( @{ $pdb->{records} } ) { print F substr($_->{'data'}, 8); } close F; Notes are stored at the end of the JPEG image. Use C to get it. =head1 METHODS Handling Palm photos can be a bit complicated. Some helper methods are exported to make some special cases a bit easier. =head2 ParseNote my $photo = read_jpeg_file( "image.jpg" ); my $note = Palm::ZirePhoto::ParseNote($photo); print "Note: $note" if defined $note; The Palm photo application stores user notes at the end of the JPEG file itself. This method will extract that note and return it. C is returned if the note is unavailable. =head2 ParseAlbum my $album = slurp("/DCIM/Unfiled/Album.db"); my @records = Palm::ZirePhoto::ParseAlbum( $album ); print $_->{name},"\n" for( @records ); Photos on memory cards are stored in subdirectories of C. The meta-data for these images are stored in C files under each category directory. This method will parse out the meta-data into an array of records similar to those returned by C. Thumbnail information, however, is not available. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::ZirePhoto requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Alessandro Zummo C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/Datebook.pm0000644000175000017500000005406712501047366014260 0ustar cjmcjmpackage Palm::Datebook; # # ABSTRACT: Handler for Palm OS DateBook and Calendar databases # # Copyright (C) 1999-2001, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); #' sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "date", "DATA" ], [ "PDat", "DATA" ], ); } #' # new # Create a new Palm::Datebook database, and return it sub new { my $classname = shift; my $params = $_[0] || {}; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. if ($params->{app} eq 'Calendar' || $self->{creator} eq 'PDat') { $self->{name} ||= "CalendarDB-PDat"; # Default $self->{creator} = "PDat" if $self->{creator} eq "\0\0\0\0"; } else { $self->{name} ||= "DatebookDB"; # Default $self->{creator} = "date" if $self->{creator} eq "\0\0\0\0"; } $self->{type} = "DATA" if $self->{type} eq "\0\0\0\0"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing, # since DatebookDB is explicitly not a PRC. $self->{appinfo} = { start_of_week => 0, # XXX - This is bogus }; &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo}); $self->{sort} = undef; # Empty sort block $self->{records} = []; # Empty list of records return $self; } sub new_Record { my $classname = shift; my $retval = $classname->SUPER::new_Record(@_); # By default, the new record is an untimed event that occurs # today. my @now = localtime(time); $retval->{day} = $now[3]; $retval->{month} = $now[4] + 1; $retval->{year} = $now[5] + 1900; $retval->{start_hour} = $retval->{start_minute} = $retval->{end_hour} = $retval->{end_minute} = 0xff; # Set the alarm. Defaults to 10 minutes before the event. $retval->{alarm}{advance} = 10; $retval->{alarm}{unit} = 0; # Minutes $retval->{repeat} = {}; # No repeat $retval->{exceptions} = []; # No exceptions $retval->{description} = ""; $retval->{note} = undef; $retval->{location} = undef; return $retval; } # ParseAppInfoBlock # Parse the AppInfo block for Datebook databases. # There appears to be one byte of padding at the end. sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $startOfWeek; my $i; my $appinfo = {}; my $std_len; # Get the standard parts of the AppInfo block $std_len = &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $data = $appinfo->{other}; # Look at non-category part # Get the rest of the AppInfo block my $unpackstr = # Argument to unpack(), since it's hairy "x2" . # Padding "C"; # Start of week # XXX - This is actually "sortOrder". Dunno what that is, # though. ($startOfWeek) = unpack $unpackstr, $data; $appinfo->{start_of_week} = $startOfWeek; return $appinfo; } sub PackAppInfoBlock { my $self = shift; my $retval; # Pack the non-category part of the AppInfo block $self->{appinfo}{other} = pack("x2 C x", $self->{appinfo}{start_of_week}); # Pack the standard part of the AppInfo block $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } sub ParseRecord { my $self = shift; my %record = @_; my $data; my $iscal = ($self->{creator} eq 'PDat'); delete $record{offset}; # This is useless # Untimed events have 0xff for $startHour, $startMinute, # $endHour and $endMinute. my $startHour; # In 24-hour format my $startMinute; my $endHour; # In 24-hour format my $endMinute; my $rawDate; my $flags; my $unpackstr = # Argument to unpack(). "C C" . # Start hour, minute "C C" . # End hour, minute "n" . # Raw date "n"; # Flags $data = $record{data}; ($startHour, $startMinute, $endHour, $endMinute, $rawDate, $flags) = unpack $unpackstr, $data; $data = substr $data, 8; # Chop off the part we've just parsed my $year; my $month; my $day; $day = $rawDate & 0x001f; # 5 bits $month = ($rawDate >> 5) & 0x000f; # 4 bits $year = ($rawDate >> 9) & 0x007f; # 7 bits (years since 1904) $year += 1904; $record{start_hour} = $startHour; $record{start_minute} = $startMinute; $record{end_hour} = $endHour; $record{end_minute} = $endMinute; $record{day} = $day; $record{month} = $month; $record{year} = $year; # Flags my $when_changed = ($flags & 0x8000 ? 1 : 0); my $have_alarm = ($flags & 0x4000 ? 1 : 0); my $have_repeat = ($flags & 0x2000 ? 1 : 0); my $have_note = ($flags & 0x1000 ? 1 : 0); my $have_exceptions = ($flags & 0x0800 ? 1 : 0); my $have_description = ($flags & 0x0400 ? 1 : 0); my $have_location = (($iscal && ($flags & 0x0200)) ? 1 : 0); $record{other_flags} = $flags & ($iscal ? 0x01ff : 0x03ff); if ($when_changed) { $record{when_changed} = 1; } if ($have_alarm) { my $advance; my $adv_unit; ($advance, $adv_unit) = unpack "cC", $data; $data = substr $data, 2; # Chop off alarm data $record{alarm}{advance} = $advance; $record{alarm}{unit} = $adv_unit; } if ($have_repeat) { my $type; my $endDate; my $frequency; my $repeatOn; my $repeatStartOfWeek; my $unknown; ($type, $endDate, $frequency, $repeatOn, $repeatStartOfWeek, $unknown) = unpack "Cx n C C C C", $data; $data = substr $data, 8; # Chop off repeat part $record{repeat}{type} = $type; $record{repeat}{unknown} = $unknown; if ($endDate != 0xffff) { my $endYear; my $endMonth; my $endDay; $endDay = $endDate & 0x001f; # 5 bits $endMonth = ($endDate >> 5) & 0x000f; # 4 bits $endYear = ($endDate >> 9) & 0x007f; # 7 bits (years $endYear += 1904; # since 1904) $record{repeat}{end_day} = $endDay; $record{repeat}{end_month} = $endMonth; $record{repeat}{end_year} = $endYear; } $record{repeat}{frequency} = $frequency; if ($type == 2) { # "Weekly" repeat my $i; my @days; # Build an array of 7 elements (one for each # day of the week). Each element is set iff # the appointment repeats on that day. for ($i = 0; $i < 7; $i++) { if ($repeatOn & (1 << $i)) { $days[$i] = 1; } else { $days[$i] = 0; } } $record{repeat}{repeat_days} = [ @days ]; $record{repeat}{start_of_week} = $repeatStartOfWeek; # I don't know what this is, # but the Datebook app appears # to perform some hairy # calculations involving this. } elsif ($type == 3) { # "Monthly by day" repeat # If "weeknum" is 5, it means the last week of # the month $record{repeat}{weeknum} = int($repeatOn / 7); $record{repeat}{daynum} = $repeatOn % 7; } } if ($have_exceptions) { my $numExceptions; my @exceptions; $numExceptions = unpack "n", $data; $data = substr $data, 2; @exceptions = unpack "n" x $numExceptions, $data; $data = substr $data, 2 * $numExceptions; my $exception; foreach $exception (@exceptions) { my $year; my $month; my $day; $day = $exception & 0x001f; $month = ($exception >> 5) & 0x000f; $year = ($exception >> 9) & 0x007f; $year += 1904; push @{$record{exceptions}}, [ $day, $month, $year ]; } } my @fields = split /\0/, $data, -1; if ($have_description) { my $description; $description = shift @fields; $record{description} = $description; } if ($have_note) { my $note; $note = shift @fields; $record{note} = $note; } if ($have_location) { my $location; $location = shift @fields; $record{location} = $location; } my $other_data= join ("\0", @fields); if ($iscal && length ($other_data) >= 21 && substr ($other_data, 0, 4) eq 'Bd00') { my $len= unpack ('n', substr ($other_data, 4, 2)); if ($len+6 <= length ($other_data)) { my $tzdata= substr ($other_data, 6, $len); $other_data= substr ($other_data, $len+6); @{$record{timezone}}{qw(offset start_hour start_daynum start_weeknum start_month end_hour end_daynum end_weeknum end_month dst_adjustment country flags name)}= unpack ('n C8 n C2 a*', $tzdata); $record{timezone}{name} =~ s/\0$//; $record{timezone}{offset}= $record{timezone}{offset} -65536 if $record{timezone}{offset} > 32767; # signed short $record{timezone}{dst_adjustment}= $record{timezone}{dst_adjustment}-65536 if $record{timezone}{dst_adjustment} > 32767; # signed short $record{timezone}{custom}= ($record{timezone}{flags} & 0x80) ? 1 : 0; $record{timezone}{flags} &= 0x7f; $record{timezone}{data}= $tzdata; } } $record{other_data}= $other_data if $other_data ne ''; delete $record{data}; return \%record; } sub PackRecord { my $self = shift; my $record = shift; my $retval; my $rawDate; my $flags; my $iscal = ($self->{creator} eq 'PDat'); $rawDate = ($record->{day} & 0x001f) | (($record->{month} & 0x000f) << 5) | ((($record->{year} - 1904) & 0x007f) << 9); # XXX - Better to collect data first, then build flags. $flags = $record->{other_flags}; # $flags |= 0x8000 if $record->{when_changed}; # $flags |= 0x4000 if keys %{$record->{alarm} } ne (); # $flags |= 0x2000 if keys %{$record->{repeat} } ne (); # $flags |= 0x1000 if $record->{note} ne ""; # $flags |= 0x0800 if $#{$record->{exceptions} } >= 0; # $flags |= 0x0400 if $record->{description} ne ""; # $flags |= 0x0200 if $iscal && $record->{location} ne ""; # $retval = pack "C C C C n n", # $record->{start_hour}, # $record->{start_minute}, # $record->{end_hour}, # $record->{end_minute}, # $rawDate, # $flags; if ($record->{when_changed}) { $flags |= 0x8000; } my $alarm = undef; if (defined($record->{alarm}) && %{$record->{alarm}}) { $flags |= 0x4000; $alarm = pack "c C", $record->{alarm}{advance}, $record->{alarm}{unit}; } my $repeat = undef; if (defined($record->{repeat}) && %{$record->{repeat}}) { my $type; # Repeat type my $endDate = 0xffff; # No end date defined by default my $repeatOn = 0; my $repeatStartOfWeek = 0; $flags |= 0x2000; if (defined($record->{repeat}{end_day})) { # End date defined $endDate = ($record->{repeat}{end_day} & 0x001f) | (($record->{repeat}{end_month} & 0x000f) << 5) | ((($record->{repeat}{end_year} - 1904) & 0x007f) << 9); } if ($record->{repeat}{type} == 2) { # Weekly repeat my $i; $repeatOn = 0; for ($i = 0; $i < 7; $i++) { if ($record->{repeat}{repeat_days}[$i]) { $repeatOn |= (1 << $i); } } $repeatStartOfWeek = $record->{repeat}{start_of_week}; } elsif ($record->{repeat}{type} == 3) { # "Monthly by day" repeat my $weeknum = $record->{repeat}{weeknum}; if ($weeknum > 5) { $weeknum = 5; } $repeatOn = ($record->{repeat}{weeknum} * 7) + ($record->{repeat}{daynum} % 7); } $repeat = pack "Cx n C C C C", $record->{repeat}{type}, $endDate, $record->{repeat}{frequency}, $repeatOn, $repeatStartOfWeek, $record->{repeat}{unknown}; } my $exceptions = undef; if (defined($record->{exceptions}) && @{$record->{exceptions}}) { my $numExceptions = $#{$record->{exceptions}} + 1; my $exception; $flags |= 0x0800; $exceptions = pack("n", $numExceptions); foreach $exception (@{$record->{exceptions}}) { my $day = $exception->[0]; my $month = $exception->[1]; my $year = $exception->[2]; $exceptions .= pack("n", ($day & 0x001f) | (($month & 0x000f) << 5) | ((($year - 1904) & 0x007f) << 9)); } } my $description = undef; if (defined($record->{description}) && ($record->{description} ne "")) { $flags |= 0x0400; $description = $record->{description} . "\0"; } my $note = undef; if (defined($record->{note}) && ($record->{note} ne "")) { $flags |= 0x1000; $note = $record->{note} . "\0"; } my $location = undef; if ($iscal && defined($record->{location}) && ($record->{location} ne "")) { $flags |= 0x0200; $location = $record->{location} . "\0"; } $retval = pack "C C C C n n", $record->{start_hour}, $record->{start_minute}, $record->{end_hour}, $record->{end_minute}, $rawDate, $flags; $retval .= $alarm if defined($alarm); $retval .= $repeat if defined($repeat); $retval .= $exceptions if defined($exceptions); $retval .= $description if defined($description); $retval .= $note if defined($note); $retval .= $location if defined($location); if ($iscal && $record->{timezone}) { my $tzflags= $record->{timezone}{flags}; $tzflags |= 0x80 if $record->{timezone}{custom}; my $tzdata = pack ('n C8 n C2', @{$record->{timezone}}{qw(offset start_hour start_daynum start_weeknum start_month end_hour end_daynum end_weeknum end_month dst_adjustment country)}, $tzflags); $tzdata .= "$record->{timezone}{name}\0"; $retval .= 'Bd00'; $retval .= pack ('n', length ($tzdata)); $retval .= $tzdata; } $retval .= $record->{other_data} if exists $record->{other_data}; return $retval; } 1; __END__ =head1 NAME Palm::Datebook - Handler for Palm OS DateBook and Calendar databases =head1 VERSION This document describes version 1.400 of Palm::Datebook, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::Datebook; =head1 DESCRIPTION The Datebook PDB handler is a helper class for the Palm::PDB package. It parses DateBook and Calendar databases. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. =head2 Sort block $pdb->{sort} This is a scalar, the raw data of the sort block. =head2 Records $record = $pdb->{records}[N] $record->{day} $record->{month} $record->{year} The day, month and year of the event. The day and month start at 1 (I, for January, C<< $record->{month} >> is set to 1). The year is a four-digit number (for dates in 2001, C<< $record->{year} >> is "2001"). For repeating events, these fields specify the first date at which the event occurs. $record->{start_hour} $record->{start_minute} $record->{end_hour} $record->{end_minute} The start and end times of the event. For untimed events, all of these are 0xff. $record->{when_changed} This is defined and true iff the "when info" for the record has changed. I don't know what this means. $record->{alarm}{advance} $record->{alarm}{unit} If the record has an alarm associated with it, the %{$record->{alarm}Z<>} hash exists. The "unit" subfield is an integer: 0 for minutes, 1 for hours, 2 for days. The "advance" subfield specifies how many units before the event the alarm should ring. I, if "unit" is 1 and "advance" is 5, then the alarm will sound 5 hours before the event. If C is -1, then there is no alarm associated with this event. New records created via C have a 10 minute alarm set by default. C<< undef $record->{alarm} >> to remove this alarm before writing. An alarm icon will still show up in the Datebook if the C field exists, even with C set to -1. %{ $record->{repeat} } This exists iff this is a repeating event. $record->{repeat}{type} An integer which specifies the type of repeat: =over 4 =item 0 no repeat. =item 1Z<> a daily event, one that occurs every day. =item 2Z<> a weekly event, one that occurs every week on the same dayZ<>(s). An event may occur on several days every week, I, every Monday, Wednesday and Friday. For weekly events, the following fields are defined: @{ $record->{repeat}{repeat_days} } This is an array of 7 elements; each element is true iff the event occurs on the corresponding day. Element 0 is Sunday, element 1 is Monday, and so forth. $record->{repeat}{start_of_week} Day the week starts on (0 for Sunday, 1 for Monday). This affects the phase of events that repeat every 2nd (or more) Sunday. =item 3Z<> a "monthly by day" event, I, one that occurs on the second Friday of every month. For "monthly by day" events, the following fields are defined: $record->{repeat}{weeknum} The number of the week on which the event occurs. 0 means the first week of the month, 1 means the second week of the month, and so forth. A value of 5 means that the event occurs on the last week of the month. $record->{repeat}{daynum} An integer, the day of the week on which the event occurs. 0 means Sunday, 1 means Monday, and so forth. =item 4Z<> a "monthly by date" event, I, one that occurs on the 12th of every month. =item 5Z<> a yearly event, I, one that occurs every year on December 25th. $record->{repeat}{frequency} Specifies the frequency of the repeat. For instance, if the event is a daily one, and $record->{repeat}{frequency} is 3, then the event occurs every 3 days. =back $record->{repeat}{unknown} I don't know what this is. $record->{repeat}{end_day} $record->{repeat}{end_month} $record->{repeat}{end_year} The last day, month and year on which the event occurs. @{ $record->{exceptions} } $day = $record->{exceptions}[N][0] $month = $record->{exceptions}[N][1] $year = $record->{exceptions}[N][2] If there are any exceptions to a repeating event, I a weekly meeting that was cancelled one time, then the @{$record->{exceptions}Z<>} array is defined. Each element in this array is a reference to an anonymous array with three elements: the day, month, and year of the exception. $record->{description} A text string, the description of the event. $record->{location} A text string, the location (if any) of the event (Calendar database only). $record->{note} A text string, the note (if any) attached to the event. %{ $record->{timezone} } This exists iff a time zone has been set for the event. $record->{timezone}{name} The time zone name, I, "London" or "San Francisco". $record->{timezone}{country} The country the time zone is in. This is an integer defined in Core/System/PalmLocale.h. $record->{timezone}{offset} This gives the offset from UTC, in minutes, of the time zone. $record->{timezone}{dst_adjustment} This gives the additional offset while daylight savings time is in effect. The offset from UTC is $record->{timezone}{offset} + $record->{timezone}{dst_adjustment} (actually only 0 or 60 are used). $record->{timezone}{custom} Should indicate whether this location was created by the user, though this always seems to be true. $record->{timezone}{flags} Reserved flags. $record->{timezone}{start_hour} $record->{timezone}{start_daynum} $record->{timezone}{start_weeknum} $record->{timezone}{start_month} $record->{timezone}{end_hour} $record->{timezone}{end_daynum} $record->{timezone}{end_weeknum} $record->{timezone}{end_month} These define the period during which daylight savings time is in effect if $record->{timezone}{dst_adjustment} is non-zero. daynum specifies the day of week (0=Sunday, 6=Saturday) and weeknum specifies the week of month (0=1st, 3=4th, 4=last), analagously to the "monthly by day" repeating event. I, The "London" time zone has DST starting on the last Sunday of March, which is indicated with start_daynum=0 (Sunday), start_weeknum=4 (last week of the month), and start_month=3 (March). =head1 METHODS =head2 new $pdb = new Palm::Datebook; $pdb = new Palm::Datebook({app => 'Calendar'}); Create a new PDB, initialized with the various Palm::Datebook fields and an empty record list. Creates a Datebook PDB by default. Specify the app parameter as 'Calendar' to create a Calendar PDB. =head2 new_Record $record = $pdb->new_Record; Creates a new Datebook record, with blank values for all of the fields. C does B add the new record to C<$pdb>. For that, you want C<< $pdb->append_Record >>. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::Datebook requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/DateTime.pm0000644000175000017500000001603612501047366014216 0ustar cjmcjmpackage Palm::DateTime; # # ABSTRACT: Deal with various Palm OS date/time formats # # Copyright (C) 2001-2002, Alessandro Zummo # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Exporter; use POSIX; use vars qw($VERSION); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @Palm::DateTime::ISA = qw( Exporter ); @Palm::DateTime::EXPORT = qw( datetime_to_palmtime dlptime_to_palmtime palmtime_to_dlptime secs_to_dlptime dlptime_to_secs palmtime_to_secs secs_to_palmtime palmtime_to_ascii palmtime_to_iso8601 ); #FIXME what values can wday have? sub datetime_to_palmtime { my ($datetime) = @_; my $palmtime = {}; @$palmtime { 'second', 'minute', 'hour', 'day', 'month', 'year', 'wday', } = unpack("nnnnnnn", $datetime); return $palmtime; } sub dlptime_to_palmtime { my ($dlptime) = @_; my $palmtime = {}; @$palmtime { 'year', 'month', 'day', 'hour', 'minute', 'second', } = unpack("nCCCCCx", $dlptime); return $palmtime; } # A future version might allow to specify only some of the fields. sub palmtime_to_dlptime { my ($palmtime) = @_; return pack("nCCCCCx", @$palmtime { 'year', 'month', 'day', 'hour', 'minute', 'second', }); } sub secs_to_dlptime { my ($secs) = @_; return palmtime_to_dlptime(secs_to_palmtime($secs)); } sub dlptime_to_secs { my ($dlptime) = @_; return palmtime_to_secs(dlptime_to_palmtime($dlptime)); } sub palmtime_to_secs { my ($palmtime) = @_; return POSIX::mktime( $palmtime->{'second'}, $palmtime->{'minute'}, $palmtime->{'hour'}, $palmtime->{'day'}, $palmtime->{'month'} - 1, # Palm used 1-12, mktime needs 0-11 $palmtime->{'year'} - 1900, 0, 0, -1); } sub secs_to_palmtime { my ($secs) = @_; my $palmtime = {}; @$palmtime { 'second', 'minute', 'hour', 'day', 'month', 'year' } = localtime($secs); # Fix values $palmtime->{'year'} += 1900; $palmtime->{'month'} += 1; return $palmtime; } sub palmtime_to_ascii { my ($palmtime) = @_; return sprintf("%4d%02d%02d%02d%02d%02d", @$palmtime { 'year', 'month', 'day', 'hour', 'minute', 'second', }); } sub palmtime_to_iso8601 { my ($palmtime) = @_; return sprintf("%4d-%02d-%02dT%02d:%02d:%02dZ", @$palmtime { 'year', 'month', 'day', 'hour', 'minute', 'second', }); } 1; __END__ =head1 NAME Palm::DateTime - Deal with various Palm OS date/time formats =head1 VERSION This document describes version 1.400 of Palm::DateTime, released March 14, 2015 as part of Palm version 1.400. =head1 DESCRIPTION Palm::DateTime exports subroutines to convert between various Palm OS date/time formats. All subroutines are exported by default. Data types: secs - Seconds since the system epoch dlptime - Palm OS DlpDateTimeType (raw) datetime - Palm OS DateTimeType (raw) palmtime - Decoded date/time (a hashref) KEY VALUES second 0-59 minute 0-59 hour 0-23 day 1-31 month 1-12 year 4 digits =head1 SUBROUTINES =head2 datetime_to_palmtime $palmtime = datetime_to_palmtime($datetime) Converts Palm OS DateTimeType to a palmtime hashref. In addition to the usual keys, C<$palmtime> will contain a C field. =head2 dlptime_to_palmtime $palmtime = dlptime_to_palmtime($dlptime) Converts Palm OS DlpDateTimeType to a palmtime hashref. =head2 dlptime_to_secs $secs = dlptime_to_secs($dlptime) Converts a Palm OS DlpDateTimeType to epoch time. =head2 palmtime_to_ascii $string = palmtime_to_secs(\%palmtime) Converts a palmtime hashref to a C string (e.g. C<20011116200051>). C<%palmtime> must contain all standard fields. =head2 palmtime_to_dlptime $dlptime = palmtime_to_dlptime(\%palmtime) Converts a palmtime hashref to a Palm OS DlpDateTimeType. C<%palmtime> must contain all standard fields. =head2 palmtime_to_iso8601 $string = palmtime_to_iso8601(\%palmtime) Converts a palmtime hashref to a C string (e.g. C<2001-11-16T20:00:51Z>). C<%palmtime> must contain all standard fields. GMT timezone ("Z") is assumed. =head2 palmtime_to_secs $secs = palmtime_to_secs(\%palmtime) Converts a palmtime hashref to epoch seconds. C<%palmtime> must contain all standard fields. =head2 secs_to_dlptime $dlptime = secs_to_dlptime($secs) Converts epoch time to a Palm OS DlpDateTimeType. =head2 secs_to_palmtime $palmtime = secs_to_palmtime($secs) Converts epoch seconds to a palmtime hashref. =head1 CONFIGURATION AND ENVIRONMENT Palm::DateTime requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Alessandro Zummo C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/Address.pm0000644000175000017500000005142012501047366014103 0ustar cjmcjmpackage Palm::Address; # # ABSTRACT: Handler for Palm OS AddressBook databases # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA $numFieldLabels $addrLabelLength @phoneLabels @countries %fieldMapBits ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); # AddressDB records are quite flexible and customizable, and therefore # a pain in the ass to deal with correctly. #' $addrLabelLength = 16; $numFieldLabels = 22; @phoneLabels = ( "Work", "Home", "Fax", "Other", "E-mail", "Main", "Pager", "Mobile", ); @countries = ( "Australia", "Austria", "Belgium", "Brazil", "Canada", "Denmark", "Finland", "France", "Germany", "Hong Kong", "Iceland", "Ireland", "Italy", "Japan", "Luxembourg", "Mexico", "Netherlands", "New Zealand", "Norway", "Spain", "Sweden", "Switzerland", "United Kingdom", "United States", ); # fieldMapBits # Each Address record contains a flag record ($fieldMap, in # &PackRecord) that indicates which fields exist in the record. This # hash defines these flags' values. %fieldMapBits = ( name => 0x0001, firstName => 0x0002, company => 0x0004, phone1 => 0x0008, phone2 => 0x0010, phone3 => 0x0020, phone4 => 0x0040, phone5 => 0x0080, address => 0x0100, city => 0x0200, state => 0x0400, zipCode => 0x0800, country => 0x1000, title => 0x2000, custom1 => 0x4000, custom2 => 0x8000, custom3 => 0x10000, custom4 => 0x20000, note => 0x40000, ); sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "addr", "DATA" ], ); } #' # new # Create a new Palm::Address database, and return it sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. $self->{name} = "AddressDB"; # Default $self->{creator} = "addr"; $self->{type} = "DATA"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing, # since AddressDB is explicitly not a PRC. # Initialize the AppInfo block $self->{appinfo} = { fieldLabels => { # Displayed labels for the various fields in # each address record. # XXX - These are American English defaults. It'd # be way keen to allow i18n. name => "Name", firstName => "First name", company => "Company", phone1 => "Work", phone2 => "Home", phone3 => "Fax", phone4 => "Other", phone5 => "E-mail", phone6 => "Main", phone7 => "Pager", phone8 => "Mobile", address => "Address", city => "City", state => "State", zipCode => "Zip Code", country => "Country", title => "Title", custom1 => "Custom 1", custom2 => "Custom 2", custom3 => "Custom 3", custom4 => "Custom 4", note => "Note", }, # XXX - The country code corresponds to "United # States". Again, it'd be keen to allow the user's # # country-specific defaults. country => 22, misc => 0, }; # Add the standard AppInfo block stuff &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo}); # Give the PDB a blank sort block $self->{sort} = undef; # Give the PDB an empty list of records $self->{records} = []; return $self; } # new_Record # Create a new, initialized record. sub new_Record { my $classname = shift; my $retval = $classname->SUPER::new_Record(@_); # Initialize the fields. This isn't particularly enlightening, # but every AddressDB record has these. $retval->{fields} = { name => undef, firstName => undef, company => undef, phone1 => undef, phone2 => undef, phone3 => undef, phone4 => undef, phone5 => undef, address => undef, city => undef, state => undef, zipCode => undef, country => undef, title => undef, custom1 => undef, custom2 => undef, custom3 => undef, custom4 => undef, note => undef, }; # Initialize the phone labels $retval->{phoneLabel} = { phone1 => 0, # Work phone2 => 1, # Home phone3 => 2, # Fax phone4 => 3, # Other phone5 => 4, # E-mail display => 0, # Display work phone by default reserved => undef # ??? }; return $retval; } # ParseAppInfoBlock # Parse the AppInfo block for Address databases. # # The AppInfo block has the following overall structure: # 1: Categories (see StdAppInfo.pm) # 2: reserved word # 3: dirty field labels # 4: field labels # 5: country # 6: misc # 3: I think this is similar to the first part of the standard AppInfo # blocka, a bit field of which field labels have changed (i.e., # which fields have been renamed). # 4: An array of field labels (16-character strings, NUL-terminated). # 5: The code for the country for which the labels were designed. # 6: 7 reserved bits followed by one flag that's set if the database # should be sorted by company. sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $dirtyFields; my @fieldLabels; my $country; my $misc; my $i; my $appinfo = {}; my $std_len; # Get the standard parts of the AppInfo block $std_len = &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $data = $appinfo->{other}; # Look at the non-standard part # Get the rest of the AppInfo block my $unpackstr = # Argument to unpack() "x2" . # Reserved "N" . # Dirty flags "a$addrLabelLength" x $numFieldLabels . # Address labels "C" . # Country "C"; # Misc ($dirtyFields, @fieldLabels[0..($numFieldLabels-1)], $country, $misc) = unpack $unpackstr, $data; for (@fieldLabels) { s/\0.*$//; # Trim everything after the first NUL # (when renaming custom fields, might # have something like "Foo\0om 1" } $appinfo->{dirtyFields} = $dirtyFields; $appinfo->{fieldLabels} = { name => $fieldLabels[0], firstName => $fieldLabels[1], company => $fieldLabels[2], phone1 => $fieldLabels[3], phone2 => $fieldLabels[4], phone3 => $fieldLabels[5], phone4 => $fieldLabels[6], phone5 => $fieldLabels[7], address => $fieldLabels[8], city => $fieldLabels[9], state => $fieldLabels[10], zipCode => $fieldLabels[11], country => $fieldLabels[12], title => $fieldLabels[13], custom1 => $fieldLabels[14], custom2 => $fieldLabels[15], custom3 => $fieldLabels[16], custom4 => $fieldLabels[17], note => $fieldLabels[18], phone6 => $fieldLabels[19], phone7 => $fieldLabels[20], phone8 => $fieldLabels[21], }; $appinfo->{country} = $country; $appinfo->{misc} = $misc; # XXX - Parse the "misc" field further return $appinfo; } sub PackAppInfoBlock { my $self = shift; my $retval; my $i; my $other; # Non-standard AppInfo stuff # Pack the application-specific part of the AppInfo block $other = pack("x2 N", $self->{appinfo}{dirtyFields}); $other .= pack("a$addrLabelLength" x $numFieldLabels, $self->{appinfo}{fieldLabels}{name}, $self->{appinfo}{fieldLabels}{firstName}, $self->{appinfo}{fieldLabels}{company}, $self->{appinfo}{fieldLabels}{phone1}, $self->{appinfo}{fieldLabels}{phone2}, $self->{appinfo}{fieldLabels}{phone3}, $self->{appinfo}{fieldLabels}{phone4}, $self->{appinfo}{fieldLabels}{phone5}, $self->{appinfo}{fieldLabels}{address}, $self->{appinfo}{fieldLabels}{city}, $self->{appinfo}{fieldLabels}{state}, $self->{appinfo}{fieldLabels}{zipCode}, $self->{appinfo}{fieldLabels}{country}, $self->{appinfo}{fieldLabels}{title}, $self->{appinfo}{fieldLabels}{custom1}, $self->{appinfo}{fieldLabels}{custom2}, $self->{appinfo}{fieldLabels}{custom3}, $self->{appinfo}{fieldLabels}{custom4}, $self->{appinfo}{fieldLabels}{note}, $self->{appinfo}{fieldLabels}{phone6}, $self->{appinfo}{fieldLabels}{phone7}, $self->{appinfo}{fieldLabels}{phone8}); $other .= pack("C C x2", $self->{appinfo}{country}, $self->{appinfo}{misc}); $self->{appinfo}{other} = $other; # Pack the standard part of the AppInfo block $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } # ParseRecord # Parse an Address Book record. # Address book records have the following overall structure: # 1: phone labels # 2: field map # 3: fields # Each record can contain a number of fields, such as "name", # "address", "city", "company", and so forth. Each field has an # internal name ("zipCode"), a printable name ("Zip Code"), and a # value ("90210"). # # For most fields, there is a hard mapping between internal and # printed names: "name" always corresponds to "Last Name". The fields # "phone1" through "phone5" are different: each of these can be mapped # to one of several printed names: "Work", "Home", "Fax", "Other", # "E-Mail", "Main", "Pager" or "Mobile". Multiple internal names can # map to the same printed name (a person might have several e-mail # addresses), and the mapping is part of the record (i.e., each record # has its own mapping). # # Part (3) is simply a series of NUL-terminated strings, giving the # values of the various fields in the record, in a certain order. If a # record does not have a given field, there is no string corresponding # to it in this part. # # Part (2) is a bit field that specifies which fields the record # contains. # # Part (1) determines the phone mapping described above. This is # implemented as an unsigned long, but what we're interested in are # the six least-significant nybbles. They are: # disp phone5 phone4 phone3 phone2 phone1 # ("phone1" is the least-significant nybble). Each nybble holds a # value in the range 0-15 which in turn specifies the printed name for # that particular internal name. sub ParseRecord { my $self = shift; my %record = @_; delete $record{offset}; # This is useless my $phoneFlags; my @phoneTypes; my $dispPhone; # Which phone to display in the phone list my $reserved; # Not sure what this is. It's the 8 high bits # of the "phone types" field. my $fieldMap; my $companyFieldOff; # Company field offset: offset into the # raw "fields" string of the beginning of # the company name, plus 1. Presumably this # is to allow the address book app to quickly # display by company name. It is 0 in entries # that don't have a "Company" field. # This can be ignored when reading, and # must be computed when writing. my $fields; my @fields; ($phoneFlags, $fieldMap, $companyFieldOff, $fields) = unpack("N N C a*", $record{data}); @fields = split /\0/, $fields; # Parse the phone flags $phoneTypes[0] = $phoneFlags & 0x0f; $phoneTypes[1] = ($phoneFlags >> 4) & 0x0f; $phoneTypes[2] = ($phoneFlags >> 8) & 0x0f; $phoneTypes[3] = ($phoneFlags >> 12) & 0x0f; $phoneTypes[4] = ($phoneFlags >> 16) & 0x0f; $dispPhone = ($phoneFlags >> 20) & 0x0f; $reserved = ($phoneFlags >> 24) & 0xff; $record{phoneLabel}{phone1} = $phoneTypes[0]; $record{phoneLabel}{phone2} = $phoneTypes[1]; $record{phoneLabel}{phone3} = $phoneTypes[2]; $record{phoneLabel}{phone4} = $phoneTypes[3]; $record{phoneLabel}{phone5} = $phoneTypes[4]; $record{phoneLabel}{display} = $dispPhone; $record{phoneLabel}{reserved} = $reserved; # Get the relevant fields $fieldMap & 0x0001 and $record{fields}{name} = shift @fields; $fieldMap & 0x0002 and $record{fields}{firstName} = shift @fields; $fieldMap & 0x0004 and $record{fields}{company} = shift @fields; $fieldMap & 0x0008 and $record{fields}{phone1} = shift @fields; $fieldMap & 0x0010 and $record{fields}{phone2} = shift @fields; $fieldMap & 0x0020 and $record{fields}{phone3} = shift @fields; $fieldMap & 0x0040 and $record{fields}{phone4} = shift @fields; $fieldMap & 0x0080 and $record{fields}{phone5} = shift @fields; $fieldMap & 0x0100 and $record{fields}{address} = shift @fields; $fieldMap & 0x0200 and $record{fields}{city} = shift @fields; $fieldMap & 0x0400 and $record{fields}{state} = shift @fields; $fieldMap & 0x0800 and $record{fields}{zipCode} = shift @fields; $fieldMap & 0x1000 and $record{fields}{country} = shift @fields; $fieldMap & 0x2000 and $record{fields}{title} = shift @fields; $fieldMap & 0x4000 and $record{fields}{custom1} = shift @fields; $fieldMap & 0x8000 and $record{fields}{custom2} = shift @fields; $fieldMap & 0x10000 and $record{fields}{custom3} = shift @fields; $fieldMap & 0x20000 and $record{fields}{custom4} = shift @fields; $fieldMap & 0x40000 and $record{fields}{note} = shift @fields; delete $record{data}; return \%record; } sub PackRecord { my $self = shift; my $record = shift; my $retval; $retval = pack("N", ($record->{phoneLabel}{phone1} & 0x0f) | (($record->{phoneLabel}{phone2} & 0x0f) << 4) | (($record->{phoneLabel}{phone3} & 0x0f) << 8) | (($record->{phoneLabel}{phone4} & 0x0f) << 12) | (($record->{phoneLabel}{phone5} & 0x0f) << 16) | (($record->{phoneLabel}{display} & 0x0f) << 20) | (($record->{phoneLabel}{reserved} & 0xff) << 24)); # Set the flag bits that indicate which fields exist in this # record. my $fieldMap = 0; foreach my $fieldname (qw(name firstName company phone1 phone2 phone3 phone4 phone5 address city state zipCode country title custom1 custom2 custom3 custom4 note)) { if (defined($record->{fields}{$fieldname}) && ($record->{fields}{$fieldname} ne "")) { $fieldMap |= $fieldMapBits{$fieldname}; } else { $record->{fields}{$fieldname} = ""; } } $retval .= pack("N", $fieldMap); my $fields = ''; my $companyFieldOff = 0; $fields .= $record->{fields}{name} . "\0" unless $record->{fields}{name} eq ""; $fields .= $record->{fields}{firstName} . "\0" unless $record->{fields}{firstName} eq ""; if ($record->{fields}{company} ne "") { $companyFieldOff = length($fields) + 1; $fields .= $record->{fields}{company} . "\0" } # Append each nonempty field in turn to $fields. foreach my $fieldname (qw(phone1 phone2 phone3 phone4 phone5 address city state zipCode country title custom1 custom2 custom3 custom4 note)) { # Skip empty fields (either blank or undefined). next if !defined($record->{fields}{$fieldname}); next if $record->{fields}{$fieldname} eq ""; # Append the field (with a terminating NUL) $fields .= $record->{fields}{$fieldname} . "\0"; } $retval .= pack("C", $companyFieldOff); $retval .= $fields; return $retval; } 1; __END__ =head1 NAME Palm::Address - Handler for Palm OS AddressBook databases =head1 VERSION This document describes version 1.400 of Palm::Address, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::Address; =head1 DESCRIPTION The Address PDB handler is a helper class for the Palm::PDB package. It parses AddressBook databases. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. Other fields include: $pdb->{appinfo}{lastUniqueID} $pdb->{appinfo}{dirtyFields} I don't know what these are. $pdb->{appinfo}{fieldLabels}{name} $pdb->{appinfo}{fieldLabels}{firstName} $pdb->{appinfo}{fieldLabels}{company} $pdb->{appinfo}{fieldLabels}{phone1} $pdb->{appinfo}{fieldLabels}{phone2} $pdb->{appinfo}{fieldLabels}{phone3} $pdb->{appinfo}{fieldLabels}{phone4} $pdb->{appinfo}{fieldLabels}{phone5} $pdb->{appinfo}{fieldLabels}{phone6} $pdb->{appinfo}{fieldLabels}{phone7} $pdb->{appinfo}{fieldLabels}{phone8} $pdb->{appinfo}{fieldLabels}{address} $pdb->{appinfo}{fieldLabels}{city} $pdb->{appinfo}{fieldLabels}{state} $pdb->{appinfo}{fieldLabels}{zipCode} $pdb->{appinfo}{fieldLabels}{country} $pdb->{appinfo}{fieldLabels}{title} $pdb->{appinfo}{fieldLabels}{custom1} $pdb->{appinfo}{fieldLabels}{custom2} $pdb->{appinfo}{fieldLabels}{custom3} $pdb->{appinfo}{fieldLabels}{custom4} $pdb->{appinfo}{fieldLabels}{note} These are the names of the various fields in the address record. $pdb->{appinfo}{country} An integer: the code for the country for which these labels were designed. The country name is available as $Palm::Address::countries[$pdb->{appinfo}{country}]; $pdb->{appinfo}{misc} An integer. The least-significant bit is a flag that indicates whether the database should be sorted by company. The other bits are reserved. =head2 Sort block $pdb->{sort} This is a scalar, the raw data of the sort block. =head2 Records $record = $pdb->{records}[N]; $record->{fields}{name} $record->{fields}{firstName} $record->{fields}{company} $record->{fields}{phone1} $record->{fields}{phone2} $record->{fields}{phone3} $record->{fields}{phone4} $record->{fields}{phone5} $record->{fields}{address} $record->{fields}{city} $record->{fields}{state} $record->{fields}{zipCode} $record->{fields}{country} $record->{fields}{title} $record->{fields}{custom1} $record->{fields}{custom2} $record->{fields}{custom3} $record->{fields}{custom4} $record->{fields}{note} These are scalars, the values of the various address book fields. $record->{phoneLabel}{phone1} $record->{phoneLabel}{phone2} $record->{phoneLabel}{phone3} $record->{phoneLabel}{phone4} $record->{phoneLabel}{phone5} Most fields in an AddressBook record are straightforward: the "name" field always gives the person's last name. The "phoneI" fields, on the other hand, can mean different things in different records. There are five such fields in each record, each of which can take on one of eight different values: "Work", "Home", "Fax", "Other", "E-mail", "Main", "Pager" and "Mobile". The $record->{phoneLabel}{phone*} fields are integers. Each one is an index into @Palm::Address::phoneLabels, and indicates which particular type of phone number each of the $record->{phone*} fields represents. $record->{phoneLabel}{display} Like the phone* fields above, this is an index into @Palm::Address::phoneLabels. It indicates which of the phone* fields to display in the list view. $record->{phoneLabel}{reserved} I don't know what this is. =head1 METHODS =head2 new $pdb = new Palm::Address; Create a new PDB, initialized with the various Palm::Address fields and an empty record list. Use this method if you're creating an Address PDB from scratch. =head2 new_Record $record = $pdb->new_Record; Creates a new Address record, with blank values for all of the fields. The AppInfo block will contain only an "Unfiled" category, with ID 0. C does B add the new record to C<$pdb>. For that, you want C<$pdb-Eappend_Record>. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::Address requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS The C method initializes the AppInfo block with English labels and "United States" as the country. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/Mail.pm0000644000175000017500000003001212501047366013372 0ustar cjmcjmpackage Palm::Mail; # # ABSTRACT: Handler for Palm OS Mail databases # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); #' sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "mail", "DATA" ], ); } #' sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. $self->{name} = "MailDB"; # Default $self->{creator} = "mail"; $self->{type} = "DATA"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing, # since MailDB is explicitly not a PRC. # Initialize the AppInfo block $self->{appinfo} = { sortOrder => undef, # XXX - ? unsent => undef, # XXX - ? sigOffset => 0, # XXX - ? }; # Add the standard AppInfo block stuff &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo}); $self->{sort} = undef; # Empty sort block $self->{records} = []; # Empty list of records return $self; } sub new_Record { my $classname = shift; my $retval = $classname->SUPER::new_Record(@_); # Set the date and time on this message to today and now. This # is arguably bogus, since the Date: header on a message ought # to represent the time when the message was sent, rather than # the time when the user started composing it, but this is # better than nothing. ($retval->{year}, $retval->{month}, $retval->{day}, $retval->{hour}, $retval->{minute}) = (localtime(time))[5,4,3,2,1]; $retval->{is_read} = 0; # Message hasn't been read yet. # No delivery service notification (DSN) by default. $retval->{confirm_read} = 0; $retval->{confirm_delivery} = 0; $retval->{priority} = 1; # Normal priority $retval->{addressing} = 0; # XXX - ? # All header fields empty by default. $retval->{from} = undef; $retval->{to} = undef; $retval->{cc} = undef; $retval->{bcc} = undef; $retval->{replyTo} = undef; $retval->{sentTo} = undef; $retval->{body} = ""; return $retval; } # ParseAppInfoBlock # Parse the AppInfo block for Mail databases. sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $dirtyAppInfo; my $sortOrder; my $unsent; my $sigOffset; # XXX - Offset of signature? my $appinfo = {}; my $std_len; # Get the standard parts of the AppInfo block $std_len = &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $data = $appinfo->{other}; # Look at the non-category part # Get the rest of the AppInfo block my $unpackstr = # Argument to unpack() "x2" . # Padding "n" . # Dirty AppInfo (what is this?) "Cx" . # Sort order "N" . # Unique ID of unsent message (what is this?) "n"; # Signature offset ($dirtyAppInfo, $sortOrder, $unsent, $sigOffset) = unpack $unpackstr, $data; $appinfo->{dirty_AppInfo} = $dirtyAppInfo; $appinfo->{sort_order} = $sortOrder; $appinfo->{unsent} = $unsent; $appinfo->{sig_offset} = $sigOffset; return $appinfo; } sub PackAppInfoBlock { my $self = shift; my $retval; # Pack the non-category part of the AppInfo block $self->{appinfo}{other} = pack "x2 n Cx N n", $self->{appinfo}{dirty_AppInfo}, $self->{appinfo}{sort_order}, $self->{appinfo}{unsent}, $self->{appinfo}{sig_offset}; # Pack the AppInfo block $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } sub ParseRecord { my $self = shift; my %record = @_; my $data = $record{data}; delete $record{offset}; # This is useless delete $record{data}; my $date; my $hour; my $minute; my $flags; my $subject; my $from; my $to; my $cc; my $bcc; my $replyTo; my $sentTo; my $body; my $extra; # Extra field after body. I don't know what # it is. my $unpackstr = "n" . # Date "C" . # Hour "C" . # Minute "n"; # Flags ($date, $hour, $minute, $flags) = unpack $unpackstr, $data; my $year; my $month; my $day; if ($date != 0) { $day = $date & 0x001f; # 5 bits $month = ($date >> 5) & 0x000f; # 4 bits $year = ($date >> 9) & 0x007f; # 7 bits (years since 1904) $year += 1904; $record{year} = $year; $record{month} = $month; $record{day} = $day; $record{hour} = $hour; $record{minute} = $minute; } my $is_read = ($flags & 0x8000); my $has_signature = ($flags & 0x4000); my $confirm_read = ($flags & 0x2000); my $confirm_delivery = ($flags & 0x1000); my $priority = ($flags >> 10) & 0x03; my $addressing = ($flags >> 8) & 0x03; # The signature is problematic: it's not stored in # "MailDB.pdb": it's actually in "Saved Preferences.pdb". Work # around this somehow; either read it from "Saved # Preferences.pdb" or, more simply, just read ~/.signature if # it exists. $record{is_read} = 1 if $is_read; $record{has_signature} = 1 if $has_signature; $record{confirm_read} = 1 if $confirm_read; $record{confirm_delivery} = 1 if $confirm_delivery; $record{priority} = $priority; $record{addressing} = $addressing; my $fields = substr $data, 6; my @fields = split /\0/, $fields; ($subject, $from, $to, $cc, $bcc, $replyTo, $sentTo, $body, $extra) = @fields; # Clean things up a bit # Multi-line values are bad in these headers. Replace newlines # with commas. Ideally, we'd use arrays for multiple # recipients, but that would involve parsing addresses, which # is non-trivial. Besides, most likely we'll just wind up # sending these strings as they are to 'sendmail', which is # better equipped to parse them. $to =~ s/\s*\n\s*(?!$)/, /gs if defined($to); $cc =~ s/\s*\n\s*(?!$)/, /gs if defined($cc); $bcc =~ s/\s*\n\s*(?!$)/, /gs if defined($bcc); $replyTo =~ s/\s*\n\s*(?!$)/, /gs if defined($replyTo); $sentTo =~ s/\s*\n\s*(?!$)/, /gs if defined($sentTo); $record{subject} = $subject; $record{from} = $from; $record{to} = $to; $record{cc} = $cc; $record{bcc} = $bcc; $record{replyTo} = $replyTo; $record{sentTo} = $sentTo; $record{body} = $body; $record{extra} = $extra; return \%record; } sub PackRecord { my $self = shift; my $record = shift; my $retval; my $rawDate; my $flags; $rawDate = ($record->{day} & 0x001f) | (($record->{month} & 0x000f) << 5) | ((($record->{year} - 1904) & 0x07f) << 9); $flags = 0; $flags |= 0x8000 if $record->{is_read}; $flags |= 0x4000 if $record->{has_signature}; $flags |= 0x2000 if $record->{confirm_read}; $flags |= 0x1000 if $record->{confirm_delivery}; $flags |= (($record->{priority} & 0x03) << 10); $flags |= (($record->{addressing} & 0x03) << 8); $retval = pack "n C C n", $rawDate, $record->{hour}, $record->{minute}, $flags; # can't leave any of these undef or join() complains foreach (qw(subject from to cc bcc replyTo sentTo body) ) { $record->{$_} ||= ""; } $retval .= join "\0", $record->{subject}, $record->{from}, $record->{to}, $record->{cc}, $record->{bcc}, $record->{replyTo}, $record->{sentTo}, $record->{body}; $retval .= "\0"; return $retval; } 1; __END__ =head1 NAME Palm::Mail - Handler for Palm OS Mail databases =head1 VERSION This document describes version 1.400 of Palm::Mail, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::Mail; =head1 DESCRIPTION The Mail PDB handler is a helper class for the Palm::PDB package. It parses Mail databases. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. Other fields include: $pdb->{appinfo}{sortOrder} $pdb->{appinfo}{unsent} $pdb->{appinfo}{sigOffset} I don't know what these are. =head2 Sort block $pdb->{sort} This is a scalar, the raw data of the sort block. =head2 Records $record = $pdb->{records}[N] $record->{year} $record->{month} $record->{day} $record->{hour} $record->{minute} The message's timestamp. $record->{is_read} This is defined and true iff the message has been read. $record->{has_signature} For outgoing messages, this is defined and true iff the message should have a signature attached. The signature itself is stored in the "Saved Preferences.prc" database, and is of type "mail" with ID 2. $record->{confirm_read} If this is defined and true, then the sender requests notification when the message has been read. $record->{confirm_delivery} If this is defined and true, then the sender requests notification when the message has been delivered. $record->{priority} An integer in the range 0-2, for high, normal, or low priority, respectively. $record->{addressing} An integer in the range 0-2, indicating the addressing type: To, Cc, or Bcc respectively. I don't know what this means. $record->{subject} $record->{from} $record->{to} $record->{cc} $record->{bcc} $record->{replyTo} $record->{sentTo} Strings, the various header fields. $record->{body} A string, the body of the message. =head1 METHODS =head2 new $pdb = new Palm::Mail; Create a new PDB, initialized with the various Palm::Mail fields and an empty record list. Use this method if you're creating a Mail PDB from scratch. =head2 new_Record $record = $pdb->new_Record; Creates a new Mail record, with blank values for all of the fields. C does B add the new record to C<$pdb>. For that, you want C<$pdb-Eappend_Record>. Note: the time given by the C, C, C, C, and C fields in the new record are initialized to the time when the record was created. They should be reset to the time when the message was sent. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::Mail requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/Memo.pm0000644000175000017500000001417712501047366013423 0ustar cjmcjmpackage Palm::Memo; # # ABSTRACT: Read/write Palm OS Memo databases # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); #' sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "memo", "DATA" ], ); } #' sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. $self->{name} = "MemoDB"; # Default $self->{creator} = "memo"; $self->{type} = "DATA"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing, # since MemoDB is explicitly not a PRC. # Initialize the AppInfo block $self->{appinfo} = { sortOrder => undef, # XXX - ? }; # Add the standard AppInfo block stuff &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo}); # Give the PDB a blank sort block $self->{sort} = undef; # Give the PDB an empty list of records $self->{records} = []; return $self; } sub new_Record { my $classname = shift; my $retval = $classname->SUPER::new_Record(@_); $retval->{data} = ""; return $retval; } # ParseAppInfoBlock # Parse the AppInfo block for Memo databases. sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $sortOrder; my $i; my $appinfo = {}; my $std_len; # Get the standard parts of the AppInfo block $std_len = &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $data = $appinfo->{other}; # Look at the non-category part # Get the rest of the AppInfo block my $unpackstr = # Argument to unpack() "x4" . # Padding "C"; # Sort order ($sortOrder) = unpack $unpackstr, $data; $appinfo->{sortOrder} = $sortOrder; return $appinfo; } sub PackAppInfoBlock { my $self = shift; my $retval; my $i; # Pack the non-category part of the AppInfo block $self->{appinfo}{other} = pack("x4 C x1", $self->{appinfo}{sortOrder}); # Pack the AppInfo block $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } sub PackSortBlock { # XXX return undef; } sub ParseRecord { my $self = shift; my %record = @_; delete $record{offset}; # This is useless $record{data} =~ s/\0$//; # Trim trailing NUL return \%record; } sub PackRecord { my $self = shift; my $record = shift; return $record->{data} . "\0"; # Add the trailing NUL } 1; __END__ =head1 NAME Palm::Memo - Handler for Palm Memo databases. =head1 VERSION This document describes version 1.400 of Palm::Memo, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::Memo; =head1 DESCRIPTION The Memo PDB handler is a helper class for the Palm::PDB package. It parses Memo databases. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. Other fields include: $pdb->{appinfo}{sortOrder} I don't know what this is. =head2 Sort block $pdb->{sort} This is a scalar, the raw data of the sort block. =head2 Records $record = $pdb->{records}[N] $record->{data} A string, the text of the memo. =head2 new $pdb = new Palm::Memo; Create a new PDB, initialized with the various Palm::Memo fields and an empty record list. Use this method if you're creating a Memo PDB from scratch. =head2 new_Record $record = $pdb->new_Record; Creates a new Memo record, with blank values for all of the fields. C does B add the new record to C<$pdb>. For that, you want C<$pdb-Eappend_Record>. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::Memo requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm/ToDo.pm0000644000175000017500000002055412501047366013367 0ustar cjmcjmpackage Palm::ToDo; # # ABSTRACT: Handler for Palm ToDo databases # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. # XXX - Bug: apparently, the first ToDo item shows up with a category # of "unfiled" use strict; use Palm::Raw(); use Palm::StdAppInfo(); use vars qw( $VERSION @ISA ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) @ISA = qw( Palm::StdAppInfo Palm::Raw ); #' sub import { &Palm::PDB::RegisterPDBHandlers(__PACKAGE__, [ "todo", "DATA" ], ); } #' # new # Create a new Palm::ToDo database, and return it sub new { my $classname = shift; my $self = $classname->SUPER::new(@_); # Create a generic PDB. No need to rebless it, # though. $self->{name} = "ToDoDB"; # Default $self->{creator} = "todo"; $self->{type} = "DATA"; $self->{attributes}{resource} = 0; # The PDB is not a resource database by # default, but it's worth emphasizing, # since ToDoDB is explicitly not a PRC. # Initialize the AppInfo block $self->{appinfo} = { dirty_appinfo => undef, # ? sortOrder => undef, # ? }; # Add the standard AppInfo block stuff &Palm::StdAppInfo::seed_StdAppInfo($self->{appinfo}); # Give the PDB a blank sort block $self->{sort} = undef; # Give the PDB an empty list of records $self->{records} = []; return $self; } # new_Record # Create a new, initialized record. sub new_Record { my $classname = shift; my $retval = $classname->SUPER::new_Record(@_); # Item has no due date by default. $retval->{due_day} = undef; $retval->{due_month} = undef; $retval->{due_year} = undef; $retval->{completed} = 0; # Not completed $retval->{priority} = 1; # Empty description, no note. $retval->{description} = ""; $retval->{note} = undef; return $retval; } # ParseAppInfoBlock # Parse the AppInfo block for ToDo databases. sub ParseAppInfoBlock { my $self = shift; my $data = shift; my $dirtyAppInfo; my $sortOrder; my $appinfo = {}; my $std_len; # Get the standard parts of the AppInfo block $std_len = &Palm::StdAppInfo::parse_StdAppInfo($appinfo, $data); $data = $appinfo->{other}; # Look at the non-category part # Get the rest of the AppInfo block my $unpackstr = # Argument to unpack() "x2" . # Reserved "n" . # XXX - Dirty AppInfo (what is this?) "Cx"; # Sort order ($dirtyAppInfo, $sortOrder) = unpack $unpackstr, $data; $appinfo->{dirty_appinfo} = $dirtyAppInfo; $appinfo->{sort_order} = $sortOrder; return $appinfo; } sub PackAppInfoBlock { my $self = shift; my $retval; # Pack the application-specific part of the AppInfo block $self->{appinfo}{other} = pack("x2 n Cx", $self->{appinfo}{dirty_appinfo}, $self->{appinfo}{sort_order}); # Pack the AppInfo block $retval = &Palm::StdAppInfo::pack_StdAppInfo($self->{appinfo}); return $retval; } sub ParseRecord { my $self = shift; my %record = @_; my $data = $record{data}; delete $record{offset}; # This is useless delete $record{data}; # No longer necessary my $date; my $priority; ($date, $priority) = unpack "n C", $data; $data = substr $data, 3; # Remove the stuff we've already seen if ($date != 0xffff) { my $day; my $month; my $year; $day = $date & 0x001f; # 5 bits $month = ($date >> 5) & 0x000f; # 4 bits $year = ($date >> 9) & 0x007f; # 7 bits (years since 1904) $year += 1904; $record{due_day} = $day; $record{due_month} = $month; $record{due_year} = $year; } my $completed; # Boolean $completed = $priority & 0x80; $priority &= 0x7f; # Strip high bit $record{completed} = 1 if $completed; $record{priority} = $priority; my $description; my $note; ($description, $note) = split /\0/, $data; $record{description} = $description; $record{note} = $note unless $note eq ""; return \%record; } sub PackRecord { my $self = shift; my $record = shift; my $retval; my $rawDate; my $priority; if (defined($record->{due_day})) { $rawDate = ($record->{due_day} & 0x001f) | (($record->{due_month} & 0x000f) << 5) | ((($record->{due_year} - 1904) & 0x007f) << 9); } else { $rawDate = 0xffff; } $priority = $record->{priority} & 0x7f; $priority |= 0x80 if $record->{completed}; $retval = pack "n C", $rawDate, $priority; $retval .= $record->{description} . "\0"; $retval .= $record->{note} . "\0"; return $retval; } 1; __END__ =head1 NAME Palm::ToDo - Handler for Palm ToDo databases =head1 VERSION This document describes version 1.400 of Palm::ToDo, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS use Palm::ToDo; =head1 DESCRIPTION The ToDo PDB handler is a helper class for the Palm::PDB package. It parses ToDo databases. =head2 AppInfo block The AppInfo block begins with standard category support. See L for details. Other fields include: $pdb->{appinfo}{dirty_appinfo} $pdb->{appinfo}{sortOrder} I don't know what these are. =head2 Sort block $pdb->{sort} This is a scalar, the raw data of the sort block. =head2 Records $record = $pdb->{records}[N] $record->{due_day} $record->{due_month} $record->{due_year} The due date of the ToDo item. If the item has no due date, these are undefined. $record->{completed} This is defined and true iff the item has been completed. $record->{priority} An integer. The priority of the item. $record->{description} A text string. The description of the item. $record->{note} A text string. The note attached to the item. Undefined if the item has no note. =head2 new $pdb = new Palm::ToDo; Create a new PDB, initialized with the various Palm::ToDo fields and an empty record list. Use this method if you're creating a ToDo PDB from scratch. =head2 new_Record $record = $pdb->new_Record; Creates a new ToDo record, with blank values for all of the fields. C does B add the new record to C<$pdb>. For that, you want C<$pdb-Eappend_Record>. =head1 SEE ALSO L L =head1 CONFIGURATION AND ENVIRONMENT Palm::ToDo requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/lib/Palm.pm0000644000175000017500000001005112501047366012511 0ustar cjmcjmpackage Palm; # # ABSTRACT: Palm OS utility functions # # Copyright (C) 1999, 2000, Andrew Arensburger. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. use strict; use warnings; use vars qw( $VERSION ); # One liner, to allow MakeMaker to work. $VERSION = '1.400'; # This file is part of Palm 1.400 (March 14, 2015) my $EPOCH_1904 = 2082844800; # Difference between Palm's # epoch (Jan. 1, 1904) and # Unix's epoch (Jan. 1, 1970), # in seconds. sub palm2epoch { return $_[0] - $EPOCH_1904; } sub epoch2palm { return $_[0] + $EPOCH_1904; } sub mkpdbname { my $name = shift; $name =~ s![%/\x00-\x19\x7f-\xff]!sprintf("%%%02X",ord($&))!ge; return $name; } 1; __END__ =head1 NAME Palm - Palm OS utility functions =head1 VERSION This document describes version 1.400 of Palm, released March 14, 2015 as part of Palm version 1.400. =head1 SYNOPSIS =head1 DESCRIPTION =head1 FUNCTIONS =head2 palm2epoch my @parts = localtime( palm2epoch($palmtime) ); Converts a S timestamp to a Unix Epoch time. Note, however, that S time is in the timezone of the Palm itself while Epoch is defined to be in the GMT timezone. Further conversion may be necessary. =head2 epoch2palm my $palmtime = epoch2palm( time() ); Converts Unix epoch time to Palm OS time. =head2 mkpdbname $PDB->Write( mkpdbname($PDB->{name}) ); Convert a S database name to a 7-bit ASCII representation. Native Palm database names can be found in ISO-8859-1 encoding. This encoding isn't going to generate the most portable of filenames and, in particular, ColdSync databases use this representation. =head1 SEE ALSO L =head1 CONFIGURATION AND ENVIRONMENT Palm requires no configuration files or environment variables. =head1 INCOMPATIBILITIES None reported. =head1 BUGS AND LIMITATIONS No bugs have been reported. =head1 AUTHORS Andrew Arensburger C<< >> Currently maintained by Christopher J. Madsen C<< >> Please report any bugs or feature requests to S >>> or through the web interface at L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Palm >>. You can follow or contribute to p5-Palm's development at L<< https://github.com/madsen/p5-Palm >>. =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. =cut Palm-1.400/META.json0000644000175000017500000002405512501047366012146 0ustar cjmcjm{ "abstract" : "Read & write Palm OS databases (both PDB and PRC)", "author" : [ "Christopher J. Madsen " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.029, CPAN::Meta::Converter version 2.142690", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Palm", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "develop" : { "requires" : { "Pod::Coverage::TrustPod" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08" } }, "runtime" : { "requires" : { "Exporter" : "0", "POSIX" : "0", "Palm::Raw" : "0", "constant" : "0", "vars" : "0" } }, "test" : { "requires" : { "Palm::PDB" : "0", "Test::More" : "0" } } }, "release_status" : "stable", "resources" : { "repository" : { "type" : "git", "url" : "git://github.com/madsen/p5-Palm.git", "web" : "https://github.com/madsen/p5-Palm" } }, "version" : "1.400", "x_Dist_Zilla" : { "perl" : { "version" : "5.018002" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::VersionFromModule", "name" : "CJM/VersionFromModule", "version" : "0.08" }, { "class" : "Dist::Zilla::Plugin::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [], "exclude_match" : [], "follow_symlinks" : "0", "include_dotfiles" : "0", "prefix" : "", "prune_directory" : [], "root" : "." } }, "name" : "CJM/GatherDir", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::PruneCruft", "name" : "CJM/PruneCruft", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "CJM/ManifestSkip", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "CJM/MetaJSON", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "CJM/MetaYAML", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "CJM/License", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::Test::PrereqsFromMeta", "name" : "CJM/Test::PrereqsFromMeta", "version" : "4.23" }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "CJM/PodSyntaxTests", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::PodCoverageTests", "name" : "CJM/PodCoverageTests", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::PodLoom", "config" : { "Pod::Loom version" : "0.08" }, "name" : "CJM/PodLoom", "version" : "5.00" }, { "class" : "Dist::Zilla::Plugin::MakeMaker", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "CJM/MakeMaker", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::RunExtraTests", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "CJM/RunExtraTests", "version" : "0.011" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "CJM/MetaConfig", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::MatchManifest", "name" : "CJM/MatchManifest", "version" : "4.02" }, { "class" : "Dist::Zilla::Plugin::RecommendedPrereqs", "name" : "CJM/RecommendedPrereqs", "version" : "4.21" }, { "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", "name" : "CJM/CheckPrereqsIndexed", "version" : "0.009" }, { "class" : "Dist::Zilla::Plugin::GitVersionCheckCJM", "name" : "CJM/GitVersionCheckCJM", "version" : "4.26" }, { "class" : "Dist::Zilla::Plugin::TemplateCJM", "name" : "CJM/TemplateCJM", "version" : "4.22" }, { "class" : "Dist::Zilla::Plugin::Repository", "name" : "CJM/Repository", "version" : "0.19" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "CJM/@Git/Check", "version" : "2.030" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "Updated Changes for %{MMMM d, yyyy}d%{ trial}t release of %v", "time_zone" : "local" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "CJM/@Git/Commit", "version" : "2.030" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "signed" : 0, "tag" : "1.400", "tag_format" : "%v%t", "tag_message" : "Tagged %N %v%{ (trial release)}t", "time_zone" : "local" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "CJM/@Git/Tag", "version" : "2.030" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "github master" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "CJM/@Git/Push", "version" : "2.030" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "CJM/TestRelease", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "CJM/UploadToCPAN", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::ArchiveRelease", "name" : "CJM/ArchiveRelease", "version" : "4.26" }, { "class" : "Dist::Zilla::Plugin::AutoPrereqs", "name" : "AutoPrereqs", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::Encoding", "name" : "Encoding", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::OurPkgVersion", "name" : "OurPkgVersion", "version" : "0.005001" }, { "class" : "Dist::Zilla::Plugin::FileFinder::ByName", "name" : ":TestFiles", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FileFinder::ByName", "name" : ":PodExamples", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "5.029" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "5.029" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : "0" }, "version" : "5.029" } } } Palm-1.400/META.yml0000644000175000017500000001427412501047366012000 0ustar cjmcjm--- abstract: 'Read & write Palm OS databases (both PDB and PRC)' author: - 'Christopher J. Madsen ' build_requires: Palm::PDB: 0 Test::More: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 0 generated_by: 'Dist::Zilla version 5.029, CPAN::Meta::Converter version 2.142690' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Palm requires: Exporter: 0 POSIX: 0 Palm::Raw: 0 constant: 0 vars: 0 resources: repository: git://github.com/madsen/p5-Palm.git version: 1.400 x_Dist_Zilla: perl: version: 5.018002 plugins: - class: Dist::Zilla::Plugin::VersionFromModule name: CJM/VersionFromModule version: 0.08 - class: Dist::Zilla::Plugin::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: [] exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: '.' name: CJM/GatherDir version: 5.029 - class: Dist::Zilla::Plugin::PruneCruft name: CJM/PruneCruft version: 5.029 - class: Dist::Zilla::Plugin::ManifestSkip name: CJM/ManifestSkip version: 5.029 - class: Dist::Zilla::Plugin::MetaJSON name: CJM/MetaJSON version: 5.029 - class: Dist::Zilla::Plugin::MetaYAML name: CJM/MetaYAML version: 5.029 - class: Dist::Zilla::Plugin::License name: CJM/License version: 5.029 - class: Dist::Zilla::Plugin::Test::PrereqsFromMeta name: CJM/Test::PrereqsFromMeta version: 4.23 - class: Dist::Zilla::Plugin::PodSyntaxTests name: CJM/PodSyntaxTests version: 5.029 - class: Dist::Zilla::Plugin::PodCoverageTests name: CJM/PodCoverageTests version: 5.029 - class: Dist::Zilla::Plugin::PodLoom config: Pod::Loom version: 0.08 name: CJM/PodLoom version: 5.00 - class: Dist::Zilla::Plugin::MakeMaker config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: CJM/MakeMaker version: 5.029 - class: Dist::Zilla::Plugin::RunExtraTests config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: CJM/RunExtraTests version: 0.011 - class: Dist::Zilla::Plugin::MetaConfig name: CJM/MetaConfig version: 5.029 - class: Dist::Zilla::Plugin::MatchManifest name: CJM/MatchManifest version: 4.02 - class: Dist::Zilla::Plugin::RecommendedPrereqs name: CJM/RecommendedPrereqs version: 4.21 - class: Dist::Zilla::Plugin::CheckPrereqsIndexed name: CJM/CheckPrereqsIndexed version: 0.009 - class: Dist::Zilla::Plugin::GitVersionCheckCJM name: CJM/GitVersionCheckCJM version: 4.26 - class: Dist::Zilla::Plugin::TemplateCJM name: CJM/TemplateCJM version: 4.22 - class: Dist::Zilla::Plugin::Repository name: CJM/Repository version: 0.19 - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: repo_root: '.' name: CJM/@Git/Check version: 2.030 - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: 'Updated Changes for %{MMMM d, yyyy}d%{ trial}t release of %v' time_zone: local Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: repo_root: '.' name: CJM/@Git/Commit version: 2.030 - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ signed: 0 tag: 1.400 tag_format: '%v%t' tag_message: 'Tagged %N %v%{ (trial release)}t' time_zone: local Dist::Zilla::Role::Git::Repo: repo_root: '.' name: CJM/@Git/Tag version: 2.030 - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - 'github master' remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: repo_root: '.' name: CJM/@Git/Push version: 2.030 - class: Dist::Zilla::Plugin::TestRelease name: CJM/TestRelease version: 5.029 - class: Dist::Zilla::Plugin::UploadToCPAN name: CJM/UploadToCPAN version: 5.029 - class: Dist::Zilla::Plugin::ArchiveRelease name: CJM/ArchiveRelease version: 4.26 - class: Dist::Zilla::Plugin::AutoPrereqs name: AutoPrereqs version: 5.029 - class: Dist::Zilla::Plugin::Encoding name: Encoding version: 5.029 - class: Dist::Zilla::Plugin::OurPkgVersion name: OurPkgVersion version: 0.005001 - class: Dist::Zilla::Plugin::FileFinder::ByName name: ':TestFiles' version: 5.029 - class: Dist::Zilla::Plugin::FileFinder::ByName name: ':PodExamples' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: 5.029 - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: 5.029 zilla: class: Dist::Zilla::Dist::Builder config: is_trial: 0 version: 5.029 Palm-1.400/MANIFEST0000644000175000017500000000103112501047366011643 0ustar cjmcjmChanges FAQ LICENSE MANIFEST META.json META.yml Makefile.PL README TODO examples/add-memo examples/copydb examples/pdbdump lib/Palm.pm lib/Palm/Address.pm lib/Palm/DateTime.pm lib/Palm/Datebook.pm lib/Palm/Mail.pm lib/Palm/Memo.pm lib/Palm/StdAppInfo.pm lib/Palm/ToDo.pm lib/Palm/ZirePhoto.pm t/00-all_prereqs.t t/00-load.t t/AddressDB.pdb t/DatebookDB.pdb t/MailDB.pdb t/MemoDB.pdb t/ToDoDB.pdb t/address.t t/datebook.t t/mail.t t/memo.t t/mkpdbname.t t/pod.t t/pod_coverage.t t/todo.t xt/release/pod-coverage.t xt/release/pod-syntax.t Palm-1.400/LICENSE0000644000175000017500000004376612501047366011544 0ustar cjmcjmThis software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Palm-1.400/t/0000755000175000017500000000000012501047366010762 5ustar cjmcjmPalm-1.400/t/00-all_prereqs.t0000644000175000017500000000533112501047366013677 0ustar cjmcjm#!perl use strict; use warnings; # This doesn't use Test::More because I don't want to clutter %INC # with modules that aren't prerequisites. my $test = 0; my $tests_completed; sub ok ($$) { my ($ok, $name) = @_; printf "%sok %d - %s\n", ($ok ? '' : 'not '), ++$test, $name; return $ok; } # end ok END { ok(0, 'unknown failure') unless defined $tests_completed; print "1..$tests_completed\n"; } sub get_version { my ($package) = @_; local $@; my $version = eval { $package->VERSION }; defined $version ? $version : 'undef'; } # end get_version TEST: { ok(open(META, ') { last if /^\s*"prereqs" : \{\s*\z/; } # end while ok(defined $_, 'found prereqs') or last TEST; while () { last if /^\s*\},?\s*\z/; ok(/^\s*"(.+)" : \{\s*\z/, "found phase $1") or last TEST; my $phase = $1; while () { last if /^\s*\},?\s*\z/; next if /^\s*"[^"]+"\s*:\s*\{\s*\},?\s*\z/; ok(/^\s*"(.+)" : \{\s*\z/, "found relationship $phase $1") or last TEST; my $rel = $1; while () { last if /^\s*\},?\s*\z/; ok(/^\s*"([^"]+)"\s*:\s*(\S+?),?\s*\z/, "found prereq $1") or last TEST; my ($prereq, $version) = ($1, $2); next if $phase ne 'runtime' or $prereq eq 'perl'; # Need a special case for if.pm, because "require if;" is a syntax error. my $loaded = ($prereq eq 'if') ? eval "require '$prereq.pm'; 1" : eval "require $prereq; 1"; if ($rel eq 'requires') { ok($loaded, "loaded $prereq") or print STDERR "\n# ERROR: Wanted: $prereq $version\n"; } else { ok(1, ($loaded ? 'loaded' : 'failed to load') . " $prereq"); } if ($loaded and not ($version eq '"0"' or eval "'$prereq'->VERSION($version); 1")) { printf STDERR "\n# WARNING: Got: %s %s\n# Wanted: %s %s\n", $prereq, get_version($prereq), $prereq, $version; } } # end while in prerequisites } # end while in relationship } # end while in phase close META; # Print version of all loaded modules: if ($ENV{AUTOMATED_TESTING} or (@ARGV and ($ARGV[0] eq '-v' or $ARGV[0] eq '--verbose'))) { print STDERR "# Listing %INC\n"; my @packages = grep { s/\.pm\Z// and do { s![\\/]!::!g; 1 } } sort keys %INC; my $len = 0; for (@packages) { $len = length if length > $len } $len = 68 if $len > 68; for my $package (@packages) { printf STDERR "# %${len}s %s\n", $package, get_version($package); } } # end if AUTOMATED_TESTING } # end TEST $tests_completed = $test; Palm-1.400/t/pod_coverage.t0000644000175000017500000000103312501047366013601 0ustar cjmcjmuse vars qw(@classes %ignore); %ignore = ( Palm::PDB => [ qw( new_Resource ) ], ); BEGIN { @classes = map { "Palm::$_" } qw( Address Datebook Mail Memo PDB Raw StdAppInfo ToDo ); } use Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; plan tests => scalar @classes; foreach my $class ( @classes ) { pod_coverage_ok( $class, { also_private => [ qr/^Pa(ck|rse)/, @{ $ignore{$class} || [] } ], }, "$class pod coverage", ); } Palm-1.400/t/DatebookDB.pdb0000644000175000017500000000122012501047366013402 0ustar cjmcjmDatebookDB/vDATAdatet@[P@[P@[P)@[P?@[PO@[Po@[P ȏ$11 to 12, repeat daily ȏ$!12 to 1:30, repeat weekly until 2007ȏ$all day event, yearly repeatȏuntimed event ȏ:8 tro 9 ȏD9 to 10, 15 min alarm ȏD10 to 11, 3 hour alarmPalm-1.400/t/AddressDB.pdb0000644000175000017500000000251212501047366013244 0ustar cjmcjmAddressDB:i/vvvv`DATAaddrUnfiledBusinessPersonalQuickList ?Last nameFirst nameCompanyWorkHomeFaxOtherE-mailAddressCityStateZip CodeCountryTitleCustom 1Custom 2Custom 3Custom 4NoteMainPagerMobile5U AccessoriesPalm, Inc.800-881-7256 (US)800-891-6342 (Canada)Int'l: See Worldwide Customer Support Information CardWebsite: www.palm.comTo find accessories and useful add-on software, please visit our web site at www.palm.com.2UTechnical SupportPalm, Inc.847-262-PALM (7256) (US)Int'l: See Worldwide Customer Support Information CardWebsite: www.palm.comsupport@palm.comFor technical support outside of the US, please use the numbers listed on the Worldwide Customer Support Information card. For the latest information on products and upgrades, check our web site regularly at www.palm.com.Palm-1.400/t/mkpdbname.t0000644000175000017500000000034312501047366013105 0ustar cjmcjmuse Test::More tests => 5; BEGIN { use_ok('Palm') } for( "Test.pdb", "Test\x04.pdb", "Test\x80.prc", "Test\xfe.pdb" ) { print "Trying $_..."; my $n = Palm::mkpdbname( $_ ); print $n,"\n"; ok( $n =~ m/[\x21-\x73]/ ); } 1; Palm-1.400/t/MailDB.pdb0000644000175000017500000000076412501047366012550 0ustar cjmcjmMailDB=k`DATAmailtARARInboxOutboxDeletedFiledDraft  Dtestchrissomeone elsethis is a test e-mail@test2 chris this is a high priority mailingPalm-1.400/t/datebook.t0000755000175000017500000000162712501047366012750 0ustar cjmcjm# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..3\n"; } END {print "not ok 1\n" unless $loaded;} use Palm::PDB; $loaded = 1; print "ok 1\n"; use Palm::Datebook; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): my $pdb = new Palm::PDB; eval { $pdb->Load( 't/DatebookDB.pdb' ); }; unless( $@ ) { print "ok 2\n"; } else { print "not ok 2\n"; } my $recs = 0; for( @{$pdb->{'records'}} ) { $recs ++; } print (($recs == 7) ? "ok 3\n" : "not ok 3\n"); 1; Palm-1.400/t/MemoDB.pdb0000644000175000017500000000660612501047366012564 0ustar cjmcjmMemoDBuvvvvpDATAmemo 8UnfiledBusinessPersonal Handheld Basics Press any application button to turn on your handheld computer and start a main application. Tap New to create a new record. Tap a record to edit it. Tap Details to access more options or delete the record. Tap the pick list in the upper-right corner to categorize records or create a new category. (Not in Date Book.) Tap the information ("i") icon in dialog boxes for tips. Press the HotSync button on the cable to exchange and update data between your computer and your handheld.4 Ways to Enter Text 1. Type into your Desktop software, attach your handheld to the cable, and press the HotSync button to transfer the typed data. 2. Use the onscreen keyboard. In the Graffiti writing area below, tap the dot below "abc" for the alphabetic keyboard or the dot below "123" for the numeric keyboard. 3. Use the stylus to write Graffiti characters in the writing area. Characters are mainly uppercase, single-stroke letters. Write letters on the left, numbers on the right. Note: To call up a Graffiti reference screen, drag the stylus from the bottom of the writing area to the top of the screen. Or see the Graffiti Reference Card. 4. Connect a portable keyboard to your handheld and type the data directly into your handheld.Download Free Applications You can easily download lots of freeware, shareware, and commercial applications from the Internet. Just follow these 4 steps: 1. Select and download applications from any Palm related web site (e.g., www.palm.com). 2. If the downloaded application is a Zip file, unzip its contents to the add-on folder in the Desktop Software directory (e.g., c:\palm\add-on). 3. Open the Palm Desktop software and click Install (or run the Install Tool from the Palm Desktop software directory). Then click Add. Select the applications you want to install. Click Open, then click Done. 4. Perform a HotSync operation to transfer your new applications to your handheld.Power Tips To improve your Graffiti accuracy, write letters BIG. (Having trouble with "V"? Try writing it backwards.) In Date Book Day View, press the scroll button on your handheld to move backward and forward one day at a time. To move an event to another day or time, tap Details and change the day or time there. In Note Pad, To Do List, and Memo you don't have to tap New to create a new record; just start writing. In Note Pad, this creates a title for a new note or drawing. In Date Book, this creates a new UNTIMED event. To create a new TIMED event, just write the time in the Graffiti number area. To set up your business card for beaming, go to Address Book and select your own name & address. Tap Menu. Then tap Select Business Card. To quickly find an application icon in the Launcher, switch to the All category and use Graffiti writing to write the first letter of the application's title. The icons with titles starting with that letter spring to view. Want to change your alarm sounds? In Date Book, Note Pad, or Clock, choose Preferences from the Options menu. Palm-1.400/t/ToDoDB.pdb0000644000175000017500000000145612501047366012532 0ustar cjmcjmToDoDB0ZvwvwXDATAtodorUnfiledBusinessPersonal Don't forget to register!To register your Palm handheld electronically, you must have an Internet connection or a modem connected to your computer. Or if you prefer, you can fill out and send the mail-in registration card included in your Palm package. Special rewards only for registered users: -FREE software programs * -Upgrade information -Important updates * For a complete list of free software, go to www.palm.com/eregdownload Palm-1.400/t/00-load.t0000644000175000017500000000034512501047366012305 0ustar cjmcjmuse vars qw(@classes); BEGIN { @classes = ('Palm', map { "Palm::$_" } qw( Address Datebook Mail Memo StdAppInfo ToDo )); } use Test::More tests => scalar @classes; foreach my $class ( @classes ) { use_ok( $class ); } Palm-1.400/t/address.t0000755000175000017500000000162512501047366012603 0ustar cjmcjm# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..3\n"; } END {print "not ok 1\n" unless $loaded;} use Palm::PDB; $loaded = 1; print "ok 1\n"; use Palm::Address; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): my $pdb = new Palm::PDB; eval { $pdb->Load( 't/AddressDB.pdb' ); }; unless( $@ ) { print "ok 2\n"; } else { print "not ok 2\n"; } my $recs = 0; for( @{$pdb->{'records'}} ) { $recs ++; } print (($recs == 2) ? "ok 3\n" : "not ok 3\n"); 1; Palm-1.400/t/mail.t0000755000175000017500000000161712501047366012101 0ustar cjmcjm# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..3\n"; } END {print "not ok 1\n" unless $loaded;} use Palm::PDB; $loaded = 1; print "ok 1\n"; use Palm::Mail; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): my $pdb = new Palm::PDB; eval { $pdb->Load( 't/MailDB.pdb' ); }; unless( $@ ) { print "ok 2\n"; } else { print "not ok 2\n"; } my $recs = 0; for( @{$pdb->{'records'}} ) { $recs ++; } print (($recs == 2) ? "ok 3\n" : "not ok 3\n"); 1; Palm-1.400/t/todo.t0000755000175000017500000000161712501047366012124 0ustar cjmcjm# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..3\n"; } END {print "not ok 1\n" unless $loaded;} use Palm::PDB; $loaded = 1; print "ok 1\n"; use Palm::ToDo; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): my $pdb = new Palm::PDB; eval { $pdb->Load( 't/ToDoDB.pdb' ); }; unless( $@ ) { print "ok 2\n"; } else { print "not ok 2\n"; } my $recs = 0; for( @{$pdb->{'records'}} ) { $recs ++; } print (($recs == 1) ? "ok 3\n" : "not ok 3\n"); 1; Palm-1.400/t/memo.t0000755000175000017500000000161712501047366012114 0ustar cjmcjm# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..3\n"; } END {print "not ok 1\n" unless $loaded;} use Palm::PDB; $loaded = 1; print "ok 1\n"; use Palm::Memo; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): my $pdb = new Palm::PDB; eval { $pdb->Load( 't/MemoDB.pdb' ); }; unless( $@ ) { print "ok 2\n"; } else { print "not ok 2\n"; } my $recs = 0; for( @{$pdb->{'records'}} ) { $recs ++; } print (($recs == 4) ? "ok 3\n" : "not ok 3\n"); 1; Palm-1.400/t/pod.t0000644000175000017500000000020112501047366011722 0ustar cjmcjmuse Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); Palm-1.400/Changes0000644000175000017500000005337412501047366012026 0ustar cjmcjmRevision history for p5-Palm (now the Palm distribution) 1.400 2015-03-14 Release by Christopher J. Madsen - Bump version number to be greater than all previous releases. Palm::StdAppInfo 1.20 was released in p5-Palm 1.008, but p5-Palm 1.009 contained Palm::StdAppInfo 1.009. The other modules had similar issues. Version numbers shouldn't go backwards. I'm jumping them to 1.400 to match Palm::PDB. (reported by David Cantrell - Palm::PDB GitHub#1) 1.015 2015-02-14 Release by Christopher J. Madsen - Update 00-all_prereqs.t to Test::PrereqsFromMeta 4.23 1.014 2014-08-02 Release by Christopher J. Madsen - New maintainer Christopher J. Madsen - Palm::PDB & Palm::Raw are now distributed separately - With permission from Andrew Arensburger & Alessandro Zummo p5-Palm is now distributed under the same terms as Perl 5 - Fix POD spelling error in Palm::ZirePhoto (RT#93436) (thanks, Jonathan Yu) 1.013 2013-08-21 Release by brian d foy - Add notice that this distribution is in need of a new maintainer 1.012 2010-02-23 Release by brian d foy - Promote to a full release from the latest development cycle 1.011_01 2010-01-02 Trial Release by brian d foy - Palm/Datebook.pm: add support for time zone entries (Tim Adye ) 1.011 2009-08-17 Release by brian d foy - Palm/Datebook.pm: add support for the newer-format Palm Calendar databases (Tim Adye ) 1.009 2007-07-30 Release by brian d foy - cleaned up the pod coverage test. - add License and Author stuff to the distro 1.006 2007-01-15 Release by brian d foy - chromatic sent me some changes living in another distro (p5-Palm-1.004_000). It catches up 1.003_000 for all of the changes since November 2002 listed in this file. 1.005 2007-01-13 Release by brian d foy - Cleansed the dist to make it installable by CPAN tools. It just needs a version without a _ in it. (http://rt.cpan.org/Ticket/Display.html?id=12837) 1.004 2004-04-15 Various Authors The release history before version 1.006 is muddled. These are the changes listed, but it's not clear what was released when. 2004-04-15 21:21 christophe - Palm/PDB.pm, util/pdbdump: Added some logic to detect broken databases during loading: - database names _must_ contain the terminating NUL within the first 32 characters of the header. This catches obviously broken situations like text files renamed to .pdb files (which, oddly enough, happens a lot when you're trying to process text files into Doc files). - position offsets mustn't go beyond the end of the database file ($pdb->{_size}). This indicates either truncation of the db or straight corruption. 2004-04-08 22:55 christophe - Palm/PDB.pm: make it impossible to create a nameless database. It can't be uploaded to the PDA, that's for sure. 2003-11-09 20:40 azummo - Palm/PDB.pm: Handle uniqueID and uniqueIDseed in the Palm OS way. 2003-11-05 15:19 azummo - Palm/DateTime.pm: Fixed ISO8601 format in palmtime_to_iso8601 Minor stylistical changes 2003-10-10 19:19 azummo - Palm/Datebook.pm: Fixed alarm documentation (Christophe Beauregard) 2003-10-10 07:01 azummo - Palm/PDB.pm: Implemented remove_Record() method. Fixed dirty flags handling. (Christophe Beauregard) 2003-10-10 06:51 azummo - Palm/PDB.pm: Added is_Dirty method (Christophe Beauregard). 2003-09-16 18:59 azummo - MANIFEST, README: Updated in preparation for the new release. 2003-09-16 18:56 azummo - Makefile.PL: Bumped version number. 2003-09-16 18:53 azummo - Palm/ZirePhoto.pm: Removed unused methods. The superclass will take care. 2003-08-03 13:06 arensb - README, Palm/PDB.pm: Added missing section header in POD. Patch contributed by Kurt Starsinic 2003-06-26 15:21 azummo - Palm/Mail.pm: Some headers were left undefined (Christophe Beauregard) 2003-06-24 10:28 azummo - Palm/ZirePhoto.pm: Added. 2002-12-17 19:09 azummo - MANIFEST: Added DateTime.pm to manifest. 2002-11-07 10:50 arensb - Makefile.PL: Updated version number. 2002-11-07 09:27 arensb - Palm/StdAppInfo.pm: (API) Now supports databases where the last byte of the AppInfo block is data instead of padding. Backwards-compatible. 2002-11-07 09:11 arensb - Palm/: Address.pm, Datebook.pm, Mail.pm, Memo.pm, ToDo.pm: Rearranged @ISA, so that it'll get the right &ParseAppInfoBlock. 2002-11-03 11:43 azummo - Palm/: Address.pm, DateTime.pm, Datebook.pm, Mail.pm, Memo.pm, PDB.pm, PQA.pm, Raw.pm, StdAppInfo.pm, ToDo.pm: Changed $VERSION parser. 2002-09-03 13:48 azummo - Palm/Address.pm: Patch from Brian Johnson (it just adds an else to the if statement to nullify non-existing entities). 2002-06-22 09:16 azummo - Palm/PDB.pm: now now takes an optional hash with default values. 2002-06-16 09:37 azummo - Palm/PDB.pm: Added some compatibility code. Reflected (part of) changes in the POD. 2002-06-16 09:26 azummo - Palm/PDB.pm: Make some more use of the new attribute names. 2002-06-16 08:34 azummo - Palm/PDB.pm: Added "official" names to record attributes. 2002-06-16 08:19 azummo - Palm/PDB.pm: Corrected an attribute flag (open) Added new attributes using "official" names 2002-05-09 11:08 arensb - Palm/Address.pm: Again, more sanity-checking and a little less code duplication. 2002-05-09 10:33 arensb - Palm/Address.pm: More sanity checks, and a somewhat more elegant way of doing things (iterate over field names, rather than duplicating code a bunch of times). 2002-05-09 10:24 arensb - Palm/StdAppInfo.pm: (bug fix) Used to do some sanity-checking, then ignored it. We now pay attention to our own sanity checks. 2002-04-09 20:59 arensb - README: Added Keni as a contributor. 2002-04-09 20:58 arensb - util/pdbdump: Applied Keni's patch: array-handling for parsed records (e.g., Datebook exceptions). 2002-04-05 14:59 azummo - Palm/DateTime.pm: Hopefully fixed mktime() invocation. (?) 2002-03-23 08:38 arensb - Palm/Mail.pm: Added extra sanity checks. 2002-03-12 15:23 azummo - Palm/DateTime.pm: Added Palm/DateTime.pm 2002-02-15 09:40 arensb - Palm/PDB.pm: (bug fix) Strip everything after the first NUL, not just trailing NULs. Patch submitted by Don Park 2002-02-08 09:20 arensb - Makefile.PL: Bumped up version number. 2002-02-08 08:56 arensb - MANIFEST: Added add-memo to distribution. 2002-02-08 08:55 arensb - util/add-memo: Added first draft of add-memo, to add a memo to an existing MemoDB.pdb. 2002-02-01 09:09 arensb - Palm/PDB.pm: Comment used to refer to a doc file in ColdSync that no longer exists. Fixed. 2002-01-26 17:25 arensb - Palm/Address.pm, Palm/Datebook.pm, Palm/Mail.pm, Palm/Memo.pm, Palm/PDB.pm, Palm/PQA.pm, Palm/Raw.pm, Palm/StdAppInfo.pm, Palm/ToDo.pm, util/pdbdump: CPAN-friendly $VERSION. 2002-01-26 17:22 arensb - TODO: Added some items. 2002-01-26 17:22 arensb - Makefile.PL: Rewrote version number in CPAN-friendly format. 2001-06-05 09:04 arensb - Palm/StdAppInfo.pm: Made addCategory, deleteCategory, renameCategory behave a bit more like the Palm, even when it's brain-damaged. 2001-06-05 08:52 arensb - TODO: Removed an item. 2001-06-02 15:17 arensb - Palm/: Datebook.pm, StdAppInfo.pm: Fixed typo in POD. 2001-04-04 23:54 arensb - Palm/StdAppInfo.pm: Fixed typo. 2001-03-30 01:23 arensb - Palm/Datebook.pm: Clarified whether date numbers start at 0 or 1. (bug fix): Fixed year conversion. (bug fix): Fixed use of undefined value. 2001-02-24 18:35 arensb - Palm/PDB.pm: In &new, initialize 'baktime' to -$EPOCH_1904, that being the Palm's epoch. 2001-02-24 17:59 arensb - FAQ: Added pointers to other sources of information about HotSync .dat files. 2001-02-24 11:49 arensb - Palm/Datebook.pm: Clarified documentation. 2001-02-20 06:17 arensb - MANIFEST: Added FAQ to distribution. 2001-02-20 06:17 arensb - Makefile.PL: Incremented version number. 2001-02-20 06:17 arensb - FAQ: (Added). 2001-02-20 06:12 arensb - README: Added contributor. 2001-02-20 06:12 arensb - util/pdbdump: (bug fix): the two NULs are optional. Fixed typo. 2001-02-20 06:11 arensb - Palm/StdAppInfo.pm: Added a "to do" comment. 2000-11-09 10:32 arensb - Palm/PDB.pm: Applied John-David Smith's patch: add the "archive" attribute. Better check for non-NULLness of AppInfo block. 2000-09-25 01:06 arensb - util/pdbdump: Added "launchable" attribute, for PQAs. Print database attributes more clearly. 2000-09-25 01:05 arensb - Palm/PQA.pm: First draft of PQA parser. 2000-09-25 01:05 arensb - Palm/PDB.pm: Added "launchable" attribute, for PQAs. 2000-09-24 12:37 arensb - util/pdbdump: Now handles resource databases as well as record databases. 2000-09-24 12:25 arensb - Palm/: Address.pm, Datebook.pm, Mail.pm, Memo.pm, PDB.pm, Raw.pm, StdAppInfo.pm, ToDo.pm: $VERSION is now a floating-point number, for comparison. 2000-09-24 12:24 arensb - TODO: Added an item. 2000-09-20 10:16 arensb - Palm/StdAppInfo.pm: Removed a "to do" comment. 2000-09-16 19:58 arensb - Makefile.PL: Bumped up patchlevel number. 2000-09-16 19:58 arensb - Palm/PDB.pm: (bug fix): The two useless NULs are allowed, but not mandated, by the spec. By assuming that they will always be there, this module failed to parse some well-formed PDBs. 2000-09-16 19:57 arensb - util/pdbdump: Oops! Forgot to fix resources. Minor cleaning. 2000-09-16 19:53 arensb - util/pdbdump: (bug fix): The two useless NULs are allowed, but not mandated, by the spec. By assuming that they will always be there, 'pdbdump' failed to parse some well-formed PDBs. 2000-09-09 00:52 arensb - Makefile.PL: Bumped up version number. 2000-09-09 00:50 arensb - Palm/StdAppInfo.pm: Added $error variable. (bug fix): A mis-written test would cause &pack_StdAppInfo to omit unnamed categories. Hence, the category list had fewer than 16 categories, when written. Fixed typo. (feature): Added &addCategory, &deleteCategory, &renameCategory. Removed BUGS section. 2000-09-08 22:48 arensb - Palm/StdAppInfo.pm: Stop Perl from complaining if there are unnamed categories. 2000-09-08 22:47 arensb - README: Added author. 2000-08-28 23:20 arensb - Makefile.PL: Bumped up the version number. 2000-08-28 23:19 arensb - Palm/StdAppInfo.pm: Changed API: the categories are new arranged as a 16-element array of category structs, the way they logically belong, rather than as disparate arrays, the way they're represented in the file. Added a lot to the POD. 2000-08-28 23:16 arensb - TODO: Removed an item. 2000-08-28 23:16 arensb - TODO: Added an item. 2000-08-24 00:57 arensb - Palm/PDB.pm: Clarified pod somewhat. 2000-08-24 00:29 arensb - util/pdbdump: (feature): Expands arrays of hash references recursively. 2000-08-13 18:08 arensb - Palm/Datebook.pm: Incorporated changes suggested by John Jannotti , to avoid warnings under Perl 5.6, when various fields are undefined. 2000-08-13 17:59 arensb - Palm/: Address.pm, Datebook.pm, Mail.pm, Memo.pm, ToDo.pm: Updated for new &parse_StdAppInfo behavior. 2000-08-13 17:59 arensb - Palm/StdAppInfo.pm: (bug fix): &parse_StdAppInfo now puts the non-category part of the AppInfo block in $appinfo->{other}. This is so that a script that reads a random .pdb file as a StdAppInfo (and nothing else) can copy it without loss of data. &pack_StdAppInfo uses $appinfo->{other}. Clarified documentation somewhat. 2000-08-04 00:12 arensb - Palm/PDB.pm: Fixed expression that made 'perl5.6 -w' print a warning. 2000-08-01 23:20 arensb - Makefile.PL: Bumped up version number. 2000-08-01 23:19 arensb - util/pdbdump: (bug fix): Read files in binary mode under Windows, MS-DOS, and other OSes that make that distinction. 2000-08-01 23:19 arensb - Palm/PDB.pm: (bug fix): Read and write files in binary mode under Windows, MS-DOS, and other OSes that make that distinction. 2000-08-01 23:17 arensb - Palm/Datebook.pm: Delete raw data field at the end of &ParseRecord. 2000-08-01 23:16 arensb - TODO: Added, removed some items. 2000-07-20 00:17 arensb - Makefile.PL: Bumped up version number. 2000-07-20 00:17 arensb - Palm/Datebook.pm: (Bug fix): Test for undefined record fields, to avoid warnings with databases built from scratch. Patch supplied by . 2000-07-19 00:00 arensb - Makefile.PL: Bumped up version number. 2000-07-19 00:00 arensb - TODO: Removed an item. 2000-07-18 23:58 arensb - Palm/: Address.pm, Datebook.pm, Mail.pm, Memo.pm, PDB.pm, ToDo.pm: Clarified the documentation for &new_Record. 2000-07-18 23:57 arensb - TODO: Added an item. 2000-07-08 20:25 arensb - Palm/PDB.pm: PDB::new now initializes more fields. PDB::Write prints a warning if writing a zero-length record. PDB::new_Resource: type now defaults to all NULs (instead of four spaces). 2000-07-08 20:11 arensb - Palm/Datebook.pm: Changed a comment. 2000-06-30 11:41 arensb - Makefile.PL: Bumped up version number. 2000-06-30 11:41 arensb - TODO: Added an item. 2000-06-30 11:41 arensb - Palm/Datebook.pm: Made AppInfo block initialization the same as other modules, even though Datebook doesn't really use categories and such. 2000-06-30 11:40 arensb - Palm/StdAppInfo.pm: (bug fix): Use of anonymous array instead of a real array caused first category (and first category ID) to be a reference rather than a "real" scalar. 2000-05-23 02:56 arensb - Makefile.PL: Incremented patchlevel number. 2000-05-23 02:55 arensb - Palm/: Address.pm, Memo.pm: (bug fix): Don't run StdAppInfo::import(). This prevents StdAppInfo from registering itself as the default handler in generic tools. 2000-05-13 16:30 arensb - Makefile.PL: Bumped up version number. 2000-05-13 16:29 arensb - README: Added contributor. 2000-05-13 16:29 arensb - Palm/Mail.pm: Fixed inconsistency in record member names ("replyTo" was sometimes "reply_to", and "sentTo" was sometimes "sent_to"). Patch supplied by Sumant S.R. Oemrawsingh 2000-05-13 01:16 arensb - Makefile.PL: Incremented patch level. Added "pdbdump" to the distribution. 2000-05-13 01:15 arensb - MANIFEST: Ship "pdbdump" instead of "dumpdb". 2000-05-13 01:15 arensb - util/dumpdb: Some obsolete refinements. 2000-05-13 01:14 arensb - Palm/StdAppInfo.pm: Added an import() function, so you can say that a function is a Palm::StdAppInfo. 2000-05-13 01:12 arensb - Palm/Mail.pm: (bug fix): Palm::Mail::new_Record() didn't return a value. Don't import StdAppInfo, since don't want new PDBs to default to StdAppInfo. 2000-05-08 05:48 arensb - util/pdbdump: Rewritten from scratch. This is basically just Palm/PDB.pm with trace statements. 2000-05-08 05:48 arensb - util/pdbdump: intermediate 2000-05-07 02:33 arensb - Palm/: StdAppInfo.pm, ToDo.pm: Removed unnecessary quoting in class members. 2000-05-07 02:33 arensb - Palm/Raw.pm: Removed unnecessary quoting in class members. Added `use strict'. Rearranged some variables at the top. 2000-05-07 02:30 arensb - Palm/: Datebook.pm, Mail.pm, Memo.pm, PDB.pm: Removed unnecessary quoting in class members. 2000-05-06 17:48 arensb - Palm/Address.pm: Removed unnecessary quoting in class members. 2000-05-06 17:20 arensb - Palm/ToDo.pm: Converted to use StdAppInfo. Fixed man page section in "see also" section. 2000-05-06 17:19 arensb - Palm/StdAppInfo.pm: Added a "to do" comment. 2000-05-06 17:18 arensb - Palm/: PDB.pm, Raw.pm: Fixed man page sections for "see also" section. 2000-04-29 17:53 arensb - Makefile.PL: Bumped up patch level. 2000-04-29 17:49 arensb - README: Added Robert Norris's patch for empty PDBs. 2000-04-29 16:52 arensb - Palm/PDB.pm: Applied Robert Norris 's patch: _load_appinfo_block used to die if the database contained no records. 2000-04-24 06:02 arensb - util/pdbdump: (added) This will eventually become the successor to dumpdb. 2000-04-24 06:01 arensb - util/dumpdb: More AppInfo block processing. 2000-04-24 06:01 arensb - Palm/StdAppInfo.pm: (added) Class for dealing with the standard part of AppInfo blocks (category support). 2000-04-24 06:00 arensb - Palm/PDB.pm: Uses `use strict'. Changed the way $VERSION is generated from RCS tag. Fixed the POD a bit. 2000-04-24 05:59 arensb - Palm/: Mail.pm, Memo.pm: Use StdAppInfo. 2000-04-24 05:56 arensb - Palm/Address.pm: Fixed manual section numbers. 2000-04-24 05:56 arensb - Palm/: Address.pm, Datebook.pm: Use StdAppInfo. 2000-04-24 05:55 arensb - TODO: Removed some stuff. 2000-04-24 05:55 arensb - Makefile.PL: Incremented version number. 2000-04-24 05:54 arensb - MANIFEST: Added "TODO", "StdAppInfo.pm" 2000-04-20 01:42 arensb - Palm/Mail.pm: Forgot to mention the subject in the documentation. 2000-02-01 23:45 arensb - TODO: (added): Things that need to be done. 2000-02-01 23:45 arensb - README: (added): README file. 2000-02-01 23:40 arensb - Makefile.PL: Incremented version number. 2000-02-01 23:21 arensb - Palm/Raw.pm: Rearranged the POD. Inherit &new, &new_Record methods. 2000-02-01 23:19 arensb - Palm/: Datebook.pm, Mail.pm, Memo.pm, ToDo.pm: Rearranged the POD. Added &new, &new_Record methods. 2000-02-01 23:18 arensb - Palm/Address.pm: Added placeholder for $pdb->{appinfo}{lastUniqueID}. 2000-02-01 07:31 arensb - Palm/: Raw.pm, ToDo.pm: Added $VERSION variable, per CPAN. 2000-02-01 07:31 arensb - Palm/PDB.pm: Renamed &deleteRecord to &delete_Record, for consistency. &append_Record, &append_Resource, &delete_Record update PDB's mtime. 2000-02-01 07:20 arensb - Palm/: Mail.pm, Memo.pm: Added $VERSION variable, per CPAN. 2000-02-01 07:19 arensb - Palm/Address.pm: Added $VERSION to all .pm files, per CPAN. Moved pod documentation to be adjacent to the code, instead of at the end. Fixed &new so there are always 16 categories, one of which is named "Unfiled" with code 0. 2000-01-23 04:18 arensb - Palm/PDB.pm: The various _load_*() functions are no longer methods, since they shouldn't be overridden anyway. Added documentation for new_Record(), append_Record(), new_Resource(), append_resource(), findRecordByID(), deleteRecord(). 2000-01-23 01:33 arensb - util/dumpdb: Bug fix: deal with PDBs without records, and PRCs without resources. Memo: Dump() now prints the AppInfo and sort blocks, if they exist. Address: Dump() now prints the field labels in the AppInfo block. Address: print the record attributes. 2000-01-23 01:28 arensb - Palm/PDB.pm: Updated copyright. Fixed function cross-references in the documentation. new() method now initializes the common fields. Fiddled with quotes in the documentation some more. Write() method now supplies the two NULs if they're missing. Added methods: new_Record(), append_Record(), new_Resource(), append_Resource(), findRecordByID(), deleteRecord(). 2000-01-23 01:24 arensb - Palm/Address.pm: Added new() method, to specifically create a new Address PDB. Added new_Record() method, to create a new Address record. Bug fix: PackAppInfoBlock() only packed whichever categories were defined. It now makes sure that it packs 16 categories. 2000-01-23 01:20 arensb - Makefile.PL: Incremented version. 1999-12-05 23:11 arensb - Palm/Address.pm: Fixed documentation to reflect reality. 1999-11-18 13:20 arensb - Palm/PDB.pm: Added magic $VERSION, to make CPAN happy. 1999-11-18 03:29 arensb - util/dumpdb: Took out Bitmaps and DopeWars, since those aren't part of the distribution (yet?). 1999-11-18 03:28 arensb - MANIFEST: Added README. 1999-11-18 03:24 arensb - Palm/Raw.pm: Clarified the use of "use Palm::Raw;" vs. "use Palm::Raw();" in the documentation. 1999-11-18 01:20 arensb - Palm/: Address.pm, Datebook.pm, Mail.pm, Memo.pm, PDB.pm, Raw.pm, ToDo.pm: Changed Palm::PDB:: to Palm:: where required. 1999-11-18 01:19 arensb - Makefile.PL: Changed distribution name to p5-Palm, for clarity. Explicitly set installation method. 1999-11-18 00:51 arensb - Makefile.PL: Fixed NAME and VERSION. 1999-11-18 00:51 arensb - MANIFEST: Removed Palm/Makefile.PL 1999-11-18 00:48 arensb - Palm/Makefile.PL: Deleted. It's not necessary. 1999-11-18 00:26 arensb - MANIFEST: Fixed after directory shuffle. 1999-11-18 00:24 arensb - test.pl: Generated by MakeMaker. Not used. 1999-11-18 00:23 arensb - util/dumpdb: Added RCS comment. Updated "use" statements to reflect the fact that the Palm stuff is in Palm::, not Palm::PDB::. 1999-11-18 00:21 arensb - util/copydb: Added RCS header. Took out the "use lib" line, for now. Changed "use" statements: the Palm stuff is no longer Palm::PDB:, but rather Palm::. 1999-11-18 00:17 arensb - util/dumpdb: Test utility to dump the contents of a PDB. 1999-11-18 00:17 arensb - util/copydb: Test utility to copy a PDB. 1999-11-18 00:16 arensb - Palm/ToDo.pm: Module for dealing with ToDo databases. 1999-11-18 00:16 arensb - Palm/Raw.pm: Module for dealing with "Raw" databases. 1999-11-18 00:16 arensb - Palm/Memo.pm: Module for dealing with Memo databases. 1999-11-18 00:16 arensb - Palm/Mail.pm: Module for dealing with Mail databases. 1999-11-18 00:16 arensb - Palm/Datebook.pm: Module for dealing with DateBook databases. 1999-11-18 00:15 arensb - Palm/Address.pm: Module for dealing with AddressBook databases. 1999-11-18 00:15 arensb - Palm/PDB.pm: Base module for dealing with PDBs. 1999-11-18 00:14 arensb - Palm/Makefile.PL: MakeMaker-generated Makefile.PL. 1999-11-18 00:10 arensb - Makefile.PL: MakeMaker-generated Makefile.PL. 1999-11-18 00:10 arensb - MANIFEST: First draft of manifest. Palm-1.400/README0000644000175000017500000000356412501047366011407 0ustar cjmcjmp5-Palm version 1.400, released March 14, 2015 This is p5-Palm, a set of Perl 5 modules for reading, manipulating, and writing the .pdb and .prc database files used by Palm OS devices such as the PalmPilot and its successors. You'll also need the Palm::PDB and Palm::Raw modules. They used to be distributed as part of p5-Palm, but were split out into their own distribution because they are also useful for manipulating the Mobipocket e-book format, which is also used for Amazon Kindle books. The modules remaining in p5-Palm are generally useful only if you're dealing with files from actual Palm OS devices. INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install CONTRIBUTING The source is in GitHub: https://github.com/madsen/p5-Palm If you have a change, fork the repo, make your patch, and send me a pull request. Don't be scared; it's easy! AUTHORS AND CONTRIBUTORS Andrew Arensburger : principal perpetrator Robert Norris : patch for empty PDBs Sumant S.R. Oemrawsingh : patch for inconsistent record fields in Mail.pm John Jannotti : patches to make Perl 5.6 shut up. John-David Smith : added "archive" attribute. Kenneth Lorber : fixed "pdbdump" to handle arrays in parsed records (e.g., Datebook exceptions). Alessandro Zummo : DateTime.pm, ZirePhoto.pm Kurt Starsinic : documentation patch. Seb Wills : documentation. brian d foy Christopher J. Madsen COPYRIGHT AND LICENSE This software is copyright (c) 2003 by Andrew Arensburger & Alessandro Zummo. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Palm-1.400/TODO0000644000175000017500000000120612501047366011206 0ustar cjmcjm- POD for add-memo. - Add support for general-purpose parsers: read the database type (PDB or PRC), creator, and type, and look them up in a database. This should return the name of a Perl module to use to parse that particular database type. The best way of doing this appears to be sub load_module { eval "require $_[0]"; die if $@; $_[0]->import($_[1..$#_]); } See "Perl Cookbook," 12.3. - Add PRC support. Unlike PDBs, the thing to do here is to have registered handlers for various resource types. - Add PQA parser. - Make $VERSION be a floating-point number. See mail from Andreas J. Koenig Palm-1.400/FAQ0000644000175000017500000000122312501047366011047 0ustar cjmcjmQ: I'm trying to read the "datebook.dat", "address.dat", "todo.dat" or "memopad.dat" files created by the HotSync desktop tool, but it doesn't work. A: Those files aren't PDB files, so these modules can't read them. It looks as if the HotSync conduits don't store a backup PDB file of the database. In any case, I don't know what format those files are in. http://web.archive.org/web/20050718081526/http://www.geocities.com/Heartland/Acres/3216/palmrecs.htm appears to have information about the file formats used by HotSync. The Pilot:: Perl package by John Wiegley might also prove useful. See: https://metacpan.org/release/Pilot