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; 56 tmp.MakeLower(); 57 58 POSITION it = m_Returned.Find(tmp); 59 if (!name.IsEmpty() && !it) 60 { 61 m_Returned.AddTail(tmp); 62 return true; 63 } 64 } 65 } 66 return false; 67 } 68 69 bool next(CStringA& name, unz_file_info64& info) 70 { 71 int err; 72 73 unzFile uf = m_Zip->getZip(); 74 if (!m_First) 75 { 76 err = unzGoToNextFile(uf); 77 if (err == UNZ_END_OF_LIST_OF_FILE) 78 { 79 return false; 80 } 81 } 82 m_First = false; 83 84 err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0); 85 if (err == UNZ_OK) 86 { 87 PSTR buf = name.GetBuffer(info.size_filename); 88 err = unzGetCurrentFileInfo64(uf, NULL, buf, name.GetAllocLength(), NULL, 0, NULL, 0); 89 name.ReleaseBuffer(info.size_filename); 90 name.Replace('\\', '/'); 91 } 92 return err == UNZ_OK; 93 } 94 }; 95 96