1 /* 2 * PROJECT: ReactOS Zip Shell Extension 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: CZipEnumerator 5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 struct CZipEnumerator 9 { 10 private: 11 CComPtr<IZip> m_Zip; 12 bool m_First; 13 CAtlList<CStringA> m_Returned; 14 public: 15 CZipEnumerator() 16 :m_First(true) 17 { 18 } 19 20 bool initialize(IZip* zip) 21 { 22 m_Zip = zip; 23 return reset(); 24 } 25 26 bool reset() 27 { 28 unzFile uf = m_Zip->getZip(); 29 m_First = true; 30 if (unzGoToFirstFile(uf) != UNZ_OK) 31 return false; 32 m_Returned.RemoveAll(); 33 return true; 34 } 35 36 bool next_unique(const char* prefix, CStringA& name, bool& folder, unz_file_info64& info) 37 { 38 size_t len = strlen(prefix); 39 CStringA tmp; 40 while (next(tmp, info)) 41 { 42 if (!_strnicmp(tmp, prefix, len)) 43 { 44 int pos = tmp.Find('/', len); 45 if (pos < 0) 46 { 47 name = tmp.Mid(len); 48 folder = false; 49 } 50 else 51 { 52 name = tmp.Mid(len, pos - len); 53 folder = true; 54 } 55 tmp = name.MakeLower(); 56 57 POSITION it = m_Returned.Find(tmp); 58 if (!name.IsEmpty() && !it) 59 { 60 m_Returned.AddTail(tmp); 61 return true; 62 } 63 } 64 } 65 return false; 66 } 67 68 bool next(CStringA& name, unz_file_info64& info) 69 { 70 int err; 71 72 unzFile uf = m_Zip->getZip(); 73 if (!m_First) 74 { 75 err = unzGoToNextFile(uf); 76 if (err == UNZ_END_OF_LIST_OF_FILE) 77 { 78 return false; 79 } 80 } 81 m_First = false; 82 83 err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0); 84 if (err == UNZ_OK) 85 { 86 PSTR buf = name.GetBuffer(info.size_filename); 87 err = unzGetCurrentFileInfo64(uf, NULL, buf, name.GetAllocLength(), NULL, 0, NULL, 0); 88 name.ReleaseBuffer(info.size_filename); 89 name.Replace('\\', '/'); 90 } 91 return err == UNZ_OK; 92 } 93 }; 94 95