📄 archive.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: archive.cpp,v 1.1.2.1 2004/07/09 02:02:36 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include "hxtypes.h"#include "hxresult.h"#include <stdio.h>#include <io.h>#include <sys/stat.h>#ifdef _WIN32#include <windows.h>#include <direct.h>#else#include <sys/types.h>#endif#include "archive.h"Archiver::Archiver() : m_fTarFile(NULL), m_pReadBuf(NULL){}Archiver::~Archiver(){ HX_VECTOR_DELETE(m_pReadBuf);}HX_RESULTArchiver::Init(FILE* fTarFile){ m_fTarFile = fTarFile; m_pReadBuf = new BYTE[READ_CHUNK_SIZE]; if(!m_pReadBuf) { return HXR_OUTOFMEMORY; } return WriteArchiveHeader();}HX_RESULTArchiver::AddFile(const char* szFileName){ HX_RESULT res = HXR_OK; struct stat fileInfo; if(stat(szFileName, &fileInfo) != 0) { return HXR_FILE_NOT_FOUND; } // Write the header if(strcmp(szFileName, ".") != 0 && strcmp(szFileName, "..") != 0) { res = WriteFileHeader(szFileName, &fileInfo); } if(FAILED(res)) { return res; } if(fileInfo.st_mode & _S_IFDIR) { res = RecurseDirectory(szFileName); } else { res = WriteFileData(szFileName, &fileInfo); } return res;}HX_RESULTArchiver::WriteArchiveHeader(){ size_t unPos; // ID (4 bytes) // Major Version (1) // Minor Version (1) memcpy(m_pReadBuf, HXAR_ID, HXAR_ID_SIZE); unPos = HXAR_ID_SIZE; m_pReadBuf[unPos++] = HXAR_VER_MAJOR; m_pReadBuf[unPos++] = HXAR_VER_MINOR; if(fwrite((void*)m_pReadBuf, 1, HXAR_ARCH_DESC_SIZE, m_fTarFile) != HXAR_ARCH_DESC_SIZE) { return HXR_WRITE_ERROR; } return HXR_OK;}HX_RESULT Archiver::WriteFileHeader(const char* szFileName, struct stat* pFileInfo){ size_t unPos = 0; size_t unLen = strlen(szFileName) + 1; // ID (4 bytes) // File Mode (2) // File Size (8) // File Name + '\0' (variable) memcpy(m_pReadBuf, HXAR_FILE_ID, HXAR_FILE_ID_SIZE); unPos = HXAR_FILE_ID_SIZE; // mode m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_mode >> 8); m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_mode); // File size - upper 32 bits are 0 memset(m_pReadBuf + unPos, 0, 4); unPos += 4; // If it's a directory, set size to 0 if(pFileInfo->st_mode & _S_IFDIR) { memset(m_pReadBuf + unPos, 0, 4); unPos += 4; } // Otherwise, write file size else { m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_size >> 24); m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_size >> 16); m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_size >> 8); m_pReadBuf[unPos++] = (BYTE)(pFileInfo->st_size); } if((fwrite((void*)m_pReadBuf, 1, unPos, m_fTarFile) != unPos) || (fwrite((void*)szFileName, 1, unLen, m_fTarFile) != unLen)) { return HXR_WRITE_ERROR; } return HXR_OK;}HX_RESULTArchiver::WriteFileData(const char* szFileName, struct stat* pFileInfo){ HX_RESULT res = HXR_OK; size_t unReadSize = READ_CHUNK_SIZE; size_t unRead = 0; size_t unWritten = 0; size_t unTotal; FILE* fInFile = fopen(szFileName, "rb"); if(!fInFile) { return HXR_FILE_NOT_FOUND; } // Copy the input file contents to the tar file for(unTotal = 0; unTotal < (size_t)pFileInfo->st_size && SUCCEEDED(res); unTotal += unRead) { if(unTotal + unReadSize > (size_t)pFileInfo->st_size) { unReadSize = pFileInfo->st_size - unTotal; } // Read a chunk unRead = fread((void*)m_pReadBuf, 1, unReadSize, fInFile); if(unRead != unReadSize) { res = HXR_INVALID_FILE; } else { // Write a chunk unWritten = fwrite((void*)m_pReadBuf, 1, unRead, m_fTarFile); if(unWritten != unRead) { res = HXR_WRITE_ERROR; } } } if(fInFile) { fclose(fInFile); } return res;}Dearchiver::Dearchiver() : m_szOutDir(NULL), m_State(STATE_CLOSED), m_pReadBuf(NULL), m_ulSaved(0), m_pSaveBuf(NULL), m_fFile(NULL), m_ulFileSize(0), m_ulMode(0), m_ulWritten(0){}Dearchiver::~Dearchiver(){ Close(); HX_VECTOR_DELETE(m_pReadBuf); HX_VECTOR_DELETE(m_pSaveBuf);}HX_RESULTDearchiver::Init(const char* szOutDir){ struct stat fileInfo; if(szOutDir) { if(stat(szOutDir, &fileInfo) == 0) { if(!(fileInfo.st_mode & _S_IFDIR)) { return HXR_WRITE_ERROR; } } else if(mkdir(szOutDir) != 0) { return HXR_WRITE_ERROR; } } if(!m_pReadBuf) { m_pReadBuf = new BYTE[READ_CHUNK_SIZE]; if(!m_pReadBuf) { return HXR_OUTOFMEMORY; } } if(!m_pSaveBuf) { m_pSaveBuf = new BYTE[DESC_BUF_SIZE]; if(!m_pSaveBuf) { return HXR_OUTOFMEMORY; } } m_szOutDir = szOutDir; m_State = STATE_ARCH_HEADER; return HXR_OK;}HX_RESULTDearchiver::Extract(FILE* fTarFile){ HX_RESULT res = HXR_OK; size_t unReadSize = READ_CHUNK_SIZE; size_t unRead = 0; UINT32 ulExtracted = 0; // untar the file while(!feof(fTarFile) && SUCCEEDED(res)) { // Read a chunk unRead = fread((void*)m_pReadBuf, 1, unReadSize, fTarFile); if(ferror(fTarFile)) { res = HXR_INVALID_FILE; } else { // Write a chunk res = Extract(m_pReadBuf, unRead, ulExtracted); } } return res;}HX_RESULTDearchiver::Extract(BYTE* pArchData, const UINT32 ulSize, UINT32& ulRead){ HX_RESULT res = HXR_OK; UINT32 ulLocalRead = 0; ulRead = 0; while(ulRead < ulSize) { switch (m_State)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -