1 /*
2 * Copyright 2008 Netallied Systems GmbH.
3 *
4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
5 * http://www.opensource.org/licenses/mit-license.php
6 *
7 */
8 
9 #ifndef __DAE_ZAE_UNCOMPRESS_HANDLER_H__
10 #define __DAE_ZAE_UNCOMPRESS_HANDLER_H__
11 
12 #include <unzip.h>
13 #include <libxml/xmlreader.h>
14 #include <dae/daeURI.h>
15 
16 /**
17  * Takes an URI to a ZAE file and extracts it to a temporary directory.
18  * Use obtainRootFilePath() to accomplish this.
19  *
20  * The whole ZAE archive gets extracted because it is not specified
21  * how an URL pointing inside a ZAE archive should look like.
22  * By extracting the whole archive we can use the 'file' scheme.
23  */
24 class DLLSPEC daeZAEUncompressHandler
25 {
26 private:
27     // zip file this object operates on.
28     unzFile mZipFile;
29 
30     // URI th zip file this object operates on.
31     const daeURI& mZipFileURI;
32 
33     // indicates if the passed URI is a valid zip file.
34     bool mValidZipFile;
35 
36     // path to root file in archive this object handles.
37     std::string mRootFilePath;
38 
39     // tmp dir where this archive is extracted.
40     std::string mTmpDir;
41 
42     // disable copy c-tor and assignment operator.
43     daeZAEUncompressHandler(const daeZAEUncompressHandler& copy);
44     daeZAEUncompressHandler& operator=(const daeZAEUncompressHandler& copy);
45 
46 public:
47     // Name of manifest file inside ZAE.
48     static const std::string MANIFEST_FILE_NAME;
49     // Root xml element inside manifest file.
50     static const std::string MANIFEST_FILE_ROOT_ELEMENT_NAME;
51     // Case insensitivity constant from minizip.
52     static const int CASE_INSENSITIVE;
53     // Buffer size for extracting files from zip archive.
54     static const int BUFFER_SIZE;
55     // Empty string to be returned in case of error.
56     static const std::string EMPTY_STRING;
57 
58     /**
59      * C-Tor.
60      * @param zaeFile URI to the ZAE file to open.
61      */
62     daeZAEUncompressHandler(const daeURI& zaeFile);
63 
64     /**
65      * D-Tor.
66      */
67     virtual ~daeZAEUncompressHandler();
68 
69     /**
70      * Returns true if this object has been initialized
71      * with a zip file.
72      */
isZipFile()73     bool isZipFile() {return mValidZipFile;}
74 
75     /**
76      * Extracts ZAE file and returns resulting path to the root DAE file.
77      */
78     const std::string& obtainRootFilePath();
79 
80     /**
81      * Returns currently known path to root DAE of ZAE file.
82      * Only valid after obtainRootFilePath() has been called.
83      */
getRootFilePath()84     const std::string& getRootFilePath() {return mRootFilePath;}
85 
86     /**
87      * Returns used temp dir.
88      */
getTmpDir()89     const std::string& getTmpDir() {return mTmpDir;}
90 
91 private:
92     /**
93      * Tries to open manifest.xml inside tmpDir. On success
94      * it parses the XML file to find URI of root DAE.
95      */
96     bool retrieveRootURIFromManifest(const std::string& tmpDir);
97 
98     /**
99      * Iterates over zip archive and extracts each file.
100      */
101     bool extractArchive(unzFile zipFile, const std::string& destDir);
102 
103     /**
104      * Extracts the current file inside zip archive.
105      */
106     bool extractFile(unzFile zipFile, const std::string& destDir);
107 
108     /**
109      * Finds <dae_root> element in manifest.xml. Used by retrieveRootURIFromManifest().
110      */
111     bool findManifestRootElement(xmlTextReaderPtr xmlReader);
112 
113     /**
114      * Checks if an extracted file is a zip archive itself and extracts it.
115      */
116     bool checkAndExtractInternalArchive(const std::string& filePath);
117 };
118 
119 #endif //__DAE_ZAE_UNCOMPRESS_HANDLER_H__
120