2 * Copyright (C) 2012-2013 Team XBMC
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)
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.
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/>.
21 #include "APKDirectory.h"
24 #include "utils/CharsetConverter.h"
25 #include "utils/log.h"
26 #include "utils/StringUtils.h"
27 #include "utils/URIUtils.h"
31 using namespace XFILE
;
33 // Android apk directory i/o. Depends on libzip
34 // Basically the same format as zip.
35 // We might want to refactor CZipDirectory someday...
36 //////////////////////////////////////////////////////////////////////
37 bool CAPKDirectory::GetDirectory(const CStdString
& strPath
, CFileItemList
&items
)
39 // uses a <fully qualified path>/filename.apk/...
42 CStdString path
= url
.GetFileName();
43 CStdString host
= url
.GetHostName();
44 URIUtils::AddSlashAtEnd(path
);
46 int zip_flags
= 0, zip_error
= 0;
47 struct zip
*zip_archive
;
48 zip_archive
= zip_open(host
.c_str(), zip_flags
, &zip_error
);
49 if (!zip_archive
|| zip_error
)
51 CLog::Log(LOGERROR
, "CAPKDirectory::GetDirectory: Unable to open archive : '%s'",
57 int numFiles
= zip_get_num_files(zip_archive
);
58 for (int zip_index
= 0; zip_index
< numFiles
; zip_index
++)
60 test_name
= zip_get_name(zip_archive
, zip_index
, zip_flags
);
62 // check for non matching path.
63 if (!StringUtils::StartsWith(test_name
, path
))
66 // libzip does not index folders, only filenames. We search for a /,
67 // add it if it's not in our list already, and hope that no one has
68 // any "file/name.exe" files in a zip.
70 size_t dir_marker
= test_name
.find('/', path
.size() + 1);
71 if (dir_marker
!= std::string::npos
)
73 // return items relative to path
74 test_name
=test_name
.substr(0, dir_marker
);
76 if (items
.Contains(host
+ "/" + test_name
))
82 if (zip_stat_index(zip_archive
, zip_index
, zip_flags
, &sb
) != -1)
84 g_charsetConverter
.unknownToUTF8(test_name
);
85 CFileItemPtr
pItem(new CFileItem(test_name
));
86 pItem
->m_dwSize
= sb
.size
;
87 pItem
->m_dateTime
= sb
.mtime
;
88 pItem
->m_bIsFolder
= dir_marker
> 0 ;
89 pItem
->SetPath(host
+ "/" + test_name
);
90 pItem
->SetLabel(test_name
.substr(path
.size()));
94 zip_close(zip_archive
);
99 bool CAPKDirectory::ContainsFiles(const CStdString
& strPath
)
101 // TODO: why might we need this ?
105 DIR_CACHE_TYPE
CAPKDirectory::GetCacheType(const CStdString
& strPath
) const
107 return DIR_CACHE_ALWAYS
;
110 bool CAPKDirectory::Exists(const char* strPath
)
112 // uses a <fully qualified path>/filename.apk/...
115 return apk
.Exists(url
);