Logo Search packages:      
Sourcecode: harbour version File versions  Download package

bool CZipArchive::RenameFile ( WORD  uIndex,
LPCTSTR  lpszNewName 
)

Change the name of the file with the given index.

Parameters:
uIndex zero-based index of the file
lpszNewName new name for the file
Returns:
Note:
Throws exceptions.
See also:
SetAdvanced

Definition at line 3024 of file ziparchive.cpp.

References CZipAutoBuffer::Allocate(), CZipPathComponent::AppendSeparator(), CZipActionCallback::CallbackEnd(), cbRename, CZipString::Collate(), ZipCompatibility::FileNameUpdate(), Flush(), GetArchivePath(), CZipCentralDir::GetBytesBefore(), GetCallback(), GetCount(), CZipFileHeader::GetExtraFieldSize(), GetFileInfo(), CZipFileHeader::GetFileName(), CZipFileHeader::GetFileNameSize(), CZipAutoBuffer::GetSize(), CZipActionCallback::Init(), CZipArchive::CZipInternalInfo::Init(), IsClosed(), CZipFileHeader::IsDirectory(), CZipStorage::IsSpanMode(), m_bAutoFlush, m_centralDir, m_iArchiveSystCompatib, m_iFileOpened, m_info, CZipStorage::m_pFile, CZipFileHeader::m_pszFileName, m_storage, CZipFileHeader::m_uOffset, MovePackedFiles(), CZipArchive::CZipInternalInfo::ReleaseBuf(), CZipCentralDir::RemoveFromDisk(), CZipPathComponent::RemoveSeparators(), CZipCentralDir::RenameFile(), CZipFileHeader::SetFileName(), CZipFileHeader::SetSystemCompatibility(), and CZipActionCallback::SetTotal().

{
      if (IsClosed())
      {
            TRACE(_T("%s(%i) : ZipArchive is closed.\n"),__FILE__,__LINE__);
            return false;
      }

      if (m_storage.IsSpanMode())
      {
            TRACE(_T("%s(%i) : You cannot rename files in the disk spannig archive.\n"),__FILE__,__LINE__);
            return false;
      }

      if (m_iFileOpened)
      {
            TRACE(_T("%s(%i) : You cannot rename a file if there is a file opened.\n"),__FILE__,__LINE__);
            return false;
      }
      CZipFileHeader fh, fhNew;
      if (!GetFileInfo(fh, uIndex))
            return false;
      CZipString szNewName(lpszNewName);
      if (fh.IsDirectory())
            CZipPathComponent::AppendSeparator(szNewName);
      else
            CZipPathComponent::RemoveSeparators(szNewName);
      if (fh.GetFileName().Collate(szNewName) == 0)
            return true;
      fhNew.SetSystemCompatibility(m_iArchiveSystCompatib);

      fhNew.SetFileName(szNewName);
      ZipCompatibility::FileNameUpdate(fhNew, false);
      ZipCompatibility::FileNameUpdate(fh, false); // in case the conversion changes the filename size
      WORD uFileNameLen = fh.GetFileNameSize();
      WORD uNewFileNameLen = fhNew.GetFileNameSize();
      int iDelta = uNewFileNameLen - uFileNameLen;
      int iOffset = 0;
      CZipAutoBuffer buf, *pBuf;
      m_centralDir.RemoveFromDisk(); // does m_storage.Flush();
      if (iDelta != 0)
      {
            // we need to make more or less space

            m_info.Init();
            DWORD uStartOffset = fh.m_uOffset + 30 + uFileNameLen;
            DWORD uFileLen = m_storage.m_pFile->GetLength();
            DWORD uEndOffset = uFileLen - m_centralDir.GetBytesBefore();
            CZipActionCallback* pCallback = GetCallback(cbRename);
            if (pCallback)
            {
                  // do it right and sent the notification
                  pCallback->Init(fh.GetFileName(), GetArchivePath());
                  pCallback->SetTotal(uEndOffset - uStartOffset);
            }
            bool bForward = iDelta > 0;
            if (bForward)
                  m_storage.m_pFile->SetLength(uFileLen + iDelta); // ensure the seek is correct

            MovePackedFiles(uStartOffset, uEndOffset, abs(iDelta), pCallback, bForward);
            if (pCallback)
                  pCallback->CallbackEnd();

            if (!bForward)
                  m_storage.m_pFile->SetLength(uFileLen + iDelta); // delta < 0; shrink the file

            m_info.ReleaseBuf();

            int iSize = GetCount();
            for (int i = uIndex + 1; i < iSize; i++)
                  m_centralDir[i]->m_uOffset += iDelta;
            buf.Allocate(4+uNewFileNameLen);
            WORD uExtraFieldSize = fh.GetExtraFieldSize();
            memcpy(buf, &uNewFileNameLen, 2);
            memcpy(buf + 2, &uExtraFieldSize, 2); // to write everything at once
            memcpy(buf + 4, fhNew.m_pszFileName, uNewFileNameLen);
            pBuf = &buf;
            iOffset = -4;
      }
      else
            pBuf = &fhNew.m_pszFileName;

      m_storage.m_pFile->Seek(m_centralDir.GetBytesBefore() + fh.m_uOffset + 30 + iOffset, CZipAbstractFile::begin);
      m_storage.m_pFile->Write(buf, buf.GetSize());
      m_centralDir.RenameFile(uIndex, szNewName);
      if (m_bAutoFlush)
            Flush();

      return true;
}


Generated by  Doxygen 1.6.0   Back to index