diff --git a/docs/changes.txt b/docs/changes.txt index 91a0a3c018..886cb9c135 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -74,6 +74,9 @@ INCOMPATIBLE CHANGES SINCE 3.1.0: - The enum value wxTASKBAR_JUMP_LIST_DESTIONATION, which was added in 3.1.0, contains a typo and has been renamed to wxTASKBAR_JUMP_LIST_DESTINATION. + +- wxZipOutputStream will now automatically convert filenames to UTF-8, if the + wxMBConv used when calling the constructor supports UTF-8 encoding. All: @@ -98,6 +101,7 @@ All: - Add wxCMD_LINE_HIDDEN wxCmdLineParser flag (Lauri Nurmi). - Fix wxRmdir() with non-ASCII paths (trivia21). - Don't crash in wxFFile::Eof() or Error() on closed file (jprotopopov). +- Add UTF-8 support to wxZipOutputStream (Tobias Taschner). All (GUI): diff --git a/include/wx/zipstrm.h b/include/wx/zipstrm.h index ad07e42d64..9323cd101c 100644 --- a/include/wx/zipstrm.h +++ b/include/wx/zipstrm.h @@ -236,6 +236,8 @@ private: bool LoadExtraInfo(const char* extraData, wxUint16 extraLen, bool localInfo); + wxUint16 GetInternalFlags(bool checkForUTF8) const; + wxUint8 m_SystemMadeBy; // one of enum wxZipSystem wxUint8 m_VersionMadeBy; // major * 10 + minor @@ -278,10 +280,10 @@ class WXDLLIMPEXP_BASE wxZipOutputStream : public wxArchiveOutputStream public: wxZipOutputStream(wxOutputStream& stream, int level = -1, - wxMBConv& conv = wxConvLocal); + wxMBConv& conv = wxConvUTF8); wxZipOutputStream(wxOutputStream *stream, int level = -1, - wxMBConv& conv = wxConvLocal); + wxMBConv& conv = wxConvUTF8); virtual WXZIPFIX ~wxZipOutputStream(); bool PutNextEntry(wxZipEntry *entry) { return DoCreate(entry); } diff --git a/interface/wx/zipstrm.h b/interface/wx/zipstrm.h index fa21b1e986..8a787b7031 100644 --- a/interface/wx/zipstrm.h +++ b/interface/wx/zipstrm.h @@ -479,11 +479,18 @@ public: In a Unicode build the third parameter @a conv is used to translate the filename and comment fields to an 8-bit encoding. It has no effect on the stream's data. + + Since version 3.1.1, filenames in the generated archive will be encoded + using UTF-8 and marked according to ZIP specification. To get the + previous behaviour wxConvLocal may be provided as the conv object. + Please note that not all unzip applications are fully ZIP spec + compatible and may not correctly decode UTF-8 characters. For the best + interoperability using only ASCII characters is the safest option. */ wxZipOutputStream(wxOutputStream& stream, int level = -1, - wxMBConv& conv = wxConvLocal); + wxMBConv& conv = wxConvUTF8); wxZipOutputStream(wxOutputStream* stream, int level = -1, - wxMBConv& conv = wxConvLocal); + wxMBConv& conv = wxConvUTF8); //@} /** diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index 12be143e92..a63f34034b 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -1137,7 +1137,7 @@ size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const wxDataOutputStream ds(stream); - ds << versionNeeded << m_Flags << m_Method; + ds << versionNeeded << GetInternalFlags(conv.IsUTF8()) << m_Method; ds.Write32(GetDateTime().GetAsDOS()); ds.Write32(m_Crc); @@ -1267,7 +1267,7 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const ds << CENTRAL_MAGIC << m_VersionMadeBy << m_SystemMadeBy; ds.Write16(versionNeeded); - ds.Write16(wx_truncate_cast(wxUint16, GetFlags())); + ds.Write16(wx_truncate_cast(wxUint16, GetInternalFlags(conv.IsUTF8()))); ds.Write16(wx_truncate_cast(wxUint16, GetMethod())); ds.Write32(GetDateTime().GetAsDOS()); ds.Write32(GetCrc()); @@ -1359,6 +1359,16 @@ size_t wxZipEntry::WriteDescriptor(wxOutputStream& stream, wxUint32 crc, return SUMS_SIZE; } +// Returns the flags as specified or including the UTF-8 flag if filename +// contains non ASCII characters +wxUint16 wxZipEntry::GetInternalFlags(bool checkForUTF8) const +{ + wxUint16 flags = m_Flags; + if (checkForUTF8 && (!m_Name.IsAscii() || !m_Comment.IsAscii())) + flags |= wxZIP_LANG_ENC_UTF8; + + return flags; +} ///////////////////////////////////////////////////////////////////////////// // wxZipEndRec - holds the end of central directory record @@ -2115,7 +2125,7 @@ WX_DEFINE_LIST(wxZipEntryList_) wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, int level /*=-1*/, - wxMBConv& conv /*=wxConvLocal*/) + wxMBConv& conv /*=wxConvUTF8*/) : wxArchiveOutputStream(stream, conv) { Init(level); @@ -2123,7 +2133,7 @@ wxZipOutputStream::wxZipOutputStream(wxOutputStream& stream, wxZipOutputStream::wxZipOutputStream(wxOutputStream *stream, int level /*=-1*/, - wxMBConv& conv /*=wxConvLocal*/) + wxMBConv& conv /*=wxConvUTF8*/) : wxArchiveOutputStream(stream, conv) { Init(level);