void wxTarOutputStream::SetExtendedHeader(const wxString& key, const wxString& value) { if (m_pax) { #if wxUSE_UNICODE const wxCharBuffer utf_key = key.utf8_str(); const wxCharBuffer utf_value = value.utf8_str(); #else const wxWX2WCbuf wide_key = key.wc_str(GetConv()); const wxCharBuffer utf_key = wxConvUTF8.cWC2MB(wide_key); const wxWX2WCbuf wide_value = value.wc_str(GetConv()); const wxCharBuffer utf_value = wxConvUTF8.cWC2MB(wide_value); #endif // wxUSE_UNICODE/!wxUSE_UNICODE // a small buffer to format the length field in char buf[32]; // length of "99<space><key>=<value>\n" unsigned long length = strlen(utf_value) + strlen(utf_key) + 5; sprintf(buf, "%lu", length); // the length includes itself size_t lenlen = strlen(buf); if (lenlen != 2) { length += lenlen - 2; sprintf(buf, "%lu", length); if (strlen(buf) > lenlen) sprintf(buf, "%lu", ++length); } // reallocate m_extendedHdr if it's not big enough if (m_extendedSize < length) { size_t rounded = RoundUpSize(length); m_extendedSize <<= 1; if (rounded > m_extendedSize) m_extendedSize = rounded; char *oldHdr = m_extendedHdr; m_extendedHdr = new char[m_extendedSize]; if (oldHdr) { strcpy(m_extendedHdr, oldHdr); delete oldHdr; } else { *m_extendedHdr = 0; } } // append the new record char *append = strchr(m_extendedHdr, 0); sprintf(append, "%s %s=%s\012", buf, (const char*)utf_key, (const char*)utf_value); } else { // if not pax then make a list of fields to report as errors if (!m_badfit.empty()) m_badfit += wxT(", "); m_badfit += key; } }
bool wxTextDataObject::GetDataHere(const wxDataFormat& format, void *buf) const { wxCharBuffer buffer = GetConv(format).cWX2MB( GetText().c_str() ); if ( !buffer ) return false; size_t len = GetConv(format).WC2MB( NULL , GetText().c_str() , 0 ) + ( format == wxDF_UNICODETEXT ? 2 : 1 ) ; memcpy( (char*) buf, (const char*) buffer , len ); // trailing (uni)char 0 return true; }
wxString wxTarInputStream::GetHeaderPath() const { wxString path(GetExtendedHeader(wxS("path"))); if (!path.empty()) return path; path = wxString(m_hdr->Get(TAR_NAME), GetConv()); if (m_tarType != TYPE_USTAR) return path; const char *prefix = m_hdr->Get(TAR_PREFIX); return *prefix ? wxString(prefix, GetConv()) + wxT("/") + path : path; }
size_t wxTextDataObject::GetDataSize(const wxDataFormat& format) const { size_t len = GetConv(format).WC2MB( NULL, GetText().c_str(), 0 ); len += (format == wxDF_UNICODETEXT ? 2 : 1); return len; }
wxString wxTarInputStream::GetHeaderString(int id) const { wxString value(GetExtendedHeader(m_hdr->Name(id))); if (value.empty()) value = wxString(m_hdr->Get(id), GetConv()); return value; }
bool wxTextDataObject::GetDataHere(const wxDataFormat& format, void *buf) const { wxCharBuffer buffer = GetConv(format).cWX2MB( GetText().c_str() ); if ( !buffer ) return false; strcpy( (char*) buf, buffer ); return true; }
bool wxTextDataObject::SetData(const wxDataFormat& format, size_t WXUNUSED(len), const void *buf) { wxWCharBuffer buffer = GetConv(format).cMB2WX((const char *)buf); if ( !buffer ) return false; SetText(buffer); return true; }
wxString wxTarInputStream::GetExtendedHeader(const wxString& key) const { wxTarHeaderRecords::iterator it; // look at normal extended header records first if (m_HeaderRecs) { it = m_HeaderRecs->find(key); if (it != m_HeaderRecs->end()) return wxString(it->second.wc_str(wxConvUTF8), GetConv()); } // if not found, look at the global header records if (m_GlobalHeaderRecs) { it = m_GlobalHeaderRecs->find(key); if (it != m_GlobalHeaderRecs->end()) return wxString(it->second.wc_str(wxConvUTF8), GetConv()); } return wxEmptyString; }
bool wxTextDataObject::SetData(const wxDataFormat& format, size_t WXUNUSED(len), const void *buf) { if ( buf == NULL ) return false; SetText(GetConv(format).cMB2WX(static_cast<const char*>(buf))); return true; }
bool wxTextDataObject::GetDataHere(const wxDataFormat& format, void *buf) const { if ( buf == NULL ) return false; wxCharBuffer buffer(GetConv(format).cWX2MB(GetText().c_str())); memcpy(buf, buffer.data(), buffer.length()); return true; }
/*---------------------------------------------------------------- CConvFactory::GetCharset キャラクタセットを取得する ----------------------------------------------------------------*/ CharSetMode CConvFactory::GetCharset(){ switch(m_nCharSet){ case CSM_UTF8: case CSM_UTF8_BOM: if (((CTextConverter_Unicode*)GetConv())->IncludeBOM()) return CSM_UTF8_BOM; else return CSM_UTF8; case CSM_UTF16_LE: case CSM_UTF16_LE_BOM: if (((CTextConverter_Unicode*)GetConv())->IncludeBOM()) return CSM_UTF16_LE_BOM; else return CSM_UTF16_LE; case CSM_UTF16_BE: case CSM_UTF16_BE_BOM: if (((CTextConverter_Unicode*)GetConv())->IncludeBOM()) return CSM_UTF16_BE_BOM; else return CSM_UTF16_BE; case CSM_UTF32_LE: case CSM_UTF32_LE_BOM: if (((CTextConverter_Unicode*)GetConv())->IncludeBOM()) return CSM_UTF32_LE_BOM; else return CSM_UTF32_LE; case CSM_UTF32_BE: case CSM_UTF32_BE_BOM: if (((CTextConverter_Unicode*)GetConv())->IncludeBOM()) return CSM_UTF32_BE_BOM; else return CSM_UTF32_BE; default: return m_nCharSet; } }
bool wxTarInputStream::ReadExtendedHeader(wxTarHeaderRecords*& recs) { if (!recs) recs = new wxTarHeaderRecords; // round length up to a whole number of blocks size_t len = m_hdr->GetOctal(TAR_SIZE); size_t size = RoundUpSize(len); // read in the whole header since it should be small wxCharBuffer buf(size); size_t lastread = m_parent_i_stream->Read(buf.data(), size).LastRead(); if (lastread < len) len = lastread; buf.data()[len] = 0; m_offset += lastread; size_t recPos, recSize; bool ok = true; for (recPos = 0; recPos < len && ok; recPos += recSize) { char *pRec = buf.data() + recPos; char *p = pRec; // read the record size (byte count in ascii decimal) recSize = 0; while (isdigit((unsigned char) *p)) recSize = recSize * 10 + *p++ - '0'; // validity checks if (recPos + recSize > len) break; if (recSize < p - pRec + (size_t)3 || *p != ' ' || pRec[recSize - 1] != '\012') { ok = false; continue; } // replace the final '\n' with a nul, to terminate value pRec[recSize - 1] = 0; // the key is here, following the space char *pKey = ++p; // look forward for the '=', the value follows while (*p && *p != '=') p++; if (!*p) { ok = false; continue; } // replace the '=' with a nul, to terminate the key *p++ = 0; wxString key(wxConvUTF8.cMB2WC(pKey), GetConv()); wxString value(wxConvUTF8.cMB2WC(p), GetConv()); // an empty value unsets a previously given value if (value.empty()) recs->erase(key); else (*recs)[key] = value; } if (!ok || recPos < len || size != lastread) { wxLogWarning(_("invalid data in extended tar header")); return false; } return true; }
size_t wxTextDataObject::GetDataSize(const wxDataFormat& format) const { return GetConv(format).WC2MB(NULL, GetText().wc_str(), 0); }
void wxTarOutputStream::SetHeaderString(int id, const wxString& str) { strncpy(m_hdr->Get(id), str.mb_str(GetConv()), m_hdr->Len(id)); if (str.length() > m_hdr->Len(id)) SetExtendedHeader(m_hdr->Name(id), str); }
void wxTarOutputStream::SetHeaderPath(const wxString& name) { if (!m_hdr->SetPath(name, GetConv()) || (m_pax && !name.IsAscii())) SetExtendedHeader(wxT("path"), name); }
bool wxTarOutputStream::WriteHeaders(wxTarEntry& entry) { m_hdr->Clear(); SetHeaderPath(entry.GetName(wxPATH_UNIX)); SetHeaderNumber(TAR_MODE, entry.GetMode()); SetHeaderNumber(TAR_UID, entry.GetUserId()); SetHeaderNumber(TAR_GID, entry.GetGroupId()); if (entry.GetSize() == wxInvalidOffset) entry.SetSize(0); m_large = !SetHeaderNumber(TAR_SIZE, entry.GetSize()); SetHeaderDate(wxT("mtime"), entry.GetDateTime()); if (entry.GetAccessTime().IsValid()) SetHeaderDate(wxT("atime"), entry.GetAccessTime()); if (entry.GetCreateTime().IsValid()) SetHeaderDate(wxT("ctime"), entry.GetCreateTime()); *m_hdr->Get(TAR_TYPEFLAG) = char(entry.GetTypeFlag()); strcpy(m_hdr->Get(TAR_MAGIC), USTAR_MAGIC); strcpy(m_hdr->Get(TAR_VERSION), USTAR_VERSION); SetHeaderString(TAR_LINKNAME, entry.GetLinkName()); SetHeaderString(TAR_UNAME, entry.GetUserName()); SetHeaderString(TAR_GNAME, entry.GetGroupName()); if (~entry.GetDevMajor()) SetHeaderNumber(TAR_DEVMAJOR, entry.GetDevMajor()); if (~entry.GetDevMinor()) SetHeaderNumber(TAR_DEVMINOR, entry.GetDevMinor()); m_chksum = m_hdr->Sum(); m_hdr->SetOctal(TAR_CHKSUM, m_chksum); if (!m_large) m_chksum -= m_hdr->SumField(TAR_SIZE); // The main header is now fully prepared so we know what extended headers // (if any) will be needed. Output any extended headers before writing // the main header. if (m_extendedHdr && *m_extendedHdr) { wxASSERT(m_pax); // the extended headers are written to the tar as a file entry, // so prepare a regular header block for the pseudo-file. if (!m_hdr2) m_hdr2 = new wxTarHeaderBlock; m_hdr2->Clear(); // an old tar that doesn't understand extended headers will // extract it as a file, so give these fields reasonable values // so that the user will have access to read and remove it. m_hdr2->SetPath(PaxHeaderPath(wxT("%d/PaxHeaders.%p/%f"), entry.GetName(wxPATH_UNIX)), GetConv()); m_hdr2->SetOctal(TAR_MODE, 0600); strcpy(m_hdr2->Get(TAR_UID), m_hdr->Get(TAR_UID)); strcpy(m_hdr2->Get(TAR_GID), m_hdr->Get(TAR_GID)); size_t length = strlen(m_extendedHdr); m_hdr2->SetOctal(TAR_SIZE, length); strcpy(m_hdr2->Get(TAR_MTIME), m_hdr->Get(TAR_MTIME)); *m_hdr2->Get(TAR_TYPEFLAG) = 'x'; strcpy(m_hdr2->Get(TAR_MAGIC), USTAR_MAGIC); strcpy(m_hdr2->Get(TAR_VERSION), USTAR_VERSION); strcpy(m_hdr2->Get(TAR_UNAME), m_hdr->Get(TAR_UNAME)); strcpy(m_hdr2->Get(TAR_GNAME), m_hdr->Get(TAR_GNAME)); m_hdr2->SetOctal(TAR_CHKSUM, m_hdr2->Sum()); m_hdr2->Write(*m_parent_o_stream); m_tarsize += TAR_BLOCKSIZE; size_t rounded = RoundUpSize(length); memset(m_extendedHdr + length, 0, rounded - length); m_parent_o_stream->Write(m_extendedHdr, rounded); m_tarsize += rounded; *m_extendedHdr = 0; // update m_headpos which is used to seek back to fix up the file // length if it is not known in advance if (m_tarstart != wxInvalidOffset) m_headpos = m_tarstart + m_tarsize; } // if don't have extended headers just report error if (!m_badfit.empty()) { wxASSERT(!m_pax); wxLogWarning(_("%s did not fit the tar header for entry '%s'"), m_badfit.c_str(), entry.GetName().c_str()); m_badfit.clear(); } m_hdr->Write(*m_parent_o_stream); m_tarsize += TAR_BLOCKSIZE; m_lasterror = m_parent_o_stream->GetLastError(); return IsOk(); }
size_t wxTextDataObject::GetDataSize(const wxDataFormat& format) const { wxCharBuffer buffer = GetConv(format).cWX2MB( GetText().c_str() ); return buffer ? strlen( buffer ) : 0; }