Re: Encode-2.07 vs. PerlIO::encoding

[email protected] (Nick Ing-Simmons)
Newsgroups perl.unicode,perl.perl5.porters
Message-ID <[email protected]>
Dan Kogai <[email protected]> writes:
>On Oct 24, 2004, at 18:34, Rafael Garcia-Suarez wrote:
>> Welcome to backward compatibility hell :)
>
>Hell it was but seems like I came up with a way out (yay).
>
>>> I just want Encode::utf8->decode() to make sure Encode:RETURN_ON_ERR 
>>> is
>>> on when the callar is PerlIO::encoding...
>>
>> Or, one could backport PerlIO::encoding (with your patch) to CPAN and
>> require this latest version for Encode 2.08.
>
>That was what came across my mind first but I found it was not good 
>enough to coerce Encode:RETURN_ON_ERR since $PerlIO::encoding:fallback 
>is open to the public (even documented!).
>
>So far ->renew() is only used by PerlIO (and is meaningful only when 
>the object is Encode::Unicode).  

And certain other bits of code writen by its original author ;-)

>In other words, you can tell it's 
>PerlIO that is calling you if the object is renewed.
>
>The following patch does that.  The new Encode::utf8->decode() checks 
>$self->renewed and if so it sets Encode:RETURN_ON_ERR.  Here is the 
>patch or you can wait for Encode-2.08.

Will try and find time to do a proper patch to the utf-8 decoder.


>
>Thankfully Encode::XS needs no "real" ->renew so it is left as is 
>(dummy ->renewed() was introduced just to be safe).
>
>Dan the Encode Maintainer
>
>diff -ruN ext/Encode-2.07/Encode.xs ext/Encode/Encode.xs
>--- ext/Encode-2.07/Encode.xs   Sat Oct 23 04:37:13 2004
>+++ ext/Encode/Encode.xs        Sun Oct 24 20:31:06 2004
>@@ -252,14 +252,6 @@
>  PROTOTYPES: DISABLE
>
>  void
>-Method_renew(obj)
>-SV *   obj
>-CODE:
>-{
>-    XSRETURN(1);
>-}
>-
>-void
>  Method_decode_xs(obj,src,check = 0)
>  SV *   obj
>  SV *   src
>@@ -270,6 +262,28 @@
>      U8 *s = (U8 *) SvPV(src, slen);
>      U8 *e = (U8 *) SvEND(src);
>      SV *dst = newSV(slen>0?slen:1); /* newSV() abhors 0 -- inaba */
>+
>+    /*
>+     * PerlO check -- we assume the object is of PerlIO if renewed
>+     * and if so, we set RETURN_ON_ERR for partial character
>+     */
>+    int renewed = 0;
>+    dSP; ENTER; SAVETMPS;
>+    PUSHMARK(sp);
>+    XPUSHs(obj);
>+    PUTBACK;
>+    if (call_method("renewed",G_SCALAR) == 1) {
>+       SPAGAIN;
>+       renewed = POPi;
>+       PUTBACK;
>+#if 0
>+       fprintf(stderr, "renewed == %d\n", renewed);
>+#endif
>+       if (renewed){ check |= ENCODE_RETURN_ON_ERR; }
>+    }
>+    FREETMPS; LEAVE;
>+    /* end PerlIO check */
>+
>      SvPOK_only(dst);
>      SvCUR_set(dst,0);
>      if (SvUTF8(src)) {
>@@ -397,6 +411,14 @@
>  {
>      XSRETURN(1);
>  }
>+
>+int
>+Method_renewed(obj)
>+SV *    obj
>+CODE:
>+    RETVAL = 0;
>+OUTPUT:
>+    RETVAL
>
>  void
>  Method_name(obj)
>diff -ruN ext/Encode-2.07/Unicode/Unicode.pm 
>ext/Encode/Unicode/Unicode.pm
>--- ext/Encode-2.07/Unicode/Unicode.pm  Sat Oct 23 04:37:17 2004
>+++ ext/Encode/Unicode/Unicode.pm       Sun Oct 24 20:38:16 2004
>@@ -46,7 +46,7 @@
>      my $self = shift;
>      $BOM_Unknown{$self->name} or return $self;
>      my $clone = bless { %$self } => ref($self);
>-    $clone->{clone} = 1; # so the caller knows it is renewed.
>+    $clone->{clone}++ # so the caller knows it is renewed.
>      return $clone;
>  }
>
>diff -ruN ext/Encode-2.07/lib/Encode/Encoding.pm 
>ext/Encode/lib/Encode/Encoding.pm
>--- ext/Encode-2.07/lib/Encode/Encoding.pm      Sat Oct 23 04:37:13 2004
>+++ ext/Encode/lib/Encode/Encoding.pm   Sun Oct 24 20:25:13 2004
>@@ -5,6 +5,7 @@
>
>  require Encode;
>
>+sub DEBUG { 0 }
>  sub Define
>  {
>      my $obj = shift;
>@@ -16,7 +17,18 @@
>
>  sub name  { return shift->{'Name'} }
>
>-sub renew { return $_[0] }
>+# sub renew { return $_[0] }
>+
>+sub renew {
>+    my $self = shift;
>+    my $clone = bless { %$self } => ref($self);
>+    $clone->{renewed}++; # so the caller can see it
>+    DEBUG and warn $clone->{renewed};
>+    return $clone;
>+}
>+
>+sub renewed{ return $_[0]->{renewed} || 0 }
>+
>  *new_sequence = \&renew;
>
>  sub needs_lines { 0 };
>@@ -167,24 +179,28 @@
>
>  Predefined As:
>
>-  sub renew { return $_[0] }
>+  sub renew {
>+    my $self = shift;
>+    my $clone = bless { %$self } => ref($self);
>+    $clone->{renewed}++;
>+    return $clone;
>+  }
>
>  This method reconstructs the encoding object if necessary.  If you need
>  to store the state during encoding, this is where you clone your 
>object.
>-Here is an example:
>-
>-  sub renew {
>-      my $self = shift;
>-      my $clone = bless { %$self } => ref($self);
>-      $clone->{clone} = 1; # so the caller can see it
>-      return $clone;
>-  }
>-
>-Since most encodings are stateless the default behavior is just return
>-itself as shown above.
>
>  PerlIO ALWAYS calls this method to make sure it has its own private
>  encoding object.
>+
>+=item -E<gt>renewed
>+
>+Predefined As:
>+
>+  sub renewed { $_[0]->{renewed} || 0 }
>+
>+Tells whether the object is renewed (and how many times).  Some
>+modules emit C<Use of uninitialized value in null operation> warning
>+unless the value is numeric so return 0 for false.
>
>  =item -E<gt>perlio_ok()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.