[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / filesystem / ZipDirectory.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "ZipDirectory.h"
22 #include "utils/log.h"
23 #include "utils/CharsetConverter.h"
24 #include "utils/URIUtils.h"
25 #include "Util.h"
26 #include "URL.h"
27 #include "ZipManager.h"
28 #include "FileItem.h"
29
30 #include <vector>
31
32 using namespace std;
33 namespace XFILE
34 {
35   CZipDirectory::CZipDirectory()
36   {
37   }
38
39   CZipDirectory::~CZipDirectory()
40   {
41   }
42
43   bool CZipDirectory::GetDirectory(const CStdString& strPathOrig, CFileItemList& items)
44   {
45     CStdString strPath;
46
47     /* if this isn't a proper archive path, assume it's the path to a archive file */
48     if( !strPathOrig.Left(6).Equals("zip://") )
49       URIUtils::CreateArchivePath(strPath, "zip", strPathOrig, "");
50     else
51       strPath = strPathOrig;
52
53     CURL url(strPath);
54
55     CStdString strArchive = url.GetHostName();
56     CStdString strOptions = url.GetOptions();
57     CStdString strPathInZip = url.GetFileName();
58
59     url.SetOptions(""); // delete options to have a clean path to add stuff too
60     url.SetFileName(""); // delete filename too as our names later will contain it
61
62     CStdString strSlashPath = url.Get();
63
64     CStdString strBuffer;
65
66     // the RAR code depends on things having a "/" at the end of the path
67     URIUtils::AddSlashAtEnd(strSlashPath);
68
69     vector<SZipEntry> entries;
70     // turn on fast lookups
71     bool bWasFast(items.GetFastLookup());
72     items.SetFastLookup(true);
73     if (!g_ZipManager.GetZipList(strPath,entries))
74       return false;
75
76     vector<CStdString> baseTokens;
77     if (!strPathInZip.IsEmpty())
78       CUtil::Tokenize(strPathInZip,baseTokens,"/");
79
80     for (vector<SZipEntry>::iterator ze=entries.begin();ze!=entries.end();++ze)
81     {
82       CStdString strEntryName(ze->name);
83       strEntryName.Replace('\\','/');
84       if (strEntryName == strPathInZip) // skip the listed dir
85         continue;
86
87       vector<CStdString> pathTokens;
88       CUtil::Tokenize(strEntryName,pathTokens,"/");
89       if (pathTokens.size() < baseTokens.size()+1)
90         continue;
91
92       bool bAdd=true;
93       strEntryName = "";
94       for ( unsigned int i=0;i<baseTokens.size();++i )
95       {
96         if (pathTokens[i] != baseTokens[i])
97         {
98           bAdd = false;
99           break;
100         }
101         strEntryName += pathTokens[i] + "/";
102       }
103       if (!bAdd)
104         continue;
105
106       strEntryName += pathTokens[baseTokens.size()];
107       char c=ze->name[strEntryName.size()];
108       if (c == '/' || c == '\\')
109         strEntryName += '/';
110       bool bIsFolder = false;
111       if (strEntryName[strEntryName.size()-1] != '/') // this is a file
112       {
113         strBuffer = strSlashPath + strEntryName + strOptions;
114       }
115       else
116       { // this is new folder. add if not already added
117         bIsFolder = true;
118         strBuffer = strSlashPath + strEntryName + strOptions;
119         if (items.Contains(strBuffer)) // already added
120           continue;
121       }
122
123       CFileItemPtr pFileItem(new CFileItem);
124
125       if (g_charsetConverter.isValidUtf8(pathTokens[baseTokens.size()]))
126         g_charsetConverter.utf8ToStringCharset(pathTokens[baseTokens.size()]);
127
128       pFileItem->SetLabel(pathTokens[baseTokens.size()]);
129       if (bIsFolder)
130       {
131         pFileItem->m_dwSize = 0;
132         URIUtils::AddSlashAtEnd(strBuffer);
133       }
134       else
135         pFileItem->m_dwSize = ze->usize;
136       pFileItem->SetPath(strBuffer);
137       pFileItem->m_bIsFolder = bIsFolder;
138       pFileItem->m_idepth = ze->method;
139       items.Add(pFileItem);
140     }
141     items.SetFastLookup(bWasFast);
142     return true;
143   }
144
145   bool CZipDirectory::ContainsFiles(const CStdString& strPath)
146   {
147     vector<SZipEntry> items;
148     g_ZipManager.GetZipList(strPath,items);
149     if (items.size())
150     {
151       if (items.size() > 1)
152         return true;
153
154       return false;
155     }
156
157     return false;
158   }
159 }
160