src/corelib/codecs/qiconvcodec.cpp
changeset 19 fcece45ef507
parent 18 2f34d5167611
child 23 89e065397ea6
equal deleted inserted replaced
18:2f34d5167611 19:fcece45ef507
   297     return s;
   297     return s;
   298 }
   298 }
   299 
   299 
   300 Q_GLOBAL_STATIC(QThreadStorage<QIconvCodec::IconvState *>, fromUnicodeState)
   300 Q_GLOBAL_STATIC(QThreadStorage<QIconvCodec::IconvState *>, fromUnicodeState)
   301 
   301 
       
   302 static bool setByteOrder(iconv_t cd)
       
   303 {
       
   304 #if !defined(NO_BOM)
       
   305     // give iconv() a BOM
       
   306     char buf[4];
       
   307     ushort bom[] = { QChar::ByteOrderMark };
       
   308 
       
   309     char *outBytes = buf;
       
   310     char *inBytes = reinterpret_cast<char *>(bom);
       
   311     size_t outBytesLeft = sizeof buf;
       
   312     size_t inBytesLeft = sizeof bom;
       
   313 
       
   314 #if defined(GNU_LIBICONV)
       
   315     const char **inBytesPtr = const_cast<const char **>(&inBytes);
       
   316 #else
       
   317     char **inBytesPtr = &inBytes;
       
   318 #endif
       
   319 
       
   320     if (iconv(cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) {
       
   321         return false;
       
   322     }
       
   323 #endif // NO_BOM
       
   324 
       
   325     return true;
       
   326 }
       
   327 
   302 QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *convState) const
   328 QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *convState) const
   303 {
   329 {
   304     char *inBytes;
   330     char *inBytes;
   305     char *outBytes;
   331     char *outBytes;
   306     size_t inBytesLeft;
   332     size_t inBytesLeft;
   323         return QString::fromRawData(uc, len).toLatin1();
   349         return QString::fromRawData(uc, len).toLatin1();
   324     }
   350     }
   325     IconvState *&state = ts->localData();
   351     IconvState *&state = ts->localData();
   326     if (!state) {
   352     if (!state) {
   327         state = new IconvState(QIconvCodec::createIconv_t(0, UTF16));
   353         state = new IconvState(QIconvCodec::createIconv_t(0, UTF16));
   328         if (state->cd != reinterpret_cast<iconv_t>(-1)) {
   354         if (state->cd == reinterpret_cast<iconv_t>(-1)) {
   329             size_t outBytesLeft = len + 3; // +3 for the BOM
   355             if (!setByteOrder(state->cd)) {
   330             QByteArray ba(outBytesLeft, Qt::Uninitialized);
       
   331             outBytes = ba.data();
       
   332 
       
   333 #if !defined(NO_BOM)
       
   334             // give iconv() a BOM
       
   335             QChar bom[] = { QChar(QChar::ByteOrderMark) };
       
   336             inBytes = reinterpret_cast<char *>(bom);
       
   337             inBytesLeft = sizeof(bom);
       
   338             if (iconv(state->cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) {
       
   339                 perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed for BOM");
   356                 perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed for BOM");
   340 
   357 
   341                 iconv_close(state->cd);
   358                 iconv_close(state->cd);
   342                 state->cd = reinterpret_cast<iconv_t>(-1);
   359                 state->cd = reinterpret_cast<iconv_t>(-1);
   343 
   360 
   344                 return QString(uc, len).toAscii();
   361                 return QString(uc, len).toAscii();
   345             }
   362             }
   346 #endif // NO_BOM
       
   347         }
   363         }
   348     }
   364     }
   349     if (state->cd == reinterpret_cast<iconv_t>(-1)) {
   365     if (state->cd == reinterpret_cast<iconv_t>(-1)) {
   350         static int reported = 0;
   366         static int reported = 0;
   351         if (!reported++) {
   367         if (!reported++) {
   420         }
   436         }
   421     }
   437     }
   422 
   438 
   423     // reset to initial state
   439     // reset to initial state
   424     iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
   440     iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
       
   441     setByteOrder(state->cd);
   425 
   442 
   426     ba.resize(ba.size() - outBytesLeft);
   443     ba.resize(ba.size() - outBytesLeft);
   427 
   444 
   428     if (convState)
   445     if (convState)
   429         convState->invalidChars = invalidCount;
   446         convState->invalidChars = invalidCount;