[DEV] first dev for archive access

This commit is contained in:
Edouard DUPIN 2013-07-24 07:42:25 +02:00
parent 61bd6002d0
commit 273a1ba41b
7 changed files with 266 additions and 2 deletions

View File

@ -81,7 +81,7 @@ namespace etk
* @param[in] _key Name of the hash requested * @param[in] _key Name of the hash requested
* @return true if the element exist * @return true if the element exist
*/ */
bool Exist(const etk::UString& _name) bool Exist(const etk::UString& _name) const
{ {
int64_t elementId = GetId(_name); int64_t elementId = GetId(_name);
if (elementId<0) { if (elementId<0) {

47
etk/archive/Archive.cpp Normal file
View File

@ -0,0 +1,47 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/archive/Archive.h>
#include <etk/archive/Zip.h>
#include <etk/DebugInternal.h>
const etk::Archive::Content& etk::Archive::GetContent(const etk::UString& _key) const
{
static const etk::Archive::Content g_error;
if (m_content.Exist(_key)==false) {
TK_ERROR("File does not exist : " << _key);
return g_error;
}
return m_content[_key];
}
void etk::Archive::Display(void)
{
for (esize_t iii=0; iii<m_content.Size(); iii++) {
esize_t size = m_content.GetValue(iii).Size();
TK_INFO(" element : " << m_content.GetKey(iii) << " size=" << size);
}
}
etk::Archive* etk::Archive::Load(const etk::UString& _fileName)
{
etk::Archive::Archive* output=NULL;
etk::UString tmpName = _fileName.ToLower();
// select the corect Loader :
if (true == tmpName.EndWith(".zip") ) {
output = new etk::archive::Zip(_fileName);
if (NULL==output) {
TK_ERROR("An error occured when load archive : " << _fileName);
}
} else {
TK_ERROR("Extention not managed " << _fileName << " Sopported extention : .zip");
}
return output;
}

89
etk/archive/Archive.h Normal file
View File

@ -0,0 +1,89 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __ETK_ARCHIVE_H__
#define __ETK_ARCHIVE_H__
#include <etk/UString.h>
#include <etk/Vector.h>
#include <etk/Hach.h>
namespace etk
{
class Archive
{
public:
class Content
{
private:
etk::Vector<char> m_data; // if null ==> this is a folder...
public:
Content(esize_t _basicSize=0) : m_data(_basicSize) { };
esize_t Size(void) const { return m_data.Size(); };
void* Data(void) { return (void*)m_data.DataPointer(); };
etk::Vector<char>& GetDataVector(void) { return m_data; };
};
public:
Archive(const etk::UString& _fileName) : m_fileName(_fileName) { };
virtual ~Archive(void) { };
protected:
etk::UString m_fileName; //!< File name when it came from an file
public:
/**
* @brief Get the current file name.
* @return the requested file name.
*/
const etk::UString& GetFileName(void) { return m_fileName; };
protected:
etk::Hash<Content> m_content;
public:
/**
* @brief Get the number of elements
* @return nb files in the archive
*/
esize_t Size(void) const { return m_content.Size(); };
/**
* @brief Get the File name of the ID
* @param[in] _id id of the element (must be < Size())
* @return FileName of the requested id
*/
const etk::UString& GetName(esize_t _id) const { return m_content.GetKey(_id); };
/**
* @brief Get the File name of the ID
* @param[in] _id id of the element (must be < Size())
* @return the archive content
*/
const Content& GetContent(esize_t _id) const { return m_content.GetValue(_id); };
/**
* @brief Get the File name of the ID
* @param[in] _key name of the file
* @return FileName of the requested id
*/
const Content& GetContent(const etk::UString& _key) const;
/**
* @brief Display all Element in the archive
*/
void Display(void);
public:
/**
* @brief Load an Achive with a specific name.
* @param[in] _fileName File name of the specific archive.
* @return A pointer an the specified archive, the user might delete it.
*/
static Archive* Load(const etk::UString& _fileName);
/**
* @brief Create an Achive with a specific name.
* @param[in] _fileName File name of the specific archive.
* @return A pointer an the specified archive. it is empty due to the fact of create a new archive file.
*/
//Archive* Create(const etk::UString& _fileName);
};
};
#endif

80
etk/archive/Zip.cpp Normal file
View File

@ -0,0 +1,80 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <etk/archive/Zip.h>
#include <etk/DebugInternal.h>
etk::archive::Zip::Zip(const etk::UString& _fileName) :
etk::Archive(_fileName),
m_ctx(NULL)
{
/* Open the zip file */
m_ctx = unzOpen(m_fileName.c_str());
if(!m_ctx) {
TK_ERROR("Unable to open the zip file '" << m_fileName << "'");
return;
}
/* Get info about the zip file */
if(unzGetGlobalInfo(m_ctx, &m_info) != UNZ_OK) {
TK_ERROR("Unable to read the global info related to the '" << m_fileName << "' zip file");
return;
}
// Store all the file in the standard structure
for(int32_t iii=0; iii<m_info.number_entry; iii++) {
char tmpFileName[FILENAME_MAX];
unz_file_info tmpFileInfo;
/* Get info about current file. */
if(unzGetCurrentFileInfo(m_ctx, &tmpFileInfo, tmpFileName, FILENAME_MAX, NULL, 0, NULL, 0) != UNZ_OK) {
TK_ERROR("Could not read file info from the zip file '" << m_fileName << "'");
return;
}
if(tmpFileName[strlen(tmpFileName) - 1] == '/' ) {
// find directory ...
} else {
// Entry is a file, so extract it.
if(unzOpenCurrentFile(m_ctx) != UNZ_OK) {
TK_ERROR("Could not open file '" << tmpFileName << "' into the zip file '" << m_fileName << "'");
return;
}
int error = UNZ_OK;
m_content.Add(tmpFileName, etk::Archive::Content(tmpFileInfo.uncompressed_size));
void* data = m_content[tmpFileName].Data();
if(NULL == data) {
TK_ERROR("Allocation error...");
return;
}
/* read the file */
do {
error = unzReadCurrentFile(m_ctx, data, tmpFileInfo.uncompressed_size);
if ( error < 0 ) {
TK_ERROR("Could not read file '" << tmpFileName << "' into the zip file '" << m_fileName << "': " << error);
unzCloseCurrentFile(m_ctx);
return;
}
} while ( error > 0 );
}
unzCloseCurrentFile(m_ctx);
/* Go the the next entry listed in the zip file. */
if((iii+1) < m_info.number_entry) {
if (unzGoToNextFile(m_ctx) != UNZ_OK) {
TK_ERROR("Could not read next file from the zip file '" << m_fileName << "'");
return;
}
}
}
}
etk::archive::Zip::~Zip(void)
{
if (m_ctx!= NULL) {
unzClose(m_ctx);
m_ctx = NULL;
};
};

32
etk/archive/Zip.h Normal file
View File

@ -0,0 +1,32 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#ifndef __ETK_ARCHIVE_ZIP_H__
#define __ETK_ARCHIVE_ZIP_H__
#include <etk/archive/Archive.h>
#include <minizip/unzip.h>
namespace etk
{
namespace archive
{
class Zip : public etk::Archive
{
private:
unzFile m_ctx; //!< mini zip context
unz_global_info m_info; //!< global information of the Zip
public:
Zip(const etk::UString& _fileName);
virtual ~Zip(void);
};
};
};
#endif

View File

@ -25,7 +25,9 @@ def Create(target):
'etk/math/Vector3D.cpp', 'etk/math/Vector3D.cpp',
'etk/os/FSNode.cpp', 'etk/os/FSNode.cpp',
'etk/os/FSNodeRight.cpp', 'etk/os/FSNodeRight.cpp',
'etk/os/Memory.cpp']) 'etk/os/Memory.cpp',
'etk/archive/Archive.cpp',
'etk/archive/Zip.cpp'])
if target.name=="Windows": if target.name=="Windows":
myModule.AddSrcFile('etk/os/Mutex.Windows.cpp') myModule.AddSrcFile('etk/os/Mutex.Windows.cpp')
@ -36,6 +38,8 @@ def Create(target):
# name of the dependency # name of the dependency
myModule.AddModuleDepend('linearmath') myModule.AddModuleDepend('linearmath')
myModule.AddModuleDepend('minizip')
if target.name=="Android": if target.name=="Android":
myModule.AddModuleDepend('zip') myModule.AddModuleDepend('zip')

View File

@ -12,6 +12,7 @@
#include <etk/Hach.h> #include <etk/Hach.h>
#include <etk/os/FSNode.h> #include <etk/os/FSNode.h>
#include <etk/DebugInternal.h> #include <etk/DebugInternal.h>
#include <etk/archive/Archive.h>
#undef __class__ #undef __class__
#define __class__ "etktest" #define __class__ "etktest"
@ -117,6 +118,16 @@ void testFSNode(void)
TK_INFO("==> Stop test of FSNode"); TK_INFO("==> Stop test of FSNode");
} }
void testArchive(void)
{
TK_INFO("==> Start test of archive");
etk::Archive* tmpArchive = etk::Archive::Load("testzip.zip");
tmpArchive->Display();
TK_INFO("==> End test of archive");
}
/* /*
void testDimension(void) void testDimension(void)
{ {
@ -147,6 +158,7 @@ int main(int argc, const char *argv[])
testHash(); testHash();
//testFSNode(); //testFSNode();
//testDimension(); //testDimension();
testArchive();
return 0; return 0;
} }