PyukiWiki CVS Commit
pyuki****@lists*****
2012年 3月 18日 (日) 02:14:51 JST
Index: PyukiWiki-Nekyo/019/lib/Yuki/DiffText.pm diff -u /dev/null PyukiWiki-Nekyo/019/lib/Yuki/DiffText.pm:1.1 --- /dev/null Sun Mar 18 02:14:51 2012 +++ PyukiWiki-Nekyo/019/lib/Yuki/DiffText.pm Sun Mar 18 02:14:51 2012 @@ -0,0 +1,90 @@ +package Yuki::DiffText; +use strict; +use Algorithm::Diff qw(traverse_sequences); +use vars qw($VERSION @EXPORT_OK @ISA); +use vars qw($diff_text $diff_msgrefA $diff_msgrefB @diff_deleted @diff_added); +require Exporter; + @ ISA = qw(Exporter); + @ EXPORT_OK = qw(difftext); +$VERSION = '0.1'; + +=head1 NAME + +Yuki::DiffText - A wrapper of Algorithm::Diff for YukiWiki. + +=head1 SYNOPSIS + + use strict; + use Yuki::DiffText qw(difftext); + + my @array1 = ( "Alice", "Bobby", "Chris", ); + my @array2 = ( "Alice", "Chris", "Diana", ); + my $difftext = difftext(\@array1, \@array2); + print $difftext; + + # Result: + # =Alice + # -Bobby + # =Chris + # +Diana + +=head1 SEE ALSO + +=over 4 + +=item L<Algorithm::Diff> + +=back + +=head1 AUTHOR + +Hiroshi Yuki <hyuki****@hyuki*****> http://www.hyuki.com/ + +=head1 LICENSE + +Copyright (C) 2002 by Hiroshi Yuki. + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=cut + +sub difftext { + ($diff_msgrefA, $diff_msgrefB) = @_; + undef $diff_text; + undef @diff_deleted; + undef @diff_added; + traverse_sequences( + $diff_msgrefA, $diff_msgrefB, + { + MATCH => \&df_match, + DISCARD_A => \&df_delete, + DISCARD_B => \&df_add, + } + ); + &diff_flush; + return $diff_text; +} + +sub diff_flush { + $diff_text .= join('', map { "-$_\n" } splice(@diff_deleted)); + $diff_text .= join('', map { "+$_\n" } splice(@diff_added)); +} + +sub df_match { + my ($a, $b) = @_; + &diff_flush; + $diff_text .= "=$diff_msgrefA->[$a]\n"; +} + +sub df_delete { + my ($a, $b) = @_; + push(@diff_deleted, $diff_msgrefA->[$a]); +} + +sub df_add { + my ($a, $b) = @_; + push(@diff_added, $diff_msgrefB->[$b]); +} + +1; Index: PyukiWiki-Nekyo/019/lib/Yuki/YukiWikiDB.pm diff -u /dev/null PyukiWiki-Nekyo/019/lib/Yuki/YukiWikiDB.pm:1.1 --- /dev/null Sun Mar 18 02:14:51 2012 +++ PyukiWiki-Nekyo/019/lib/Yuki/YukiWikiDB.pm Sun Mar 18 02:14:51 2012 @@ -0,0 +1,121 @@ +package Yuki::YukiWikiDB; + +use strict; +use Fcntl ':flock'; + +# Constructor +sub new { + return shift->TIEHASH(@_); +} + +# tying +sub TIEHASH { + my ($class, $dbname) = @_; + my $self = { + dir => $dbname, + keys => [], + }; + if (not -d $self->{dir}) { + if (!mkdir($self->{dir}, 0777)) { + die "mkdir(" . $self->{dir} . ") fail"; + } + } + return bless($self, $class); +} + +# Store +sub STORE { + my ($self, $key, $value) = @_; + my $filename = &make_filename($self, $key); + &lock_store($filename, $value); + return $value; +} + +# Fetch +sub FETCH { + my ($self, $key) = @_; + my $filename = &make_filename($self, $key); + my $value = &lock_fetch($filename); + return $value; +} + +# Exists +sub EXISTS { + my ($self, $key) = @_; + my $filename = &make_filename($self, $key); + return -e($filename); +} + +# Delete +sub DELETE { + my ($self, $key) = @_; + my $filename = &make_filename($self, $key); + unlink $filename; + # return delete $self->{$key}; +} + +sub FIRSTKEY { + my ($self) = @_; + opendir(DIR, $self->{dir}) or die $self->{dir}; + @{$self->{keys}} = grep /\.txt$/, readdir(DIR); + foreach my $name (@{$self->{keys}}) { + $name =~ s/\.txt$//; + $name =~ s/[0-9A-F][0-9A-F]/pack("C", hex($&))/eg; + } + closedir(DIR); + return shift @{$self->{keys}}; +} + +sub NEXTKEY { + my ($self) = @_; + return shift @{$self->{keys}}; +} + +sub make_filename { + my ($self, $key) = @_; + my $enkey = ''; + foreach my $ch (split(//, $key)) { + $enkey .= sprintf("%02X", ord($ch)); + } + return $self->{dir} . "/$enkey.txt"; +} + +sub lock_store { + my ($filename, $value) = @_; + open(FILE, "+< $filename") or open(FILE, "> $filename") or die "$filename cannot be created"; + eval("flock(FILE, LOCK_EX)"); + if ($@) { + # Your platform does not support flock. + # Implement another EXCLUSIVE LOCK here. + } + truncate(FILE, 0); + # binmode(FILE); + print FILE $value; + eval("flock(FILE, LOCK_UN)"); + if ($@) { + # Your platform does not support flock. + # Implement another UNLOCK here. + } + close(FILE); +} + +sub lock_fetch { + my ($filename) = @_; + open(FILE, "$filename") or return(undef); + eval("flock(FILE, LOCK_SH)"); + if ($@) { + # Your platform does not support flock. + # Implement another SHARED LOCK here. + } + local $/; + my $value = <FILE>; + eval("flock(FILE, LOCK_UN)"); + if ($@) { + # Your platform does not support flock. + # Implement another UNLOCK here. + } + close(FILE); + return $value; +} + +1;