📄 stafzip.cpp
字号:
/*****************************************************************************/
/* Software Testing Automation Framework (STAF) */
/* (C) Copyright IBM Corp. 2004, 2005 */
/* */
/* This software is licensed under the Common Public License (CPL) V1.0. */
/*****************************************************************************/
#include "STAF.h"
#include "STAFString.h"
#include "STAFTrace.h"
#include "STAFMutexSem.h"
#include "STAFCommandParser.h"
#include "STAFServiceInterface.h"
#include "STAFUtil.h"
#include <vector>
#include <map>
#include "zlib.h"
#include "STAFZip.h"
#include "STAFZipUtil.h"
#include "STAFZipFileHeader.h"
#include "STAFZipFileAttribute.h"
#include "STAFZipCentralDirExtension.h"
#include "STAFZipLocalFileHeader.h"
#include "STAFZipCentralDirEndRecord.h"
#include "STAFZipCentralDir.h"
#include "STAFZipFile.h"
#include "STAFZipMutexLock.h"
// STAFZip Service Data
struct STAFZipServiceData
{
unsigned int fDebugMode; // Debug Mode flag
STAFString fShortName; // Short service name
STAFString fName; // Registered service name
STAFString fLocalMachineName; // Logical identifier for the local
// machine
STAFHandlePtr fHandlePtr; // STAFZip service's STAF handle
STAFCommandParserPtr fAddParser; // STAFZip ADD command parser
STAFCommandParserPtr fUnzipParser; // STAFZip UNZIP command parser
STAFCommandParserPtr fListParser; // STAFZip LIST command parser
STAFCommandParserPtr fDeleteParser; // STAFZip DELETE command parser
STAFCommandParserPtr fHelpParser; // STAFZip HELP command parser
STAFCommandParserPtr fVersionParser; // STAFZip VERSION command parser
};
// static STAFZipMutexLock class
static STAFZipMutexLock zipLock;
// Static Variables
static STAFString sLineSep;
static const STAFString sVersionInfo("3.1.1");
// 3.0.0 Original release
// 3.0.1 Bug 1012202: Can't read permission info in the latest InfoZip archive
// 3.0.2 Bug 1033654: Error inflate file
// 3.0.3 Feature 1055682: Improve unzip's performance on large files
// 3.0.4 Bug 1076948: zero bytes when unzipping JAR archives
// 3.0.5 Feature 1084669: Move Zip archive handling out of STAFZipFile class
// Bug 1084676: unable to unzip symbolic link on SuSE Linux
static const STAFString sLocal("local");
static const STAFString sHelp("help");
static const STAFString sVar("var");
static const STAFString sResStrResolve("RESOLVE REQUEST ");
static const STAFString sString(" STRING ");
static const STAFString sLeftCurlyBrace(kUTF8_LCURLY);
// Prototypes
static STAFResultPtr handleAdd(STAFServiceRequestLevel30 *,
STAFZipServiceData *, STAFString *);
static STAFResultPtr handleUnzip(STAFServiceRequestLevel30 *,
STAFZipServiceData *, STAFString *);
static STAFResultPtr handleList(STAFServiceRequestLevel30 *,
STAFZipServiceData *, STAFString *);
static STAFResultPtr handleDelete(STAFServiceRequestLevel30 *,
STAFZipServiceData *, STAFString *);
static STAFResultPtr handleHelp(STAFServiceRequestLevel30 *,
STAFZipServiceData *);
static STAFResultPtr handleVersion(STAFServiceRequestLevel30 *,
STAFZipServiceData *);
static STAFResultPtr resolveStr(STAFServiceRequestLevel30 *pInfo,
STAFZipServiceData *pData,
const STAFString &theString);
static STAFResultPtr resolveOp(STAFServiceRequestLevel30 *pInfo,
STAFZipServiceData *pData,
STAFCommandParseResultPtr &parsedResult,
const STAFString &fOption,
unsigned int optionIndex = 1);
STAFResultPtr resolveOpLocal(STAFZipServiceData *pData,
STAFCommandParseResultPtr &parsedResult,
const STAFString &fOption,
unsigned int optionIndex = 1);
static void registerHelpData(STAFZipServiceData *pData,
unsigned int errorNumber,
const STAFString &shortInfo,
const STAFString &longInfo);
static void unregisterHelpData(STAFZipServiceData *pData,
unsigned int errorNumber);
// Begin implementation
STAFRC_t STAFServiceGetLevelBounds(unsigned int levelID,
unsigned int *minimum,
unsigned int *maximum)
{
switch (levelID)
{
case kServiceInfo:
{
*minimum = 30;
*maximum = 30;
break;
}
case kServiceInit:
{
*minimum = 30;
*maximum = 30;
break;
}
case kServiceAcceptRequest:
{
*minimum = 30;
*maximum = 30;
break;
}
case kServiceTerm:
case kServiceDestruct:
{
*minimum = 0;
*maximum = 0;
break;
}
default:
{
return kSTAFInvalidAPILevel;
}
}
return kSTAFOk;
}
STAFRC_t STAFServiceConstruct(STAFServiceHandle_t *pServiceHandle,
void *pServiceInfo, unsigned int infoLevel,
STAFString_t *pErrorBuffer)
{
STAFRC_t rc = kSTAFUnknownError;
try
{
if (infoLevel != 30) return kSTAFInvalidAPILevel;
STAFServiceInfoLevel30 *pInfo =
reinterpret_cast<STAFServiceInfoLevel30 *>(pServiceInfo);
STAFZipServiceData data;
data.fDebugMode = 0;
data.fShortName = pInfo->name;
data.fName = "STAF/Service/";
data.fName += pInfo->name;
for (unsigned int i = 0; i < pInfo->numOptions; ++i)
{
if (STAFString(pInfo->pOptionName[i]).upperCase() == "DEBUG")
{
data.fDebugMode = 1;
}
else
{
STAFString optionError(pInfo->pOptionName[i]);
*pErrorBuffer = optionError.adoptImpl();
return kSTAFServiceConfigurationError;
}
}
// Set service handle
*pServiceHandle = new STAFZipServiceData(data);
return kSTAFOk;
}
catch (STAFException &e)
{
STAFString result;
result += STAFString("In STAFZip.cpp: STAFServiceConstruct")
+ kUTF8_SCOLON;
result += STAFString("Name: ") + e.getName() + kUTF8_SCOLON;
result += STAFString("Location: ") + e.getLocation() + kUTF8_SCOLON;
result += STAFString("Text: ") + e.getText() + kUTF8_SCOLON;
result += STAFString("Error code: ") + e.getErrorCode() + kUTF8_SCOLON;
*pErrorBuffer = result.adoptImpl();
}
catch (...)
{
STAFString error(
"STAFZip.cpp: STAFServiceConstruct: Caught "
"unknown exception in STAFServiceConstruct()");
*pErrorBuffer = error.adoptImpl();
}
return kSTAFUnknownError;
}
STAFRC_t STAFServiceInit(STAFServiceHandle_t serviceHandle,
void *pInitInfo, unsigned int initLevel,
STAFString_t *pErrorBuffer)
{
STAFRC_t retCode = kSTAFUnknownError;
try
{
if (initLevel != 30) return kSTAFInvalidAPILevel;
STAFZipServiceData *pData =
reinterpret_cast<STAFZipServiceData *>(serviceHandle);
STAFServiceInitLevel30 *pInfo =
reinterpret_cast<STAFServiceInitLevel30 *>(pInitInfo);
retCode = STAFHandle::create(pData->fName, pData->fHandlePtr);
if (retCode != kSTAFOk)
return retCode;
//ADD options
pData->fAddParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fAddParser->addOption("ADD", 1,
STAFCommandParser::kValueNotAllowed);
// This option has been deprecated
pData->fAddParser->addOption("ZIP", 1,
STAFCommandParser::kValueNotAllowed);
pData->fAddParser->addOption("ZIPFILE", 1,
STAFCommandParser::kValueRequired);
pData->fAddParser->addOption("FILE", 1,
STAFCommandParser::kValueRequired);
pData->fAddParser->addOption("DIRECTORY", 1,
STAFCommandParser::kValueRequired);
pData->fAddParser->addOption("RELATIVETO", 1,
STAFCommandParser::kValueRequired);
pData->fAddParser->addOption("RECURSE", 1,
STAFCommandParser::kValueNotAllowed);
pData->fAddParser->addOptionNeed("ADD", "ZIPFILE");
pData->fAddParser->addOptionNeed("RELATIVETO", "ADD");
pData->fAddParser->addOptionNeed("RELATIVETO", "ZIPFILE");
pData->fAddParser->addOptionNeed("RELATIVETO", "ADD");
pData->fAddParser->addOptionNeed("RECURSE", "ADD");
pData->fAddParser->addOptionNeed("RECURSE", "ZIPFILE");
pData->fAddParser->addOptionNeed("RECURSE", "DIRECTORY");
pData->fAddParser->addOptionNeed("ADD", "FILE DIRECTORY");
pData->fAddParser->addOptionNeed("FILE DIRECTORY", "ADD");
pData->fAddParser->addOptionGroup("FILE DIRECTORY", 0, 1);
//UNZIP options
pData->fUnzipParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fUnzipParser->addOption("UNZIP", 1,
STAFCommandParser::kValueNotAllowed);
pData->fUnzipParser->addOption("ZIPFILE", 1,
STAFCommandParser::kValueRequired);
pData->fUnzipParser->addOption("FILE", 0,
STAFCommandParser::kValueRequired);
pData->fUnzipParser->addOption("DIRECTORY", 1,
STAFCommandParser::kValueRequired);
pData->fUnzipParser->addOption("TODIRECTORY", 1,
STAFCommandParser::kValueRequired);
pData->fUnzipParser->addOption("REPLACE", 1,
STAFCommandParser::kValueNotAllowed);
pData->fUnzipParser->addOption("RESTOREPERMISSION", 1,
STAFCommandParser::kValueNotAllowed);
pData->fUnzipParser->addOptionNeed("UNZIP", "ZIPFILE");
pData->fUnzipParser->addOptionNeed("UNZIP", "TODIRECTORY");
pData->fUnzipParser->addOptionNeed("FILE DIRECTORY", "UNZIP");
pData->fUnzipParser->addOptionNeed("FILE DIRECTORY", "ZIPFILE");
pData->fUnzipParser->addOptionNeed("FILE DIRECTORY", "TODIRECTORY");
pData->fUnzipParser->addOptionGroup("FILE DIRECTORY", 0, 1);
pData->fUnzipParser->addOptionNeed("REPLACE", "UNZIP");
pData->fUnzipParser->addOptionNeed("REPLACE", "ZIPFILE");
pData->fUnzipParser->addOptionNeed("REPLACE", "TODIRECTORY");
pData->fUnzipParser->addOptionNeed("RESTOREPERMISSION", "UNZIP");
pData->fUnzipParser->addOptionNeed("RESTOREPERMISSION", "ZIPFILE");
pData->fUnzipParser->addOptionNeed("RESTOREPERMISSION", "TODIRECTORY");
//LIST options
pData->fListParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fListParser->addOption("LIST", 1,
STAFCommandParser::kValueNotAllowed);
pData->fListParser->addOption("ZIPFILE", 1,
STAFCommandParser::kValueRequired);
pData->fListParser->addOptionNeed("LIST", "ZIPFILE");
//DELETE options
pData->fDeleteParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fDeleteParser->addOption("DELETE", 1,
STAFCommandParser::kValueNotAllowed);
pData->fDeleteParser->addOption("ZIPFILE", 1,
STAFCommandParser::kValueRequired);
pData->fDeleteParser->addOption("FILE", 0,
STAFCommandParser::kValueRequired);
pData->fDeleteParser->addOption("CONFIRM", 1,
STAFCommandParser::kValueNotAllowed);
pData->fDeleteParser->addOptionNeed("DELETE", "ZIPFILE");
pData->fDeleteParser->addOptionNeed("DELETE", "FILE");
pData->fDeleteParser->addOptionNeed("DELETE", "CONFIRM");
//HELP options
pData->fHelpParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fHelpParser->addOption("HELP", 1,
STAFCommandParser::kValueNotAllowed);
//VERSION options
pData->fVersionParser = STAFCommandParserPtr(new STAFCommandParser,
STAFCommandParserPtr::INIT);
pData->fVersionParser->addOption("VERSION", 1,
STAFCommandParser::kValueNotAllowed);
// Get line separator
STAFResultPtr result = pData->fHandlePtr->submit(
"local", "VAR", "RESOLVE STRING {STAF/Config/Sep/Line}");
if (result->rc != 0)
{
*pErrorBuffer = result->result.adoptImpl();
return result->rc;
}
else sLineSep = result->result;
// Get local machine name (logical identifier)
result = pData->fHandlePtr->submit(
"local", "VAR", "RESOLVE STRING {STAF/Config/Machine}");
if (result->rc != 0)
{
*pErrorBuffer = result->result.adoptImpl();
return result->rc;
}
else pData->fLocalMachineName = result->result;
// Register help information for service errors
registerHelpData(pData, kZIPGeneralZipError,
STAFString("General Zip Error"),
STAFString("ZIP service returns a general error "));
registerHelpData(pData, kZIPNotEnoughMemory,
STAFString("Not Enought Memory"),
STAFString("There is not enough memory in system "));
registerHelpData(pData, kZIPChangeFileSizeError,
STAFString("Change File Size Error"),
STAFString("Change file size is unsuccessful "));
registerHelpData(pData, kZIPErrorCreatingDir,
STAFString("Error Creating Dir"),
STAFString("Creating dir is unsuccessful "));
registerHelpData(pData, kZIPInvalidZipFile,
STAFString("Invalid Zip File"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -