package JFileUTF8; use Common; @ISA = qw(Common); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Encode qw/encode decode from_to/; use utf8; #use open IN => ":utf8"; # 入力をUTF8とする #use open OUT => ":utf8"; # 出力をUTF8とする #use open IO => ":utf8"; # 入出力をUTF8とする(上の2つを同時に行う) #use open ":utf8"; # 上と同じ use Jcode; use File::Path; use File::Basename; use File::Find; use Symbol qw(gensym); use Utils; use Deps; #=============================================== # デバッグ関係変数 #=============================================== my $Debug = 0; #=============================================== # 文字コード関係変数 #=============================================== # sjis, euc, jis, noconv, utf8 my $FileSystemCharCode = Deps::FileSystemCharCode(); my $PerlCharCode = Deps::PerlCharCode(); my $MySQLCharCode = Deps::MySQLCharCode(); my $WebCharCode = Deps::WebCharCode(); my $WebCharSet = Deps::WebCharSet(); #=============================================== # スクリプト大域変数 #=============================================== my $LF = Deps::LF(); my $DirectorySeparator = Deps::DirectorySeparator(); my $OS = Deps::OS(); sub new { my ($module, $path, $mode, $charcode, $IsPrintOut) = @_; my $this = {}; bless $this; if(defined $path and defined $mode) { return undef unless($this->Open($path, $mode, $charcode, $IsPrintOut)); } $this->SetSuppressCharCodeConversion(0); return $this; } sub DESTROY { my $this = shift; $this->Close(); } sub SetSuppressCharCodeConversion { my ($this,$f)=@_; return $this->{SuppressCharCodeConversion} = $f; } sub SuppressCharCodeConversion { return shift->{SuppressCharCodeConversion}; } sub SuppressIOBuffering { my ($this, $h) = @_; $h = $this->HANDLE() if(!defined $h); my $oldfh = select($h); $|=1; select($oldfh); } sub SetSourceCharCode { my ($this, $c) = @_; return $this->{SoruceCharCode} = $c; } sub SourceCharCode { return shift->{SoruceCharCode}; } sub read { my ($this, $s, $len, $offset) = @_; my $ret = read($this->HANDLE(), $s, $len, $offset); $_[1] = $s; return $ret; } sub sysread { my ($this, $s, $len, $offset) = @_; my $ret = sysread($this->HANDLE(), $s, $len, $offset); $_[1] = $s; return $ret; } sub syswrite { my ($this, $s, $len, $offset) = @_; return syswrite($this->HANDLE(), $s, $len, $offset); } sub stat { my ($this) = @_; return stat($this->HANDLE()); } sub lstat { my ($this) = @_; return lstat($this->HANDLE()); } sub fileno { my ($this) = @_; return fileno($this->HANDLE()); } sub flock { my ($this, $operation) = @_; return flock($this->HANDLE(), $operation); } sub getc { my ($this) = @_; return getc($this->HANDLE()); } sub truncate { my ($this, $length) = @_; return truncate($this->HANDLE(), $length); } sub WriteFile { my ($this, $filename, $content, $charcode, $mode) = @_; Jcode::convert(\$content, $charcode) if($content and $charcode and !$this->SuppressCharCodeConversion()); open(JFILEFILE, ">$filename") or return 0; binmode(JFILEFILE) if(defined $mode and $mode =~ /b/i); print JFILEFILE $content; close(JFILEFILE); return 1; } sub ReadFile { my ($this, $filename, $charcode, $mode) = @_; open(JFILEFILE, "<$filename") or return 0; binmode(JFILEFILE) if(defined $mode and $mode =~ /b/i); my $str = do { local $/; }; close(JFILEFILE); Jcode::convert(\$str, $charcode) if($str and $charcode and !$this->SuppressCharCodeConversion()); return $str; } sub ReadFileToLines { my ($this, $filename, $charcode, $mode) = @_; open(JFILEFILE, "<$filename") or return 0; binmode(JFILEFILE) if(defined $mode and $mode =~ /b/i); my @lines = ; close(JFILEFILE); if($charcode and !$this->SuppressCharCodeConversion()) { for(my $i = 0 ; $i < @lines ; $i++) { Jcode::convert(\$lines[$i], $charcode) if($lines[$i]); } } return @lines; } sub Open { my ($this, $filename, $mode, $charcode, $IsPrintOut) = @_; $IsPrintOut = 1 if(!defined $IsPrintOut); if($this->{inHANDLE} or $this->{outHANDLE}) { $this->Close(); } $mode = 'r' if(!defined $mode or $mode eq ''); # $charcode = 'noconv' unless($charcode); $filename = 'con' if($filename eq ''); Jcode::convert(\$filename, Deps::OSCharCode()); my $ret = 1; if($filename eq 'con') { $this->{inHANDLE} = STDIN; $this->{outHANDLE} = STDOUT; } else { if($mode =~ /w/i or $mode =~ /a/i) { $this->{outHANDLE} = gensym() if($mode =~ /w/i); $filename = ">$filename" if($mode =~ /w/i); $filename = ">>$filename" if($mode =~ /a/i); $ret = open($this->{'outHANDLE'}, $filename); unless($ret) { $filename =~ s/^[\<\>]+//; print "Error in JFile::Open: Can not write to [$filename].\n" if($IsPrintOut); $this->Initialize(); return $ret; } binmode($this->{outHANDLE}) if($mode =~ /b/i); } if($mode =~ /r/i) { $this->{'inHANDLE'} = gensym() if($mode =~ /r/i); $filename = "<$filename"; $ret = open($this->{inHANDLE}, $filename); unless($ret) { $filename =~ s/^[\<\>]+//; print "Error in JFile::Open: Can not read [$filename].\n" if($IsPrintOut); $this->Initialize(); return $ret; } binmode($this->{inHANDLE}) if($mode =~ /b/i); } } $filename =~ s/[\<\>]//g; $this->{FileName} = $filename; $this->{Mode} = $mode; $this->{CharCode} = $charcode; return $ret; } sub Close { my ($this) = @_; if($this->{'FileName'} and $this->{'FileName'} eq 'con') { $this->Initialize(); return ''; } close($this->{'inHANDLE'}) if($this->{'inHANDLE'}); close($this->{'outHANDLE'}) if($this->{'outHANDLE'}); $this->Initialize(); return ''; } sub eof { my $this = shift; return eof($this->{'inHANDLE'}) if($this->{'inHANDLE'}); return eof($this->{'outHANDLE'}) if($this->{'outHANDLE'}); return 1; } sub ReadLine { my ($this, $DelSpace, $code, $UseEncodeModule) = @_; my $fh = $this->{'inHANDLE'}; return undef unless($fh); my $line = <$fh>; return undef unless(defined $line); #print "line0: [$line]"; Utils::DelSpace($line) if($DelSpace); #$this->{CharCode} = 'utf-8' if($this->{CharCode} eq ''); #print "C=[$this->{CharCode}]\n"; if($code and $UseEncodeModule) { $line = decode($code, $line); } else { # Jcode::convert(\$line, $this->{CharCode}) if($line and $this->{CharCode} and !$this->SuppressCharCodeConversion()); Utils::convert(\$line, $this->{CharCode}) if($line and $this->{CharCode} and !$this->SuppressCharCodeConversion()); } return $line; } sub PreReadLine { my ($this) = @_; my $pos = $this->tell(); my $line = $this->ReadLine(); $this->seek($pos, 0); return $line; } sub Write { my ($this, $str) = @_; Jcode::convert(\$str, $this->{'CharCode'}) if($str and $this->{'CharCode'} and !$this->SuppressCharCodeConversion()); my $fh = $this->{'outHANDLE'}; return undef unless($fh); print $fh $str; return $str; } sub print { my ($this, @args) = @_; $this->{CharCode} = 'utf8' if(defined $this->{CharCode} and $this->{CharCode} =~ /utf-8/i); for(my $i = 0 ; $i < @args ; $i++) { next if($args[$i] eq ''); if($this->{CharCode} and $this->{CharCode} ne 'ascii') { if($this->{SourceCharCode} and $this->{SourceCharCode} ne 'ascii') { if($this->{SourceCharCode} ne $this->{CharCode} and !$this->SuppressCharCodeConversion()) { Jcode::convert(\$args[$i], $this->{CharCode}, $this->{SourceCharCode}); } } else { if(!$this->SuppressCharCodeConversion()) { Jcode::convert(\$args[$i], $this->{CharCode}); } } } #print "arg$i: $args[$i]"; } my $fh = $this->{outHANDLE}; print $fh @args; return @args; } sub printf { my ($this, @args) = @_; for(my $i = 0 ; $i < @args ; $i++) { Jcode::convert(\$args[$i], $this->{'CharCode'}) if($args[$i] and $this->{'CharCode'} and !$this->SuppressCharCodeConversion()); } my $fh = $this->{'outHANDLE'}; printf $fh @args; return @args; } sub SetAuxOutput { my ($this, $aux) = @_; $this->{AuxOutput} = $aux; } sub mprint { my ($this, @args) = @_; if(!defined $this->{AuxOutput}) { print(@args); } else { $this->{AuxOutput}->print(@args); } $this->print(@args); } sub mprintf { my ($this, @args) = @_; if(defined $this->{AuxOutput}) { printf(@args); } else { $this->{AuxOutput}->printf(@args); } $this->printf(@args); } sub SkipTo { my ($this, $pattern, $origin) = @_; # $origin = 0 unless($origin); $this->seek($origin, 0) if(defined $origin and $origin ne ''); Jcode::convert(\$pattern, $PerlCharCode) if($pattern and $PerlCharCode and !$this->SuppressCharCodeConversion()); my $line; my $IsFound = 0; while($line = $this->ReadLine()) { last if($this->eof()); Jcode::convert(\$line, $PerlCharCode) if($line and $PerlCharCode and !$this->SuppressCharCodeConversion()); if($line =~ /$pattern/i) { $IsFound = 1; last; } } return undef unless($IsFound); return $line; } sub tell { my ($this) = @_; return tell($this->{'inHANDLE'}) if($this->{'inHANDLE'} ne ''); return tell($this->{'outHANDLE'}) if($this->{'outHANDLE'} ne ''); } sub rewind { return shift->seek(0,0); } sub seek { my ($this, $pos, $origin) = @_; return seek($this->{'inHANDLE'}, $pos, $origin) if($this->{'inHANDLE'} ne ''); return seek($this->{'outHANDLE'}, $pos, $origin) if($this->{'outHANDLE'} ne ''); } sub Initialize { my ($this) = @_; $this->{'inHANDLE'} = ''; $this->{'outHANDLE'} = ''; $this->{'FileName'} = ''; $this->{'Mode'} = ''; $this->{'CharCode'} = ''; } sub FileName { my ($this) = @_; return $this->{'FileName'}; } sub HANDLE { my ($this) = @_; return $this->{'inHANDLE'} if($this->{'inHANDLE'} ne ''); return $this->{'outHANDLE'} if($this->{'outHANDLE'} ne ''); } sub inHANDLE { my ($this) = @_; return $this->{'inHANDLE'}; } sub outHANDLE { my ($this) = @_; return $this->{'outHANDLE'}; } sub Mode { my ($this) = @_; return $this->{'Mode'}; } sub CharCode { my ($this) = @_; return $this->{'CharCode'}; } 1;