\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /usr/lib64/perl5/vendor_perl/Encode/CN/

Viewing File: HZ.pm

package Encode::CN::HZ;

use strict;
use warnings;
use utf8 ();

use vars qw($VERSION);
$VERSION = do { my @r = ( q$Revision: 2.6 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r };

use Encode qw(:fallbacks);

use base qw(Encode::Encoding);
__PACKAGE__->Define('hz');

# HZ is a combination of ASCII and escaped GB, so we implement it
# with the GB2312(raw) encoding here. Cf. RFCs 1842 & 1843.

# not ported for EBCDIC.  Which should be used, "~" or "\x7E"?

sub needs_lines { 1 }

sub decode ($$;$) {
    my ( $obj, $str, $chk ) = @_;

    my $GB  = Encode::find_encoding('gb2312-raw');
    my $ret = substr($str, 0, 0); # to propagate taintedness
    my $in_ascii = 1;    # default mode is ASCII.

    while ( length $str ) {
        if ($in_ascii) {    # ASCII mode
            if ( $str =~ s/^([\x00-\x7D\x7F]+)// ) {    # no '~' => ASCII
                $ret .= $1;

                # EBCDIC should need ascii2native, but not ported.
            }
            elsif ( $str =~ s/^\x7E\x7E// ) {           # escaped tilde
                $ret .= '~';
            }
            elsif ( $str =~ s/^\x7E\cJ// ) {    # '\cJ' == LF in ASCII
                1;                              # no-op
            }
            elsif ( $str =~ s/^\x7E\x7B// ) {    # '~{'
                $in_ascii = 0;                   # to GB
            }
            else {    # encounters an invalid escape, \x80 or greater
                last;
            }
        }
        else {        # GB mode; the byte ranges are as in RFC 1843.
            no warnings 'uninitialized';
            if ( $str =~ s/^((?:[\x21-\x77][\x21-\x7E])+)// ) {
                $ret .= $GB->decode( $1, $chk );
            }
            elsif ( $str =~ s/^\x7E\x7D// ) {    # '~}'
                $in_ascii = 1;
            }
            else {                               # invalid
                last;
            }
        }
    }
    $_[1] = '' if $chk;    # needs_lines guarantees no partial character
    return $ret;
}

sub cat_decode {
    my ( $obj, undef, $src, $pos, $trm, $chk ) = @_;
    my ( $rdst, $rsrc, $rpos ) = \@_[ 1 .. 3 ];

    my $GB  = Encode::find_encoding('gb2312-raw');
    my $ret = '';
    my $in_ascii = 1;      # default mode is ASCII.

    my $ini_pos = pos($$rsrc);

    substr( $src, 0, $pos ) = '';

    my $ini_len = bytes::length($src);

    # $trm is the first of the pair '~~', then 2nd tilde is to be removed.
    # XXX: Is better C<$src =~ s/^\x7E// or die if ...>?
    $src =~ s/^\x7E// if $trm eq "\x7E";

    while ( length $src ) {
        my $now;
        if ($in_ascii) {    # ASCII mode
            if ( $src =~ s/^([\x00-\x7D\x7F])// ) {    # no '~' => ASCII
                $now = $1;
            }
            elsif ( $src =~ s/^\x7E\x7E// ) {          # escaped tilde
                $now = '~';
            }
            elsif ( $src =~ s/^\x7E\cJ// ) {    # '\cJ' == LF in ASCII
                next;
            }
            elsif ( $src =~ s/^\x7E\x7B// ) {    # '~{'
                $in_ascii = 0;                   # to GB
                next;
            }
            else {    # encounters an invalid escape, \x80 or greater
                last;
            }
        }
        else {        # GB mode; the byte ranges are as in RFC 1843.
            if ( $src =~ s/^((?:[\x21-\x77][\x21-\x7F])+)// ) {
                $now = $GB->decode( $1, $chk );
            }
            elsif ( $src =~ s/^\x7E\x7D// ) {    # '~}'
                $in_ascii = 1;
                next;
            }
            else {                               # invalid
                last;
            }
        }

        next if !defined $now;

        $ret .= $now;

        if ( $now eq $trm ) {
            $$rdst .= $ret;
            $$rpos = $ini_pos + $pos + $ini_len - bytes::length($src);
            pos($$rsrc) = $ini_pos;
            return 1;
        }
    }

    $$rdst .= $ret;
    $$rpos = $ini_pos + $pos + $ini_len - bytes::length($src);
    pos($$rsrc) = $ini_pos;
    return '';    # terminator not found
}

sub encode($$;$) {
     my ( $obj, $str, $chk ) = @_;

    my $GB  = Encode::find_encoding('gb2312-raw');
    my $ret = substr($str, 0, 0); # to propagate taintedness;
    my $in_ascii = 1;    # default mode is ASCII.

    no warnings 'utf8';  # $str may be malformed UTF8 at the end of a chunk.

    while ( length $str ) {
        if ( $str =~ s/^([[:ascii:]]+)// ) {
            my $tmp = $1;
            $tmp =~ s/~/~~/g;    # escapes tildes
            if ( !$in_ascii ) {
                $ret .= "\x7E\x7D";    # '~}'
                $in_ascii = 1;
            }
            $ret .= pack 'a*', $tmp;    # remove UTF8 flag.
        }
        elsif ( $str =~ s/(.)// ) {
            my $s = $1;
            my $tmp = $GB->encode( $s, $chk );
            last if !defined $tmp;
            if ( length $tmp == 2 ) {    # maybe a valid GB char (XXX)
                if ($in_ascii) {
                    $ret .= "\x7E\x7B";    # '~{'
                    $in_ascii = 0;
                }
                $ret .= $tmp;
            }
            elsif ( length $tmp ) {        # maybe FALLBACK in ASCII (XXX)
                if ( !$in_ascii ) {
                    $ret .= "\x7E\x7D";    # '~}'
                    $in_ascii = 1;
                }
                $ret .= $tmp;
            }
        }
        else {    # if $str is malformed UTF8 *and* if length $str != 0.
            last;
        }
    }
    $_[1] = $str if $chk;

    # The state at the end of the chunk is discarded, even if in GB mode.
    # That results in the combination of GB-OUT and GB-IN, i.e. "~}~{".
    # Parhaps it is harmless, but further investigations may be required...

    if ( !$in_ascii ) {
        $ret .= "\x7E\x7D";    # '~}'
        $in_ascii = 1;
    }
    utf8::encode($ret); # https://rt.cpan.org/Ticket/Display.html?id=35120
    return $ret;
}

1;
__END__

=head1 NAME

Encode::CN::HZ -- internally used by Encode::CN

=cut