void CCurve::AddArcOrLines(bool check_for_arc, std::list<CVertex> &new_vertices, std::list<const CVertex*>& might_be_an_arc, CArc &arc, bool &arc_found, bool &arc_added) { if(check_for_arc && CheckForArc(new_vertices.back(), might_be_an_arc, arc)) { arc_found = true; } else { if(arc_found) { if(arc.AlmostALine()) { new_vertices.push_back(CVertex(arc.m_e, arc.m_user_data)); } else { new_vertices.push_back(CVertex(arc.m_dir ? 1:-1, arc.m_e, arc.m_c, arc.m_user_data)); } arc_added = true; arc_found = false; const CVertex* back_vt = might_be_an_arc.back(); might_be_an_arc.clear(); if(check_for_arc)might_be_an_arc.push_back(back_vt); } else { const CVertex* back_vt = might_be_an_arc.back(); if(check_for_arc)might_be_an_arc.pop_back(); for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++) { const CVertex* v = *It; if(It != might_be_an_arc.begin() || (new_vertices.size() == 0) || (new_vertices.back().m_p != v->m_p)) { new_vertices.push_back(*v); } } might_be_an_arc.clear(); if(check_for_arc)might_be_an_arc.push_back(back_vt); } } }
HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress) { // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) { Files.Free(); Dirs.Clear(); Dirs.AddNew(); IInArchive *archive = arc.Archive; UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); if (progress) RINOK(progress->SetTotal(numItems)); Files.Alloc(numItems); UString path; UString name; NCOM::CPropVariant prop; for (UInt32 i = 0; i < numItems; i++) { if (progress && (i & 0xFFFF) == 0) { UInt64 currentItemIndex = i; RINOK(progress->SetCompleted(¤tItemIndex)); } const wchar_t *s = NULL; unsigned len = 0; bool isPtrName = false; #ifdef MY_CPU_LE if (arc.GetRawProps) { const void *p; UInt32 size; UInt32 propType; if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK && propType == NPropDataType::kUtf16z && size > 2) { // is (size <= 2), it's empty name, and we call default arc.GetItemPath(); len = size / 2 - 1; s = (const wchar_t *)p; isPtrName = true; } } if (!s) #endif { prop.Clear(); RINOK(arc.Archive->GetProperty(i, kpidPath, &prop)); if (prop.vt == VT_BSTR) { s = prop.bstrVal; len = ::SysStringLen(prop.bstrVal); } else if (prop.vt != VT_EMPTY) return E_FAIL; if (len == 0) { RINOK(arc.GetDefaultItemPath(i, path)); len = path.Len(); s = path; } /* RINOK(arc.GetItemPath(i, path)); len = path.Len(); s = path; */ } unsigned curItem = 0; /* if (arc.Ask_Deleted) { bool isDeleted = false; RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)); if (isDeleted) curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]"); } */ unsigned namePos = 0; for (unsigned j = 0; j < len; j++) { wchar_t c = s[j]; if (c == WCHAR_PATH_SEPARATOR || c == L'/') { name.SetFrom(s + namePos, j - namePos); curItem = AddDir(curItem, -1, name); namePos = j + 1; } } /* that code must be implemeted to hide alt streams in list. if (arc.Ask_AltStreams) { bool isAltStream; RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); if (isAltStream) { } } */ bool isDir; RINOK(Archive_IsItem_Dir(archive, i, isDir)); CProxyFile &f = Files[i]; f.NameLen = len - namePos; s += namePos; if (isPtrName) f.Name = s; else { f.Name = new wchar_t[f.NameLen + 1]; f.NeedDeleteName = true; MyStringCopy((wchar_t *)f.Name, s); } if (isDir) { name = s; AddDir(curItem, (int)i, name); } else Dirs[curItem].SubFiles.Add(i); } CalculateSizes(0, archive); // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s); return S_OK; }
HRESULT CFieldPrinter::PrintItemInfo(const CArc &arc, UInt32 index, bool techMode) { /* if (techMode) { g_StdOut << "Index = "; g_StdOut << (UInt64)index; g_StdOut << endl; } */ for (int i = 0; i < _fields.Size(); i++) { const CFieldInfo &fieldInfo = _fields[i]; if (!techMode) PrintSpaces(fieldInfo.PrefixSpacesWidth); NCOM::CPropVariant prop; if (fieldInfo.PropID == kpidPath) { UString s; RINOK(arc.GetItemPath(index, s)); prop = s; } else { RINOK(arc.Archive->GetProperty(index, fieldInfo.PropID, &prop)); } if (techMode) { g_StdOut << fieldInfo.Name << " = "; } int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width; if (fieldInfo.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) { UInt32 attrib = (prop.vt == VT_EMPTY) ? 0 : prop.ulVal; bool isFolder; RINOK(IsArchiveItemFolder(arc.Archive, index, isFolder)); char s[8]; GetAttribString(attrib, isFolder, s); g_StdOut << s; } else if (prop.vt == VT_EMPTY) { if (!techMode) PrintSpaces(width); } else if (fieldInfo.PropID == kpidMTime) { PrintTime(prop); } else if (prop.vt == VT_BSTR) { if (techMode) g_StdOut << prop.bstrVal; else PrintString(fieldInfo.TextAdjustment, width, prop.bstrVal); } else { UString s = ConvertPropertyToString(prop, fieldInfo.PropID); s.Replace(wchar_t(0xA), L' '); s.Replace(wchar_t(0xD), L' '); if (techMode) g_StdOut << s; else PrintString(fieldInfo.TextAdjustment, width, s); } if (techMode) g_StdOut << endl; } return S_OK; }
HRESULT CArchiveLink::Open( CCodecs *codecs, const CIntVector &formatIndices, bool stdInMode, IInStream *stream, const UString &filePath, IArchiveOpenCallback *callback) { Release(); if (formatIndices.Size() >= 32) return E_NOTIMPL; HRESULT resSpec; for (;;) { resSpec = S_OK; int formatIndex = -1; if (formatIndices.Size() >= 1) { if (Arcs.Size() >= formatIndices.Size()) break; formatIndex = formatIndices[formatIndices.Size() - Arcs.Size() - 1]; } else if (Arcs.Size() >= 32) break; if (Arcs.IsEmpty()) { CArc arc; arc.Path = filePath; arc.SubfileIndex = (UInt32)(Int32)-1; RINOK(arc.OpenStreamOrFile(codecs, formatIndex, stdInMode, stream, callback)); Arcs.Add(arc); continue; } const CArc &arc = Arcs.Back(); resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL); UInt32 mainSubfile; { NCOM::CPropVariant prop; RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)); if (prop.vt == VT_UI4) mainSubfile = prop.ulVal; else break; UInt32 numItems; RINOK(arc.Archive->GetNumberOfItems(&numItems)); if (mainSubfile >= numItems) break; } CMyComPtr<IInArchiveGetStream> getStream; if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) break; CMyComPtr<ISequentialInStream> subSeqStream; if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) break; CMyComPtr<IInStream> subStream; if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream) break; CArc arc2; RINOK(arc.GetItemPath(mainSubfile, arc2.Path)); CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName; callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); if (setSubArchiveName) setSubArchiveName->SetSubArchiveName(arc2.Path); arc2.SubfileIndex = mainSubfile; HRESULT result = arc2.OpenStream(codecs, formatIndex, subStream, NULL, callback); resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE); if (result == S_FALSE) break; RINOK(result); RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined)); Arcs.Add(arc2); } IsOpen = !Arcs.IsEmpty(); return S_OK; }
bool CCurve::CheckForArc(const CVertex& prev_vt, std::list<const CVertex*>& might_be_an_arc, CArc &arc_returned) { // this examines the vertices in might_be_an_arc // if they do fit an arc, set arc to be the arc that they fit and return true // returns true, if arc added if(might_be_an_arc.size() < 2)return false; // find middle point std::size_t num = might_be_an_arc.size(); std::size_t i = 0; const CVertex* mid_vt = NULL; std::size_t mid_i = (num-1)/2; for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++, i++) { if(i == mid_i) { mid_vt = *It; break; } } // create a circle to test Point p0(prev_vt.m_p); Point p1(mid_vt->m_p); Point p2(might_be_an_arc.back()->m_p); Circle c(p0, p1, p2); const CVertex* current_vt = &prev_vt; double accuracy = CArea::m_accuracy * 1.4 / CArea::m_units; for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++) { const CVertex* vt = *It; if(!c.LineIsOn(current_vt->m_p, vt->m_p, accuracy)) return false; current_vt = vt; } CArc arc; arc.m_c = c.m_c; arc.m_s = prev_vt.m_p; arc.m_e = might_be_an_arc.back()->m_p; arc.SetDirWithPoint(might_be_an_arc.front()->m_p); arc.m_user_data = might_be_an_arc.back()->m_user_data; double angs = atan2(arc.m_s.y - arc.m_c.y, arc.m_s.x - arc.m_c.x); double ange = atan2(arc.m_e.y - arc.m_c.y, arc.m_e.x - arc.m_c.x); if(arc.m_dir) { // make sure ange > angs if(ange < angs)ange += 6.2831853071795864; } else { // make sure angs > ange if(angs < ange)angs += 6.2831853071795864; } if(arc.IncludedAngle() >= 3.15)return false; // We don't want full arcs, so limit to about 180 degrees for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++) { const CVertex* vt = *It; double angp = atan2(vt->m_p.y - arc.m_c.y, vt->m_p.x - arc.m_c.x); if(arc.m_dir) { // make sure angp > angs if(angp < angs)angp += 6.2831853071795864; if(angp > ange)return false; } else { // make sure angp > ange if(angp < ange)angp += 6.2831853071795864; if(angp > angs)return false; } } arc_returned = arc; return true; }
CElem* CXMLVecLS::LoadElem(CXmlNode &node) { CString str; int nType = GetType(node.GetName()); CPointF pt; CRectF rc; CElem *elem = NULL; switch (nType) { case CElem::Line: { CLine *pElem = new CLine(); TEST_FREE_RETURNNULL(!LoadNonFillVecElem(pElem,node),pElem); pt.x = node.GetFloatAttrib(_T("StartPointX")); pt.y = node.GetFloatAttrib(_T("StartPointY")); pElem->SetStartPoint(pt); pt.x = node.GetFloatAttrib(_T("EndPointX")); pt.y = node.GetFloatAttrib(_T("EndPointY")); pElem->SetEndPoint(pt); elem = pElem; } break; case CElem::Bezier: { CBezier *pElem = new CBezier(); TEST_FREE_RETURNNULL(!LoadNonFillVecElem(pElem,node),pElem); CXmlNode n; CPointF pt; CFPoints pts; for (int i=0,cnt=node.ChildCount; i<cnt; ++i) { n = node.Child[i]; if (n.GetName() == _T("Point")) { pt.x = n.GetFloatAttrib(_T("X")); pt.y = n.GetFloatAttrib(_T("Y")); pts.Add(pt); } } pElem->SetPoints(pts); elem = pElem; } break; case CElem::FreeLine: { CFreeLine *pElem = new CFreeLine(); TEST_FREE_RETURNNULL(!LoadNonFillVecElem(pElem,node),pElem); CXmlNode n; CPointF pt; CFPoints pts; for (int i=0,cnt=node.ChildCount; i<cnt; ++i) { n = node.Child[i]; if (n.GetName() == _T("Point")) { pt.x = n.GetFloatAttrib(_T("X")); pt.y = n.GetFloatAttrib(_T("Y")); pts.Add(pt); } } pElem->SetPoints(pts); elem = pElem; } break; case CElem::Arc: { CArc *pElem = new CArc(); TEST_FREE_RETURNNULL(!LoadNonFillVecElem(pElem,node),pElem); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); pElem->SetStartAngel(node.GetFloatAttrib(_T("StartAngel"))); pElem->SetEndAngel(node.GetFloatAttrib(_T("EndAngel"))); elem = pElem; } break; case CElem::Chord: { CChord *pElem = new CChord(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); pElem->SetStartAngel(node.GetFloatAttrib(_T("StartAngel"))); pElem->SetEndAngel(node.GetFloatAttrib(_T("EndAngel"))); elem = pElem; } break; case CElem::Pie: { CPie *pElem = new CPie(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); pElem->SetStartAngel(node.GetFloatAttrib(_T("StartAngel"))); pElem->SetEndAngel(node.GetFloatAttrib(_T("EndAngel"))); elem = pElem; } break; case CElem::Poly: { CPoly *pElem = new CPoly(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); CXmlNode n; CPointF pt; CFPoints pts; for (int i=0,cnt=node.ChildCount; i<cnt; ++i) { n = node.Child[i]; if (n.GetName() == _T("Point")) { pt.x = n.GetFloatAttrib(_T("X")); pt.y = n.GetFloatAttrib(_T("Y")); pts.Add(pt); } } pElem->SetPoints(pts); elem = pElem; } break; case CElem::Region: { CRegion *pElem = new CRegion(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); CXmlNode n; CPointF pt; CFPoints pts; for (int i=0,cnt=node.ChildCount; i<cnt; ++i) { n = node.Child[i]; if (n.GetName() == _T("Point")) { pt.x = n.GetFloatAttrib(_T("X")); pt.y = n.GetFloatAttrib(_T("Y")); pts.Add(pt); } } pElem->SetPoints(pts); elem = pElem; } break; case CElem::Rectangle: { CRectangle *pElem = new CRectangle(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); pElem->SetText(node.GetStringAttrib(_T("Text"))); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); elem = pElem; } break; case CElem::RoundRect: { CRoundRect *pElem = new CRoundRect(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); pElem->SetXEllipse(node.GetFloatAttrib(_T("XEllipse"))); pElem->SetYEllipse(node.GetFloatAttrib(_T("YEllipse"))); elem = pElem; } break; case CElem::Ellipse: { CEllipse *pElem = new CEllipse(); TEST_FREE_RETURNNULL(!LoadFilledVecElem(pElem,node),pElem); rc.left = node.GetFloatAttrib(_T("RectLeft")); rc.top = node.GetFloatAttrib(_T("RectTop")); rc.right = node.GetFloatAttrib(_T("RectRight")); rc.bottom = node.GetFloatAttrib(_T("RectBottom")); pElem->SetBoundsRect(rc); elem = pElem;; } break; default: ASSERT(FALSE); return NULL; } if (elem != NULL) { elem->SetCustomData(node.GetBigUIntAttrib(_T("CustomData"))); elem->SetDesc(node.GetStringAttrib(_T("Desc"))); //elem->SetText(node.GetStringAttrib(_T("Text"))); //elem->SetTextColor(node.GetUIntAttrib(_T("TextColor"))); } return elem; }
HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress) { RootFolder.Clear(); IInArchive *archive = arc.Archive; { ThereIsPathProp = false; UInt32 numProps; archive->GetNumberOfProperties(&numProps); for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE varType; RINOK(archive->GetPropertyInfo(i, &name, &propID, &varType)); if (propID == kpidPath) { ThereIsPathProp = true; break; } } } UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); if (progress != NULL) { UInt64 totalItems = numItems; RINOK(progress->SetTotal(totalItems)); } UString fileName; for (UInt32 i = 0; i < numItems; i++) { if (progress != NULL && (i & 0xFFFFF) == 0) { UInt64 currentItemIndex = i; RINOK(progress->SetCompleted(¤tItemIndex)); } UString filePath; RINOK(arc.GetItemPath(i, filePath)); CProxyFolder *curItem = &RootFolder; int len = filePath.Length(); fileName.Empty(); for (int j = 0; j < len; j++) { wchar_t c = filePath[j]; if (c == WCHAR_PATH_SEPARATOR || c == L'/') { curItem = curItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName); fileName.Empty(); } else fileName += c; } bool isFolder; RINOK(IsArchiveItemFolder(archive, i, isFolder)); if (isFolder) curItem->AddDirSubItem(i, true, fileName); else curItem->AddFileSubItem(i, fileName); } RootFolder.CalculateSizes(archive); return S_OK; }
static HRESULT DecompressArchive( const CArc &arc, UInt64 packSize, const NWildcard::CCensorNode &wildcardCensor, const CExtractOptions &options, IExtractCallbackUI *callback, CArchiveExtractCallback *extractCallbackSpec, UString &errorMessage, UInt64 &stdInProcessed) { stdInProcessed = 0; IInArchive *archive = arc.Archive; CRecordVector<UInt32> realIndices; if (!options.StdInMode) { UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); for (UInt32 i = 0; i < numItems; i++) { UString filePath; RINOK(arc.GetItemPath(i, filePath)); bool isFolder; RINOK(IsArchiveItemFolder(archive, i, isFolder)); if (!wildcardCensor.CheckPath(filePath, !isFolder)) continue; realIndices.Add(i); } if (realIndices.Size() == 0) { callback->ThereAreNoFiles(); return S_OK; } } UStringVector removePathParts; UString outDir = options.OutputDir; outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName)); #ifdef _WIN32 // GetCorrectFullFsPath doesn't like "..". // outDir.TrimRight(); // outDir = GetCorrectFullFsPath(outDir); #endif if (!outDir.IsEmpty()) if (!NFile::NDirectory::CreateComplexDirectory(outDir)) { HRESULT res = ::GetLastError(); if (res == S_OK) res = E_FAIL; errorMessage = ((UString)L"Can not create output directory ") + outDir; return res; } extractCallbackSpec->Init( options.StdInMode ? &wildcardCensor : NULL, &arc, callback, options.StdOutMode, options.TestMode, options.CalcCrc, outDir, removePathParts, packSize); #if !defined(_7ZIP_ST) && !defined(_SFX) RINOK(SetProperties(archive, options.Properties)); #endif HRESULT result; Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0; if (options.StdInMode) { result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec); NCOM::CPropVariant prop; if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK) if (prop.vt == VT_UI8 || prop.vt == VT_UI4) stdInProcessed = ConvertPropVariantToUInt64(prop); } else result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec); return callback->ExtractResult(result); }