HRESULT CAgent::CreateFolder( const wchar_t *newArchiveName, const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100) { if (!CanUpdate()) return E_NOTIMPL; CUpdateCallbackAgent updateCallbackAgent; updateCallbackAgent.SetCallback(updateCallback100); CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CRecordVector<CUpdatePair2> updatePairs; UInt32 numItemsInArchive; RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); for (UInt32 i = 0; i < numItemsInArchive; i++) { CUpdatePair2 up2; up2.NewData = up2.NewProps = false; up2.IsAnti = false; // check it. up2.ArcIndex = i; updatePairs.Add(up2); } CUpdatePair2 up2; up2.NewData = up2.NewProps = true; up2.IsAnti = false; up2.DirIndex = 0; updatePairs.Add(up2); updatePairs.ReserveDown(); CDirItems dirItems; CDirItem di; di.Attrib = FILE_ATTRIBUTE_DIRECTORY; di.Size = 0; di.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName; FILETIME ft; NTime::GetCurUtcFileTime(ft); di.CTime = di.ATime = di.MTime = ft; dirItems.Items.Add(di); updateCallbackSpec->Callback = &updateCallbackAgent; updateCallbackSpec->DirItems = &dirItems; updateCallbackSpec->UpdatePairs = &updatePairs; updateCallbackSpec->Archive = GetArchive(); return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); }
void UpdateProduce( const CRecordVector<CUpdatePair> &updatePairs, const CActionSet &actionSet, CRecordVector<CUpdatePair2> &operationChain, IUpdateProduceCallback *callback) { for (int i = 0; i < updatePairs.Size(); i++) { const CUpdatePair &pair = updatePairs[i]; CUpdatePair2 up2; up2.IsAnti = false; up2.DirIndex = pair.DirIndex; up2.ArcIndex = pair.ArcIndex; up2.NewData = up2.NewProps = true; switch(actionSet.StateActions[pair.State]) { case NPairAction::kIgnore: /* if (pair.State != NPairState::kOnlyOnDisk) IgnoreArchiveItem(m_ArchiveItems[pair.ArcIndex]); // cout << "deleting"; */ if (callback) callback->ShowDeleteFile(pair.ArcIndex); continue; case NPairAction::kCopy: if (pair.State == NPairState::kOnlyOnDisk) throw kUpdateActionSetCollision; up2.NewData = up2.NewProps = false; break; case NPairAction::kCompress: if (pair.State == NPairState::kOnlyInArchive || pair.State == NPairState::kNotMasked) throw kUpdateActionSetCollision; break; case NPairAction::kCompressAsAnti: up2.IsAnti = true; break; } operationChain.Add(up2); } operationChain.ReserveDown(); }
void GetUpdatePairInfoList( const CDirItems &dirItems, const CObjectVector<CArcItem> &arcItems, NFileTimeType::EEnum fileTimeType, CRecordVector<CUpdatePair> &updatePairs) { CUIntVector dirIndices, arcIndices; unsigned numDirItems = dirItems.Items.Size(); unsigned numArcItems = arcItems.Size(); CIntArr duplicatedArcItem(numArcItems); { int *vals = &duplicatedArcItem[0]; for (unsigned i = 0; i < numArcItems; i++) vals[i] = 0; } { arcIndices.ClearAndSetSize(numArcItems); if (numArcItems != 0) { unsigned *vals = &arcIndices[0]; for (unsigned i = 0; i < numArcItems; i++) vals[i] = i; } arcIndices.Sort(CompareArcItems, (void *)&arcItems); for (unsigned i = 0; i + 1 < numArcItems; i++) if (CompareArcItemsBase( arcItems[arcIndices[i]], arcItems[arcIndices[i + 1]]) == 0) { duplicatedArcItem[i] = 1; duplicatedArcItem[i + 1] = -1; } } UStringVector dirNames; { dirNames.ClearAndReserve(numDirItems); unsigned i; for (i = 0; i < numDirItems; i++) dirNames.AddInReserved(dirItems.GetLogPath(i)); SortFileNames(dirNames, dirIndices); for (i = 0; i + 1 < numDirItems; i++) { const UString &s1 = dirNames[dirIndices[i]]; const UString &s2 = dirNames[dirIndices[i + 1]]; if (CompareFileNames(s1, s2) == 0) ThrowError(k_Duplicate_inDir_Message, s1, s2); } } unsigned dirIndex = 0; unsigned arcIndex = 0; int prevHostFile = -1; const UString *prevHostName = NULL; while (dirIndex < numDirItems || arcIndex < numArcItems) { CUpdatePair pair; int dirIndex2 = -1; int arcIndex2 = -1; const CDirItem *di = NULL; const CArcItem *ai = NULL; int compareResult = -1; const UString *name = NULL; if (dirIndex < numDirItems) { dirIndex2 = dirIndices[dirIndex]; di = &dirItems.Items[dirIndex2]; } if (arcIndex < numArcItems) { arcIndex2 = arcIndices[arcIndex]; ai = &arcItems[arcIndex2]; compareResult = 1; if (dirIndex < numDirItems) { compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name); if (compareResult == 0) { if (di->IsDir() != ai->IsDir) compareResult = (ai->IsDir ? 1 : -1); } } } if (compareResult < 0) { name = &dirNames[dirIndex2]; pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; pair.DirIndex = dirIndex2; dirIndex++; } else if (compareResult > 0) { name = &ai->Name; pair.State = ai->Censored ? NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; pair.ArcIndex = arcIndex2; arcIndex++; } else { int dupl = duplicatedArcItem[arcIndex]; if (dupl != 0) ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name); name = &dirNames[dirIndex2]; if (!ai->Censored) ThrowError(k_NotCensoredCollision_Message, *name, ai->Name); pair.DirIndex = dirIndex2; pair.ArcIndex = arcIndex2; switch (ai->MTimeDefined ? MyCompareTime( ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType, di->MTime, ai->MTime): 0) { case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; default: pair.State = (ai->SizeDefined && di->Size == ai->Size) ? NUpdateArchive::NPairState::kSameFiles : NUpdateArchive::NPairState::kUnknowNewerFiles; } dirIndex++; arcIndex++; } if ((di && di->IsAltStream) || (ai && ai->IsAltStream)) { if (prevHostName) { unsigned hostLen = prevHostName->Len(); if (name->Len() > hostLen) if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0) pair.HostIndex = prevHostFile; } } else { prevHostFile = updatePairs.Size(); prevHostName = name; } updatePairs.Add(pair); } updatePairs.ReserveDown(); }