[Python-checkins] python/dist/src/Modules _iconv_codec.c,1.4,1.5

doerwalter@users.sourceforge.net doerwalter@users.sourceforge.net
Thu, 30 Jan 2003 11:55:30 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv25417/Modules

Modified Files:
	_iconv_codec.c 
Log Message:
Check whether the choosen encoding requires byte swapping
for this iconv() implementation in the init function.

For encoding: use a byteswapped version of the input if
neccessary.

For decoding: byteswap every piece returned by iconv()
if neccessary (but not those pieces returned from the
callback)

Comment out test_sane() in the test script, because
whether this works depends on whether byte swapping
is neccessary or not (an on Py_UNICODE_SIZE)


Index: _iconv_codec.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_iconv_codec.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** _iconv_codec.c	27 Jan 2003 11:39:04 -0000	1.4
--- _iconv_codec.c	30 Jan 2003 19:55:28 -0000	1.5
***************
*** 43,46 ****
--- 43,50 ----
  staticforward PyTypeObject iconvcodec_Type;
  
+ /* does the choosen internal encoding require
+  * byteswapping to get native endianness?
+  * 0=no, 1=yes, -1=unknown */
+ static int byteswap = -1;
  
  #define ERROR_STRICT                (PyObject *)(1)
***************
*** 89,92 ****
--- 93,98 ----
      PyObject            *outputobj = NULL, *errorcb = NULL,
                          *exceptionobj = NULL;
+     Py_UNICODE          *swappedinput;
+     int                  swapi;
  
      if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u#|s:encode",
***************
*** 122,125 ****
--- 128,149 ----
      out_top = PyString_AS_STRING(outputobj);                \
  }
+     if (byteswap) {
+         swappedinput = PyMem_Malloc(inplen);
+         if (swappedinput == NULL)
+             return NULL;
+         for (swapi = 0; swapi<inputlen; ++swapi)
+         {
+            Py_UNICODE c = input[swapi];
+ #if Py_UNICODE_SIZE == 2
+            c = ((char *)&c)[0]<<8 | ((char *)&c)[1];
+ #else
+            c = ((char *)&c)[0]<<24 | ((char *)&c)[1]<<16 |
+                ((char *)&c)[2]<<8 | ((char *)&c)[3];
+ #endif
+            swappedinput[swapi] = c;
+         }
+         inp = inp_top = (char *)swappedinput;
+     }
+ 
      while (inplen > 0) {
          if (iconv(self->enchdl, (char**)&inp, &inplen, &out, &outlen) == -1) {
***************
*** 254,257 ****
--- 278,283 ----
          if (rettup == NULL) {
              Py_DECREF(outputobj);
+             if (byteswap)
+                 PyMem_Free(swappedinput);
              return NULL;
          }
***************
*** 267,270 ****
--- 293,298 ----
      }
      Py_XDECREF(exceptionobj);
+     if (byteswap)
+         PyMem_Free(swappedinput);
  
      return NULL;
***************
*** 320,324 ****
  }
      while (inplen > 0) {
!         if (iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen) == -1) {
              char         reason[128], *reasonpos = (char *)reason;
              int          errpos;
--- 348,372 ----
  }
      while (inplen > 0) {
!         char *oldout = out;
!         char res = iconv(self->dechdl, (char**)&inp, &inplen, &out, &outlen);
! 
!         if (byteswap) {
!             while (oldout < out)
!             {
!                 char c0 = oldout[0];
! #if Py_UNICODE_SIZE == 2
!                 oldout[0] = oldout[1];
!                 oldout[1] = c0;
! #else
!                 char c1 = oldout[1];
!                 oldout[0] = oldout[3];
!                 oldout[1] = oldout[2];
!                 oldout[2] = c1;
!                 oldout[3] = c0;
! #endif
!                 oldout += sizeof(Py_UNICODE);
!             }
!         }
!         if (res == -1) {
              char         reason[128], *reasonpos = (char *)reason;
              int          errpos;
***************
*** 602,605 ****
--- 650,683 ----
  {
      PyObject *m;
+ 
+     char in = 1;
+     char *inptr = &in;
+     int insize = 1;
+     Py_UNICODE out = 0;
+     char *outptr = (char *)&out;
+     int outsize = sizeof(out);
+     int res;
+ 
+     iconv_t hdl = iconv_open(UNICODE_ENCODING, "ASCII");
+ 
+     if (hdl == (iconv_t)-1)
+         Py_FatalError("can't initialize the _iconv_codec module: iconv_open() failed");
+ 
+     res = iconv(hdl, &inptr, &insize, &outptr, &outsize);
+     if (res == -1)
+         Py_FatalError("can't initialize the _iconv_codec module: iconv() failed");
+ 
+     /* Check whether conv() returned native endianess or not for the choosen encoding */
+     if (out == 0x1)
+        byteswap = 0;
+ #if Py_UNICODE_SIZE == 2
+     else if (out == 0x0100)
+ #else
+     else if (out == 0x01000000)
+ #endif
+        byteswap = 1;
+     else
+         Py_FatalError("can't initialize the _iconv_codec module: mixed endianess");
+     iconv_close(hdl);
  
      m = Py_InitModule("_iconv_codec", _iconv_codec_methods);