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