mirror of
https://github.com/sfall-team/Fallout_DAT2.git
synced 2026-07-27 16:53:05 -07:00
Initial commit: the original DAT2 v2.32
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DatFileBase.h"
|
||||||
|
|
||||||
|
// CFileList1
|
||||||
|
class CFileList1 : public CObject {
|
||||||
|
public:
|
||||||
|
CFileList1();
|
||||||
|
virtual ~CFileList1();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CFileList1)
|
||||||
|
|
||||||
|
virtual void Serialize(CArchive& ar);
|
||||||
|
INT_PTR GetSize() const;
|
||||||
|
|
||||||
|
DWORD GetLength();
|
||||||
|
|
||||||
|
INT_PTR Add(const CFileDescriptorBase& newElement);
|
||||||
|
void RemoveAt(INT_PTR nIndex);
|
||||||
|
|
||||||
|
CFileDescriptorBase& operator [] (INT_PTR nIndex);
|
||||||
|
CFileDescriptorBase operator [] (INT_PTR nIndex) const;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
virtual void AssertValid() const;
|
||||||
|
virtual void Dump(CDumpContext& dc) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Assignment and copy not allowed
|
||||||
|
CFileList1(const CFileList1&);
|
||||||
|
CFileList1& operator = (const CFileList1&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// CFileDescriptorBaseArray
|
||||||
|
typedef CArray<CFileDescriptorBase, const CFileDescriptorBase&> CFileDescriptorBaseArray;
|
||||||
|
|
||||||
|
// CFileTreeItem
|
||||||
|
class CFileTreeItem {
|
||||||
|
public:
|
||||||
|
CFileTreeItem();
|
||||||
|
CFileTreeItem(const CFileTreeItem& item);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CFileTreeItem& operator = (const CFileTreeItem& item);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CString m_strDirectoryName;
|
||||||
|
CFileDescriptorBaseArray m_FileList;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CFileTree
|
||||||
|
typedef CArray<CFileTreeItem, const CFileTreeItem&> CFileTree;
|
||||||
|
|
||||||
|
CFileTree m_FileTree;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CDatFile1
|
||||||
|
class CDatFile1 : public CDatFileBase {
|
||||||
|
public:
|
||||||
|
CDatFile1();
|
||||||
|
virtual ~CDatFile1();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CDatFile1)
|
||||||
|
|
||||||
|
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);
|
||||||
|
virtual void Close();
|
||||||
|
virtual void Flush();
|
||||||
|
|
||||||
|
virtual INT_PTR GetFileCount();
|
||||||
|
virtual CFileDescriptorBase operator [] (INT_PTR nIndex) const;
|
||||||
|
|
||||||
|
virtual INT_PTR FindNext();
|
||||||
|
|
||||||
|
virtual BOOL Inflate(CArchive& ar);
|
||||||
|
virtual BOOL Deflate(CArchive& ar, DWORD dwLength, LPCTSTR lpszName, int level);
|
||||||
|
virtual BOOL Delete();
|
||||||
|
virtual BOOL Shrink(void (*pCallback)(INT_PTR nIndex));
|
||||||
|
|
||||||
|
private:
|
||||||
|
void FreeSpaceForCatalog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Restricted operations
|
||||||
|
CDatFile1(const CDatFile1&);
|
||||||
|
CDatFile1& operator = (const CDatFile1&);
|
||||||
|
virtual void Serialize(CArchive&) {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFileList1 m_FileList;
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DatFileBase.h"
|
||||||
|
|
||||||
|
// CFileDescriptor2
|
||||||
|
class CFileDescriptor2 : public CFileDescriptorBase {
|
||||||
|
public:
|
||||||
|
CFileDescriptor2();
|
||||||
|
CFileDescriptor2(const CFileDescriptor2& item);
|
||||||
|
virtual ~CFileDescriptor2();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CFileDescriptor2)
|
||||||
|
|
||||||
|
virtual void Serialize(CArchive& ar);
|
||||||
|
int GetSize() const;
|
||||||
|
|
||||||
|
CFileDescriptor2& operator = (const CFileDescriptor2& item);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
virtual void AssertValid() const;
|
||||||
|
virtual void Dump(CDumpContext& dc) const;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// CFileList2
|
||||||
|
class CFileList2 : public CObject {
|
||||||
|
public:
|
||||||
|
CFileList2();
|
||||||
|
virtual ~CFileList2();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CFileList2)
|
||||||
|
|
||||||
|
virtual void Serialize(CArchive& ar);
|
||||||
|
INT_PTR GetSize() const;
|
||||||
|
|
||||||
|
INT_PTR Add(const CFileDescriptor2& newElement);
|
||||||
|
void RemoveAt(INT_PTR nIndex);
|
||||||
|
|
||||||
|
CFileDescriptor2& operator [] (INT_PTR nIndex);
|
||||||
|
CFileDescriptor2 operator [] (INT_PTR nIndex) const;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
virtual void AssertValid() const;
|
||||||
|
virtual void Dump(CDumpContext& dc) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Assignment and copy not allowed
|
||||||
|
CFileList2(const CFileList2&);
|
||||||
|
CFileList2& operator = (const CFileList2&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef CArray<CFileDescriptor2> CFileDescriptor2Array;
|
||||||
|
|
||||||
|
CFileDescriptor2Array m_FileList;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CDatFile2
|
||||||
|
class CDatFile2 : public CDatFileBase {
|
||||||
|
public:
|
||||||
|
CDatFile2();
|
||||||
|
virtual ~CDatFile2();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CDatFile2)
|
||||||
|
|
||||||
|
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);
|
||||||
|
virtual void Close();
|
||||||
|
virtual void Flush();
|
||||||
|
|
||||||
|
virtual INT_PTR GetFileCount();
|
||||||
|
virtual CFileDescriptorBase operator [](INT_PTR nIndex) const;
|
||||||
|
|
||||||
|
virtual INT_PTR FindNext();
|
||||||
|
|
||||||
|
virtual BOOL Inflate(CArchive& ar);
|
||||||
|
virtual BOOL Deflate(CArchive& ar, DWORD dwLength, LPCTSTR lpszName, int level);
|
||||||
|
virtual BOOL Delete();
|
||||||
|
|
||||||
|
virtual BOOL Shrink(void (*pCallback)(INT_PTR nIndex));
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Restricted operations
|
||||||
|
CDatFile2(const CDatFile2&);
|
||||||
|
CDatFile2& operator = (const CDatFile2&);
|
||||||
|
virtual void Serialize(CArchive&) {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
CFileList2 m_FileList;
|
||||||
|
};
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
// DatFile.cpp : implementation file
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "DatFileBase.h"
|
||||||
|
#include ".\datfilebase.h"
|
||||||
|
|
||||||
|
#if defined(_UNICODE) || defined(UNICODE)
|
||||||
|
#error UNICODE not supported
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Utility function
|
||||||
|
CString MakeLower(CString str)
|
||||||
|
{
|
||||||
|
return str.MakeLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
// CFileDescriptorBase
|
||||||
|
IMPLEMENT_DYNAMIC(CFileDescriptorBase, CObject)
|
||||||
|
|
||||||
|
CFileDescriptorBase::CFileDescriptorBase() :
|
||||||
|
m_strFileName(""),
|
||||||
|
m_nType(0),
|
||||||
|
m_dwFileLength(0),
|
||||||
|
m_dwPackedFileLength(0),
|
||||||
|
m_dwOffset(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileDescriptorBase::CFileDescriptorBase(const CFileDescriptorBase& item) :
|
||||||
|
m_strFileName(item.m_strFileName),
|
||||||
|
m_nType(item.m_nType),
|
||||||
|
m_dwFileLength(item.m_dwFileLength),
|
||||||
|
m_dwPackedFileLength(item.m_dwPackedFileLength),
|
||||||
|
m_dwOffset(item.m_dwOffset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileDescriptorBase::~CFileDescriptorBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFileDescriptorBase& CFileDescriptorBase::operator = (const CFileDescriptorBase& item)
|
||||||
|
{
|
||||||
|
if (&item != this) {
|
||||||
|
m_strFileName = item.m_strFileName;
|
||||||
|
m_nType = item.m_nType;
|
||||||
|
m_dwFileLength = item.m_dwFileLength;
|
||||||
|
m_dwPackedFileLength = item.m_dwPackedFileLength;
|
||||||
|
m_dwOffset = item.m_dwOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileDescriptorBase::Serialize(CArchive& ar)
|
||||||
|
{
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
void CFileDescriptorBase::AssertValid() const
|
||||||
|
{
|
||||||
|
CObject::AssertValid();
|
||||||
|
ASSERT(!m_strFileName.IsEmpty());
|
||||||
|
ASSERT(m_nType <= 1);
|
||||||
|
ASSERT(m_dwFileLength != 0);
|
||||||
|
ASSERT(m_dwPackedFileLength != 0);
|
||||||
|
ASSERT(m_dwPackedFileLength >= m_dwFileLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFileDescriptorBase::Dump(CDumpContext& dc) const
|
||||||
|
{
|
||||||
|
CObject::Dump(dc);
|
||||||
|
dc << "File name length:\t" << m_strFileName.GetLength() << "\n";
|
||||||
|
dc << "File name:\t\t\t" << m_strFileName << "\n";
|
||||||
|
dc << "Type:\t\t\t\t" << m_nType << "\n";
|
||||||
|
dc << "File length:\t\t\t" << m_dwFileLength << " (";
|
||||||
|
dc.DumpAsHex(m_dwFileLength);
|
||||||
|
dc << ")\n";
|
||||||
|
dc << "Packed file length:\t" << m_dwPackedFileLength << " (";
|
||||||
|
dc.DumpAsHex(m_dwPackedFileLength);
|
||||||
|
dc << ")\n";
|
||||||
|
dc << "Offset:\t\t\t\t" << m_dwOffset << " (";
|
||||||
|
dc.DumpAsHex(m_dwOffset);
|
||||||
|
dc << ")\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// CDatFileBase
|
||||||
|
IMPLEMENT_DYNAMIC(CDatFileBase, CObject)
|
||||||
|
|
||||||
|
CDatFileBase::CDatFileBase() :
|
||||||
|
m_strPattern("*"),
|
||||||
|
m_bNeedFlush(FALSE),
|
||||||
|
m_nCurrent(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CDatFileBase::~CDatFileBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD CDatFileBase::GetLength(void)
|
||||||
|
{
|
||||||
|
return DWORD(m_Dat.GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CDatFileBase::FindFirst(LPCTSTR lpszPattern)
|
||||||
|
{
|
||||||
|
m_strPattern = lpszPattern;
|
||||||
|
m_nCurrent = -1;
|
||||||
|
return FindNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CDatFileBase::GetCurrentFileIndex()
|
||||||
|
{
|
||||||
|
return m_nCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CDatFileBase::GetFindFilePattern()
|
||||||
|
{
|
||||||
|
return m_strPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CDatFileBase::MatchPattern(LPCTSTR lpszString, LPCTSTR lpszPattern, BOOL bCaseSensitive)
|
||||||
|
{
|
||||||
|
char c, p;
|
||||||
|
|
||||||
|
for(; ;) {
|
||||||
|
switch(p = ConvertCase(*lpszPattern++, bCaseSensitive)) {
|
||||||
|
case 0: // end of lpszPattern
|
||||||
|
return *lpszString ? FALSE : TRUE; // if end of lpszString TRUE
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
while (*lpszString) { // match zero or more char
|
||||||
|
if (MatchPattern(lpszString++, lpszPattern, bCaseSensitive))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MatchPattern (lpszString, lpszPattern, bCaseSensitive );
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
if (*lpszString++ == 0) // match any one char
|
||||||
|
return FALSE; // not end of lpszString
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
c = ConvertCase(*lpszString++, bCaseSensitive);
|
||||||
|
|
||||||
|
if (c != p) // check for exact char
|
||||||
|
return FALSE; // not a match
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char CDatFileBase::ConvertCase(char c, BOOL bCaseSensetive)
|
||||||
|
{
|
||||||
|
return bCaseSensetive ? c : char(CharUpper(LPTSTR(c)));
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// CFileDescriptorBase
|
||||||
|
class CFileDescriptorBase : public CObject {
|
||||||
|
public:
|
||||||
|
CFileDescriptorBase();
|
||||||
|
CFileDescriptorBase(const CFileDescriptorBase& item);
|
||||||
|
virtual ~CFileDescriptorBase();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CFileDescriptorBase)
|
||||||
|
|
||||||
|
virtual void Serialize(CArchive& ar);
|
||||||
|
|
||||||
|
CFileDescriptorBase& operator = (const CFileDescriptorBase& item);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
virtual void AssertValid() const;
|
||||||
|
virtual void Dump(CDumpContext& dc) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
CString m_strFileName;
|
||||||
|
BYTE m_nType;
|
||||||
|
DWORD m_dwFileLength;
|
||||||
|
DWORD m_dwPackedFileLength;
|
||||||
|
DWORD m_dwOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// CDatFileBase
|
||||||
|
class CDatFileBase : public CObject {
|
||||||
|
public:
|
||||||
|
CDatFileBase();
|
||||||
|
virtual ~CDatFileBase();
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC(CDatFileBase)
|
||||||
|
|
||||||
|
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags) = 0;
|
||||||
|
virtual void Close() = 0;
|
||||||
|
virtual void Flush() = 0;
|
||||||
|
|
||||||
|
DWORD GetLength();
|
||||||
|
|
||||||
|
virtual INT_PTR GetFileCount() = 0;
|
||||||
|
virtual CFileDescriptorBase operator [](INT_PTR nIndex) const = 0;
|
||||||
|
|
||||||
|
INT_PTR FindFirst(LPCTSTR lpszPattern);
|
||||||
|
virtual INT_PTR FindNext() = 0;
|
||||||
|
INT_PTR GetCurrentFileIndex();
|
||||||
|
CString GetFindFilePattern();
|
||||||
|
|
||||||
|
virtual BOOL Inflate(CArchive& ar) = 0;
|
||||||
|
virtual BOOL Deflate(CArchive& ar, DWORD dwLength, LPCTSTR lpszName, int level) = 0;
|
||||||
|
virtual BOOL Delete() = 0;
|
||||||
|
virtual BOOL Shrink(void (*pCallback)(INT_PTR nIndex)) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOL MatchPattern(LPCTSTR lpszString, LPCTSTR lpszPattern, BOOL bCaseSensitive);
|
||||||
|
char ConvertCase(char c, BOOL bCaseSensetive);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CString m_strPattern;
|
||||||
|
CFile m_Dat;
|
||||||
|
|
||||||
|
BOOL m_bNeedFlush;
|
||||||
|
INT_PTR m_nCurrent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Utility function
|
||||||
|
CString MakeLower(CString str);
|
||||||
+304
@@ -0,0 +1,304 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#define N 4096 /* size of ring buffer */
|
||||||
|
#define F 18 /* upper limit for match_length */
|
||||||
|
#define THRESHOLD 2 /* encode string into position and length if match_length is greater than this */
|
||||||
|
#define NIL N /* index for root of binary search trees */
|
||||||
|
|
||||||
|
//unsigned long int textsize = 0; /* text size counter */
|
||||||
|
//unsigned long int codesize = 0; /* code size counter */
|
||||||
|
|
||||||
|
BYTE text_buf[N + F - 1]; /* Ring buffer of size N, with extra F-1 bytes to facilitate string comparison */
|
||||||
|
|
||||||
|
int match_position; /* Longest match. These are set by the InsertNode() procedure. */
|
||||||
|
int match_length;
|
||||||
|
|
||||||
|
int lson[N + 1]; /* left children */
|
||||||
|
int rson[N + 257]; /* right children */
|
||||||
|
int dad[N + 1]; /* parents -- These constitute binary search trees. */
|
||||||
|
|
||||||
|
void InitTree()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = N + 1; i <= N + 256; i++) {
|
||||||
|
rson[i] = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < N; i++) {
|
||||||
|
dad[i] = NIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertNode(int r)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int p;
|
||||||
|
int cmp;
|
||||||
|
BYTE* key;
|
||||||
|
|
||||||
|
cmp = 1;
|
||||||
|
key = &text_buf[r];
|
||||||
|
p = N + 1 + key[0];
|
||||||
|
|
||||||
|
rson[r] = lson[r] = NIL;
|
||||||
|
match_length = 0;
|
||||||
|
|
||||||
|
for( ; ; ) {
|
||||||
|
if (cmp >= 0) {
|
||||||
|
if (rson[p] != NIL) {
|
||||||
|
p = rson[p];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rson[p] = r;
|
||||||
|
dad[r] = p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (lson[p] != NIL) {
|
||||||
|
p = lson[p];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lson[p] = r;
|
||||||
|
dad[r] = p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < F; i++) {
|
||||||
|
if ((cmp = key[i] - text_buf[p + i]) != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > match_length) {
|
||||||
|
match_position = p;
|
||||||
|
|
||||||
|
if ((match_length = i) >= F) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dad[r] = dad[p];
|
||||||
|
lson[r] = lson[p];
|
||||||
|
rson[r] = rson[p];
|
||||||
|
|
||||||
|
dad[lson[p]] = r;
|
||||||
|
dad[rson[p]] = r;
|
||||||
|
|
||||||
|
if (rson[dad[p]] == p) {
|
||||||
|
rson[dad[p]] = r;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lson[dad[p]] = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
dad[p] = NIL; /* remove p */
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteNode(int p)
|
||||||
|
{
|
||||||
|
int q;
|
||||||
|
|
||||||
|
if (dad[p] == NIL) {
|
||||||
|
return; /* not in tree */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rson[p] == NIL) {
|
||||||
|
q = lson[p];
|
||||||
|
}
|
||||||
|
else if (lson[p] == NIL) {
|
||||||
|
q = rson[p];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
q = lson[p];
|
||||||
|
|
||||||
|
if (rson[q] != NIL) {
|
||||||
|
do {
|
||||||
|
q = rson[q];
|
||||||
|
} while (rson[q] != NIL);
|
||||||
|
|
||||||
|
rson[dad[q]] = lson[q];
|
||||||
|
dad[lson[q]] = dad[q];
|
||||||
|
lson[q] = lson[p];
|
||||||
|
dad[lson[p]] = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
rson[q] = rson[p];
|
||||||
|
dad[rson[p]] = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
dad[q] = dad[p];
|
||||||
|
|
||||||
|
if (rson[dad[p]] == p) {
|
||||||
|
rson[dad[p]] = q;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lson[dad[p]] = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
dad[p] = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GETBYTE() ((dwInputCurrent < dwInputLength) ? int(buffer[dwInputCurrent++]) & 0xFF : (-1))
|
||||||
|
|
||||||
|
void LZSSEncodeBuffer(BYTE* buffer, DWORD dwInputLength, CFile& fileOut)
|
||||||
|
{
|
||||||
|
ASSERT(buffer);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int c;
|
||||||
|
int len;
|
||||||
|
int r;
|
||||||
|
int s;
|
||||||
|
int last_match_length;
|
||||||
|
int code_buf_ptr;
|
||||||
|
|
||||||
|
BYTE code_buf[17];
|
||||||
|
BYTE mask;
|
||||||
|
|
||||||
|
DWORD dwInputCurrent = 0;
|
||||||
|
|
||||||
|
InitTree();
|
||||||
|
|
||||||
|
code_buf[0] = 0;
|
||||||
|
code_buf_ptr = mask = 1;
|
||||||
|
s = 0;
|
||||||
|
r = N - F;
|
||||||
|
|
||||||
|
for(i = s; i < r; i++) {
|
||||||
|
text_buf[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
for(len = 0; len < F && (c = GETBYTE()) != (-1); len++) {
|
||||||
|
text_buf[r + len] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 1; i <= F; i++) {
|
||||||
|
InsertNode(r - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertNode(r);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (match_length > len) {
|
||||||
|
match_length = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_length <= THRESHOLD) {
|
||||||
|
match_length = 1;
|
||||||
|
code_buf[0] |= mask;
|
||||||
|
code_buf[code_buf_ptr++] = text_buf[r];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
code_buf[code_buf_ptr++] = (BYTE) match_position;
|
||||||
|
code_buf[code_buf_ptr++] = (BYTE)(((match_position >> 4) & 0xf0) | (match_length - (THRESHOLD + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mask <<= 1) == 0) {
|
||||||
|
for (i = 0; i < code_buf_ptr; i++) {
|
||||||
|
fileOut.Write(code_buf + i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
code_buf[0] = 0;
|
||||||
|
code_buf_ptr = mask = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_match_length = match_length;
|
||||||
|
|
||||||
|
for (i = 0; i < last_match_length && (c = GETBYTE()) != (-1); i++) {
|
||||||
|
DeleteNode(s);
|
||||||
|
text_buf[s] = c;
|
||||||
|
|
||||||
|
if (s < F - 1) {
|
||||||
|
text_buf[s + N] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = (s + 1) & (N - 1);
|
||||||
|
r = (r + 1) & (N - 1);
|
||||||
|
InsertNode(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i++ < last_match_length) {
|
||||||
|
DeleteNode(s);
|
||||||
|
s = (s + 1) & (N - 1);
|
||||||
|
r = (r + 1) & (N - 1);
|
||||||
|
|
||||||
|
if (--len) {
|
||||||
|
InsertNode(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(len > 0);
|
||||||
|
|
||||||
|
if (code_buf_ptr > 1) {
|
||||||
|
for (i = 0; i < code_buf_ptr; i++) {
|
||||||
|
fileOut.Write(code_buf + i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LZSSDecodeBuffer(BYTE* buffer, DWORD dwInputLength, CArchive& arOut)
|
||||||
|
{
|
||||||
|
ASSERT(buffer);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int k;
|
||||||
|
int r;
|
||||||
|
int c;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
DWORD dwInputCurrent = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < N - F; i++) {
|
||||||
|
text_buf[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
r = N - F;
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
for ( ; ; ) {
|
||||||
|
if (((flags >>= 1) & 256) == 0) {
|
||||||
|
if ((c = GETBYTE()) == (-1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = c | 0xff00; /* uses higher byte cleverly */
|
||||||
|
} /* to count eight */
|
||||||
|
|
||||||
|
if (flags & 1) {
|
||||||
|
if ((c = GETBYTE()) == (-1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arOut.Write(&c, 1);
|
||||||
|
text_buf[r++] = c;
|
||||||
|
r &= (N - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((i = GETBYTE()) == (-1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((j = GETBYTE()) == (-1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i |= ((j & 0xf0) << 4);
|
||||||
|
j = (j & 0x0f) + THRESHOLD;
|
||||||
|
|
||||||
|
for (k = 0; k <= j; k++) {
|
||||||
|
c = text_buf[(i + k) & (N - 1)];
|
||||||
|
arOut.Write(&c, 1);
|
||||||
|
text_buf[r++] = c;
|
||||||
|
r &= (N - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef LZ77C_H
|
||||||
|
#define LZ77C_H
|
||||||
|
|
||||||
|
void LZSSEncodeBuffer(BYTE* buffer, DWORD dwInputLength, CFile& fileOut);
|
||||||
|
void LZSSDecodeBuffer(BYTE* buffer, DWORD dwInputLength, CArchive& arOut);
|
||||||
|
|
||||||
|
#endif /* LZ77C_H */
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
extern CString g_strTargetDir;
|
||||||
|
|
||||||
|
DWORD g_dwTotalAdded;
|
||||||
|
|
||||||
|
BOOL ProcessTree(CString strPattern, CString strRoot, BOOL bRecursive)
|
||||||
|
{
|
||||||
|
BOOL bResult = TRUE;
|
||||||
|
|
||||||
|
CString strPath = ExtractFilePath(strPattern);
|
||||||
|
CString strFilePattern = ExtractFileName(strPattern);
|
||||||
|
|
||||||
|
WIN32_FIND_DATA fd;
|
||||||
|
HANDLE hSearchHandle = FindFirstFile(strPattern, &fd);
|
||||||
|
|
||||||
|
if (hSearchHandle != INVALID_HANDLE_VALUE) {
|
||||||
|
do {
|
||||||
|
if (CString(fd.cFileName) != CString(_T(".")) &&
|
||||||
|
CString(fd.cFileName) != CString(_T(".."))) {
|
||||||
|
|
||||||
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
if (bRecursive) {
|
||||||
|
ProcessTree(strPath + fd.cFileName + "\\" + strFilePattern,
|
||||||
|
strRoot.IsEmpty() ? fd.cFileName : strRoot + "\\" + fd.cFileName, // + _T("\\"),
|
||||||
|
bRecursive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CFile fileIn;
|
||||||
|
|
||||||
|
if (fileIn.Open(strPath + fd.cFileName, CFile::modeRead | CFile::shareDenyWrite)) {
|
||||||
|
CArchive arIn(&fileIn, CArchive::load);
|
||||||
|
CString strFileDescriptorName = g_strTargetDir;
|
||||||
|
strFileDescriptorName += strRoot.IsEmpty() ? fd.cFileName : strRoot + _T("\\") + fd.cFileName;
|
||||||
|
|
||||||
|
printf("Adding: %s", strFileDescriptorName);
|
||||||
|
|
||||||
|
if (g_pDatFile->Deflate(arIn, DWORD(fileIn.GetLength()),
|
||||||
|
strFileDescriptorName, g_nCompressMethod)) {
|
||||||
|
printf("\n");
|
||||||
|
g_dwTotalAdded++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf(" Error!!!\n");
|
||||||
|
bResult = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bResult = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(FindNextFile(hSearchHandle, &fd));
|
||||||
|
|
||||||
|
FindClose(hSearchHandle);
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int OnAdd()
|
||||||
|
{
|
||||||
|
g_dwTotalAdded = 0;
|
||||||
|
|
||||||
|
if (g_pDatFile->Open(g_strDatFileName, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite | CFile::shareDenyWrite)) {
|
||||||
|
for(INT_PTR j = 0; j < g_FileList.GetCount(); j++) {
|
||||||
|
CString strRoot = ExtractFilePath(g_FileList[j], FALSE);
|
||||||
|
|
||||||
|
if (strRoot[0] == '\\') {
|
||||||
|
strRoot = strRoot.Right(strRoot.GetLength() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strRoot.Right(1) == '\\') {
|
||||||
|
strRoot = strRoot.Left(strRoot.GetLength() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ProcessTree(g_FileList[j], strRoot, g_bRecurseIntoDir)) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("----------\n");
|
||||||
|
printf("%u file(s) added\n", g_dwTotalAdded);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Error: Unable open file %s\n", LPCTSTR(g_strDatFileName));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
|
||||||
|
int OnDelete()
|
||||||
|
{
|
||||||
|
CFileDescriptorBase descriptor;
|
||||||
|
DWORD dwTotalDeleted = 0;
|
||||||
|
|
||||||
|
for(INT_PTR j = 0; j < g_FileList.GetCount(); j++) {
|
||||||
|
if (g_pDatFile->FindFirst(g_FileList[j]) != -1) {
|
||||||
|
do {
|
||||||
|
descriptor = (*g_pDatFile)[g_pDatFile->GetCurrentFileIndex()];
|
||||||
|
printf("Deleting: %s", descriptor.m_strFileName);
|
||||||
|
|
||||||
|
if (g_pDatFile->Delete()) {
|
||||||
|
dwTotalDeleted++;
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf(" Error!!!\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
} while(g_pDatFile->FindNext() != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("----------\n");
|
||||||
|
printf("%u file(s) deleted\n", dwTotalDeleted);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
int OnExtract()
|
||||||
|
{
|
||||||
|
CFileDescriptorBase descriptor;
|
||||||
|
DWORD dwTotalExtracted = 0;
|
||||||
|
CString strDirectory;
|
||||||
|
CString strFileName;
|
||||||
|
int nLastSlashPos;
|
||||||
|
CString strOutFileName;
|
||||||
|
CFile fileOut;
|
||||||
|
|
||||||
|
// Create output directory
|
||||||
|
if (!g_strOutFolder.IsEmpty()) {
|
||||||
|
if (!ForceCreateDirectory(g_strOutFolder)) {
|
||||||
|
printf("Error: Unable create output directory\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(INT_PTR j = 0; j < g_FileList.GetCount(); j++) {
|
||||||
|
if (g_pDatFile->FindFirst(g_FileList[j]) != -1) {
|
||||||
|
do {
|
||||||
|
descriptor = (*g_pDatFile)[g_pDatFile->GetCurrentFileIndex()];
|
||||||
|
printf("Extracting: %s", descriptor.m_strFileName);
|
||||||
|
nLastSlashPos = descriptor.m_strFileName.ReverseFind('\\');
|
||||||
|
strDirectory = descriptor.m_strFileName.Left(nLastSlashPos + 1);
|
||||||
|
strFileName = descriptor.m_strFileName.Right(descriptor.m_strFileName.GetLength() - nLastSlashPos - 1);
|
||||||
|
|
||||||
|
|
||||||
|
if (g_bExtractWithoutPaths) {
|
||||||
|
strOutFileName = g_strOutFolder + strFileName;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!ForceCreateDirectory(g_strOutFolder + strDirectory)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
strOutFileName = g_strOutFolder + strDirectory + strFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileOut.Open(strOutFileName, CFile::modeCreate | CFile::modeWrite)) {
|
||||||
|
CArchive arOut(&fileOut, CArchive::store);
|
||||||
|
|
||||||
|
if (g_pDatFile->Inflate(arOut)) {
|
||||||
|
dwTotalExtracted++;
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf(" Error!!!\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf(" Error!!! Unable open out file %s\n", strOutFileName);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut.Close();
|
||||||
|
} while(g_pDatFile->FindNext() != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("----------\n");
|
||||||
|
printf("%u file(s) extracted\n", dwTotalExtracted);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
|
||||||
|
int OnList()
|
||||||
|
{
|
||||||
|
CFileDescriptorBase descriptor;
|
||||||
|
DWORD dwTotalSize = 0;
|
||||||
|
|
||||||
|
printf(" Length Packed Type Name\n");
|
||||||
|
printf(" ---------- ----------- -------- ---------------\n");
|
||||||
|
|
||||||
|
for(INT_PTR i = 0; i < g_pDatFile->GetFileCount(); i++) {
|
||||||
|
descriptor = (*g_pDatFile)[i];
|
||||||
|
dwTotalSize += descriptor.m_dwFileLength;
|
||||||
|
printf("%11u %11u %s %s\n",
|
||||||
|
descriptor.m_dwFileLength,
|
||||||
|
descriptor.m_dwPackedFileLength,
|
||||||
|
(descriptor.m_nType) ? "Packed" : "Stored",
|
||||||
|
descriptor.m_strFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" ---------- ---------------\n");
|
||||||
|
printf("%11u %u file(s)\n",
|
||||||
|
dwTotalSize,
|
||||||
|
DWORD(g_pDatFile->GetFileCount()));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
|
||||||
|
|
||||||
|
DWORD dwTotalMoved = 0;
|
||||||
|
|
||||||
|
void OutInfo(INT_PTR nIndex)
|
||||||
|
{
|
||||||
|
CFileDescriptorBase descriptor;
|
||||||
|
descriptor = (*g_pDatFile)[nIndex];
|
||||||
|
|
||||||
|
|
||||||
|
dwTotalMoved++;
|
||||||
|
printf("Moving: %s\n", descriptor.m_strFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int OnShrink()
|
||||||
|
{
|
||||||
|
DWORD dwOldLength = g_pDatFile->GetLength();
|
||||||
|
|
||||||
|
if (g_pDatFile->Shrink(OutInfo)) {
|
||||||
|
printf("----------\n");
|
||||||
|
printf("%u file(s) moved. Old size: %u bytes. New size: %u bytes \n", dwTotalMoved, dwOldLength, g_pDatFile->GetLength());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Error: Unable shrink file\n");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by dat2.rc
|
||||||
|
//
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
+177
@@ -0,0 +1,177 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
CString ExtractFilePath(const CString& strFileName, BOOL bIncludeDrive)
|
||||||
|
{
|
||||||
|
CString strDrive;
|
||||||
|
CString strDirectory;
|
||||||
|
LPTSTR lpszDrive = strDrive.GetBufferSetLength(_MAX_DRIVE);
|
||||||
|
LPTSTR lpszDirectory = strDirectory.GetBufferSetLength(_MAX_DIR);
|
||||||
|
_splitpath(strFileName, lpszDrive, lpszDirectory, NULL, NULL);
|
||||||
|
strDrive.ReleaseBuffer();
|
||||||
|
strDirectory.ReleaseBuffer();
|
||||||
|
|
||||||
|
if (bIncludeDrive) {
|
||||||
|
return (strDrive + strDirectory);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return strDirectory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CString ExtractFileName(const CString& strFileName)
|
||||||
|
{
|
||||||
|
CString strName;
|
||||||
|
CString strExtension;
|
||||||
|
LPTSTR lpszName = strName.GetBufferSetLength(_MAX_FNAME);
|
||||||
|
LPTSTR lpszExtension = strExtension.GetBufferSetLength(_MAX_EXT);
|
||||||
|
_splitpath(strFileName, NULL, NULL, lpszName, lpszExtension);
|
||||||
|
strName.ReleaseBuffer();
|
||||||
|
strExtension.ReleaseBuffer();
|
||||||
|
return (strName + strExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DirectoryExist(const CString& strDirectory)
|
||||||
|
{
|
||||||
|
DWORD dwResult = ::GetFileAttributes(strDirectory);
|
||||||
|
return ((dwResult != INVALID_FILE_ATTRIBUTES) &&
|
||||||
|
((dwResult & FILE_ATTRIBUTE_DIRECTORY) != 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ForceCreateDirectory(CString strDirectory)
|
||||||
|
{
|
||||||
|
if (strDirectory.GetLength() == 0) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strDirectory.Right(1) == _T("\\")) {
|
||||||
|
strDirectory = strDirectory.Left(strDirectory.GetLength() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((strDirectory.GetLength() < 3) ||
|
||||||
|
DirectoryExist(strDirectory) ||
|
||||||
|
(ExtractFilePath(strDirectory) == strDirectory)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ForceCreateDirectory(ExtractFilePath(strDirectory)) &&
|
||||||
|
::CreateDirectory(strDirectory, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ReadMSBWord(CArchive& ar, WORD& wValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&wValue);
|
||||||
|
return (ar.Read(pBuffer + 1, 1) + ar.Read(pBuffer, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ReadMSBDWord(CArchive& ar, DWORD& dwValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&dwValue);
|
||||||
|
return (ar.Read(pBuffer + 3, 1) + ar.Read(pBuffer + 2, 1) +
|
||||||
|
ar.Read(pBuffer + 1, 1) + ar.Read(pBuffer, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ReadMSBWord(CFile& file, WORD& wValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&wValue);
|
||||||
|
return (file.Read(pBuffer + 1, 1) + file.Read(pBuffer, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ReadMSBDWord(CFile& file, DWORD& dwValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&dwValue);
|
||||||
|
return (file.Read(pBuffer + 3, 1) + file.Read(pBuffer + 2, 1) +
|
||||||
|
file.Read(pBuffer + 1, 1) + file.Read(pBuffer, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ReadString(CArchive& ar, CString& strString)
|
||||||
|
{
|
||||||
|
BYTE nStrLength;
|
||||||
|
|
||||||
|
if (ar.Read(&nStrLength, 1) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPTSTR lpszString = strString.GetBufferSetLength(nStrLength + 1);
|
||||||
|
DWORD dwRead = ar.Read(lpszString, nStrLength);
|
||||||
|
strString.ReleaseBuffer(nStrLength);
|
||||||
|
|
||||||
|
if (dwRead != nStrLength) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ReadString(CFile& file, CString& strString)
|
||||||
|
{
|
||||||
|
BYTE nStrLength;
|
||||||
|
|
||||||
|
if (file.Read(&nStrLength, 1) != 1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPTSTR lpszString = strString.GetBufferSetLength(nStrLength + 1);
|
||||||
|
DWORD dwRead = file.Read(lpszString, nStrLength);
|
||||||
|
strString.ReleaseBuffer(nStrLength);
|
||||||
|
|
||||||
|
if (dwRead != nStrLength) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteMSBWord(CArchive& ar, WORD wValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&wValue);
|
||||||
|
|
||||||
|
ar.Write(pBuffer + 1, 1);
|
||||||
|
ar.Write(pBuffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteMSBDWord(CArchive& ar, DWORD dwValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&dwValue);
|
||||||
|
|
||||||
|
ar.Write(pBuffer + 3, 1);
|
||||||
|
ar.Write(pBuffer + 2, 1);
|
||||||
|
ar.Write(pBuffer + 1, 1);
|
||||||
|
ar.Write(pBuffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteMSBWord(CFile& file, WORD wValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&wValue);
|
||||||
|
|
||||||
|
file.Write(pBuffer + 1, 1);
|
||||||
|
file.Write(pBuffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteMSBDWord(CFile& file, DWORD dwValue)
|
||||||
|
{
|
||||||
|
BYTE* pBuffer = reinterpret_cast<BYTE*>(&dwValue);
|
||||||
|
|
||||||
|
file.Write(pBuffer + 3, 1);
|
||||||
|
file.Write(pBuffer + 2, 1);
|
||||||
|
file.Write(pBuffer + 1, 1);
|
||||||
|
file.Write(pBuffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteString(CArchive& ar, CString& strString)
|
||||||
|
{
|
||||||
|
BYTE nStrLength = BYTE(strString.GetLength());
|
||||||
|
|
||||||
|
ar.Write(&nStrLength, 1);
|
||||||
|
ar.Write(LPCTSTR(strString), nStrLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteString(CFile& file, CString& strString)
|
||||||
|
{
|
||||||
|
BYTE nStrLength = BYTE(strString.GetLength());
|
||||||
|
|
||||||
|
file.Write(&nStrLength, 1);
|
||||||
|
file.Write(LPCTSTR(strString), nStrLength);
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
CString ExtractFileName(const CString& strFileName);
|
||||||
|
CString ExtractFilePath(const CString& strFileName, BOOL bIncludeDrive = TRUE);
|
||||||
|
BOOL DirectoryExist(const CString& strDirectory);
|
||||||
|
BOOL ForceCreateDirectory(CString strDirectory);
|
||||||
|
|
||||||
|
UINT ReadMSBWord(CArchive& ar, WORD& wValue);
|
||||||
|
UINT ReadMSBDWord(CArchive& ar, DWORD& dwValue);
|
||||||
|
|
||||||
|
UINT ReadMSBWord(CFile& file, WORD& wValue);
|
||||||
|
UINT ReadMSBDWord(CFile& file, DWORD& dwValue);
|
||||||
|
|
||||||
|
BOOL ReadString(CArchive& ar, CString& strString);
|
||||||
|
BOOL ReadString(CFile& file, CString& strString);
|
||||||
|
|
||||||
|
void WriteMSBWord(CArchive& ar, WORD wValue);
|
||||||
|
void WriteMSBDWord(CArchive& ar, DWORD dwValue);
|
||||||
|
|
||||||
|
void WriteMSBWord(CFile& file, WORD wValue);
|
||||||
|
void WriteMSBDWord(CFile& file, DWORD dwValue);
|
||||||
|
|
||||||
|
void WriteString(CArchive& ar, CString& strString);
|
||||||
|
void WriteString(CFile& file, CString& strString);
|
||||||
+219
@@ -0,0 +1,219 @@
|
|||||||
|
// XGetopt.cpp Version 1.2
|
||||||
|
//
|
||||||
|
// Author: Hans Dietrich
|
||||||
|
// hdietrich2@hotmail.com
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// XGetopt.cpp implements getopt(), a function to parse command lines.
|
||||||
|
//
|
||||||
|
// History
|
||||||
|
// Version 1.2 - 2003 May 17
|
||||||
|
// - Added Unicode support
|
||||||
|
//
|
||||||
|
// Version 1.1 - 2002 March 10
|
||||||
|
// - Added example to XGetopt.cpp module header
|
||||||
|
//
|
||||||
|
// This software is released into the public domain.
|
||||||
|
// You are free to use it in any way you like.
|
||||||
|
//
|
||||||
|
// This software is provided "as is" with no expressed
|
||||||
|
// or implied warranty. I accept no liability for any
|
||||||
|
// damage or loss of business that this software may cause.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if you are using precompiled headers then include this line:
|
||||||
|
#include "stdafx.h"
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if you are not using precompiled headers then include these lines:
|
||||||
|
//#include <windows.h>
|
||||||
|
//#include <stdio.h>
|
||||||
|
//#include <tchar.h>
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#include "XGetopt.h"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// X G e t o p t . c p p
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// NAME
|
||||||
|
// getopt -- parse command line options
|
||||||
|
//
|
||||||
|
// SYNOPSIS
|
||||||
|
// int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
|
||||||
|
//
|
||||||
|
// extern TCHAR *optarg;
|
||||||
|
// extern int optind;
|
||||||
|
//
|
||||||
|
// DESCRIPTION
|
||||||
|
// The getopt() function parses the command line arguments. Its
|
||||||
|
// arguments argc and argv are the argument count and array as
|
||||||
|
// passed into the application on program invocation. In the case
|
||||||
|
// of Visual C++ programs, argc and argv are available via the
|
||||||
|
// variables __argc and __argv (double underscores), respectively.
|
||||||
|
// getopt returns the next option letter in argv that matches a
|
||||||
|
// letter in optstring. (Note: Unicode programs should use
|
||||||
|
// __targv instead of __argv. Also, all character and string
|
||||||
|
// literals should be enclosed in _T( ) ).
|
||||||
|
//
|
||||||
|
// optstring is a string of recognized option letters; if a letter
|
||||||
|
// is followed by a colon, the option is expected to have an argument
|
||||||
|
// that may or may not be separated from it by white space. optarg
|
||||||
|
// is set to point to the start of the option argument on return from
|
||||||
|
// getopt.
|
||||||
|
//
|
||||||
|
// Option letters may be combined, e.g., "-ab" is equivalent to
|
||||||
|
// "-a -b". Option letters are case sensitive.
|
||||||
|
//
|
||||||
|
// getopt places in the external variable optind the argv index
|
||||||
|
// of the next argument to be processed. optind is initialized
|
||||||
|
// to 0 before the first call to getopt.
|
||||||
|
//
|
||||||
|
// When all options have been processed (i.e., up to the first
|
||||||
|
// non-option argument), getopt returns EOF, optarg will point
|
||||||
|
// to the argument, and optind will be set to the argv index of
|
||||||
|
// the argument. If there are no non-option arguments, optarg
|
||||||
|
// will be set to NULL.
|
||||||
|
//
|
||||||
|
// The special option "--" may be used to delimit the end of the
|
||||||
|
// options; EOF will be returned, and "--" (and everything after it)
|
||||||
|
// will be skipped.
|
||||||
|
//
|
||||||
|
// RETURN VALUE
|
||||||
|
// For option letters contained in the string optstring, getopt
|
||||||
|
// will return the option letter. getopt returns a question mark (?)
|
||||||
|
// when it encounters an option letter not included in optstring.
|
||||||
|
// EOF is returned when processing is finished.
|
||||||
|
//
|
||||||
|
// BUGS
|
||||||
|
// 1) Long options are not supported.
|
||||||
|
// 2) The GNU double-colon extension is not supported.
|
||||||
|
// 3) The environment variable POSIXLY_CORRECT is not supported.
|
||||||
|
// 4) The + syntax is not supported.
|
||||||
|
// 5) The automatic permutation of arguments is not supported.
|
||||||
|
// 6) This implementation of getopt() returns EOF if an error is
|
||||||
|
// encountered, instead of -1 as the latest standard requires.
|
||||||
|
//
|
||||||
|
// EXAMPLE
|
||||||
|
// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
|
||||||
|
// {
|
||||||
|
// int c;
|
||||||
|
//
|
||||||
|
// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
|
||||||
|
// {
|
||||||
|
// switch (c)
|
||||||
|
// {
|
||||||
|
// case _T('a'):
|
||||||
|
// TRACE(_T("option a\n"));
|
||||||
|
// //
|
||||||
|
// // set some flag here
|
||||||
|
// //
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case _T('B'):
|
||||||
|
// TRACE( _T("option B\n"));
|
||||||
|
// //
|
||||||
|
// // set some other flag here
|
||||||
|
// //
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case _T('n'):
|
||||||
|
// TRACE(_T("option n: value=%d\n"), atoi(optarg));
|
||||||
|
// //
|
||||||
|
// // do something with value here
|
||||||
|
// //
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case _T('?'):
|
||||||
|
// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
|
||||||
|
// return FALSE;
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// default:
|
||||||
|
// TRACE(_T("WARNING: no handler for option %c\n"), c);
|
||||||
|
// return FALSE;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// //
|
||||||
|
// // check for non-option args here
|
||||||
|
// //
|
||||||
|
// return TRUE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TCHAR *optarg; // global argument pointer
|
||||||
|
int optind = 0; // global argv index
|
||||||
|
|
||||||
|
int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
|
||||||
|
{
|
||||||
|
static TCHAR *next = NULL;
|
||||||
|
if (optind == 0)
|
||||||
|
next = NULL;
|
||||||
|
|
||||||
|
optarg = NULL;
|
||||||
|
|
||||||
|
if (next == NULL || *next == _T('\0'))
|
||||||
|
{
|
||||||
|
if (optind == 0)
|
||||||
|
optind++;
|
||||||
|
|
||||||
|
if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0'))
|
||||||
|
{
|
||||||
|
optarg = NULL;
|
||||||
|
if (optind < argc)
|
||||||
|
optarg = argv[optind];
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_tcscmp(argv[optind], _T("--")) == 0)
|
||||||
|
{
|
||||||
|
optind++;
|
||||||
|
optarg = NULL;
|
||||||
|
if (optind < argc)
|
||||||
|
optarg = argv[optind];
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = argv[optind];
|
||||||
|
next++; // skip past -
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCHAR c = *next++;
|
||||||
|
TCHAR *cp = _tcschr(optstring, c);
|
||||||
|
|
||||||
|
if (cp == NULL || c == _T(':'))
|
||||||
|
return _T('?');
|
||||||
|
|
||||||
|
cp++;
|
||||||
|
if (*cp == _T(':'))
|
||||||
|
{
|
||||||
|
if (*next != _T('\0'))
|
||||||
|
{
|
||||||
|
optarg = next;
|
||||||
|
next = NULL;
|
||||||
|
}
|
||||||
|
else if (optind < argc)
|
||||||
|
{
|
||||||
|
optarg = argv[optind];
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _T('?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// XGetopt.h Version 1.2
|
||||||
|
//
|
||||||
|
// Author: Hans Dietrich
|
||||||
|
// hdietrich2@hotmail.com
|
||||||
|
//
|
||||||
|
// This software is released into the public domain.
|
||||||
|
// You are free to use it in any way you like.
|
||||||
|
//
|
||||||
|
// This software is provided "as is" with no expressed
|
||||||
|
// or implied warranty. I accept no liability for any
|
||||||
|
// damage or loss of business that this software may cause.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef XGETOPT_H
|
||||||
|
#define XGETOPT_H
|
||||||
|
|
||||||
|
extern int optind, opterr;
|
||||||
|
extern TCHAR *optarg;
|
||||||
|
|
||||||
|
int getopt(int argc, TCHAR *argv[], TCHAR *optstring);
|
||||||
|
|
||||||
|
#endif //XGETOPT_H
|
||||||
+320
@@ -0,0 +1,320 @@
|
|||||||
|
// dat2.cpp : Defines the entry point for the console application.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "dat2.h"
|
||||||
|
#include "DatFile1.h"
|
||||||
|
#include "DatFile2.h"
|
||||||
|
#include "XGetopt.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
Command g_Command = COMMAND_UNKNOWN;
|
||||||
|
int g_nCompressMethod = 9;
|
||||||
|
BOOL g_bRecurseIntoDir = FALSE;
|
||||||
|
BOOL g_bExtractWithoutPaths = FALSE;
|
||||||
|
CString g_strOutFolder;
|
||||||
|
CString g_strDatFileName;
|
||||||
|
CStringArray g_FileList;
|
||||||
|
BOOL g_bFallout1Dat = FALSE;
|
||||||
|
CString g_strTargetDir = "";
|
||||||
|
|
||||||
|
// Dat-file
|
||||||
|
CDatFile1 g_DatFile1;
|
||||||
|
CDatFile2 g_DatFile2;
|
||||||
|
CDatFileBase* g_pDatFile = NULL;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
void PrintUsage(char* lpszFileName);
|
||||||
|
int ParseCommandLine(int argc, char* argv[]);
|
||||||
|
|
||||||
|
// The one and only application object
|
||||||
|
CWinApp theApp;
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {
|
||||||
|
printf("Fatal Error: MFC initialization failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Fallout DAT-files packer/unpacker, version 2.32\n");
|
||||||
|
printf("Copyright (C) Anchorite (TeamX), 2004-2006\n");
|
||||||
|
printf("anchorite2001@yandex.ru\n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// for(int i = 0; i < argc; i++) {
|
||||||
|
// printf("argv[%d] = %s\n", i, argv[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nResult = ParseCommandLine(argc, argv);
|
||||||
|
|
||||||
|
switch(nResult) {
|
||||||
|
case -1: {
|
||||||
|
printf("Error: Invalid command\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -2: {
|
||||||
|
printf("Error: Name of output directory is omitted\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -3: {
|
||||||
|
printf("Error: Name of dat-file is omitted\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -4: {
|
||||||
|
printf("Error: List of files is omitted\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -5: {
|
||||||
|
printf("Error: Unable open response file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nResult = 0;
|
||||||
|
UINT nOpenMode;
|
||||||
|
|
||||||
|
switch(g_Command) {
|
||||||
|
case COMMAND_EXTRACT:
|
||||||
|
nOpenMode = CFile::modeRead | CFile::shareDenyWrite;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_DELETE:
|
||||||
|
nOpenMode = CFile::modeReadWrite | CFile::shareDenyWrite;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_LIST:
|
||||||
|
nOpenMode = CFile::modeRead | CFile::shareDenyWrite;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_SHRINK:
|
||||||
|
nOpenMode = CFile::modeReadWrite | CFile::shareDenyWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_Command == COMMAND_ADD) {
|
||||||
|
if (g_bFallout1Dat) {
|
||||||
|
g_pDatFile = &g_DatFile1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_pDatFile = &g_DatFile2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (g_DatFile2.Open(g_strDatFileName, nOpenMode)) {
|
||||||
|
g_pDatFile = &g_DatFile2;
|
||||||
|
}
|
||||||
|
else if (g_DatFile1.Open(g_strDatFileName, nOpenMode)) {
|
||||||
|
g_pDatFile = &g_DatFile1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Error: Unable open file %s\n", LPCTSTR(g_strDatFileName));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(g_Command) {
|
||||||
|
case COMMAND_ADD:
|
||||||
|
nResult = OnAdd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_EXTRACT:
|
||||||
|
nResult = OnExtract();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_DELETE:
|
||||||
|
nResult = OnDelete();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_LIST:
|
||||||
|
nResult = OnList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMAND_SHRINK:
|
||||||
|
nResult = OnShrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("Flushing buffers...\n");
|
||||||
|
g_pDatFile->Flush();
|
||||||
|
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintUsage(char* lpszFileName)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <command> [options] [-t dir] [-d dir] dat-file [list | @response-file]\n", lpszFileName);
|
||||||
|
printf("\n");
|
||||||
|
printf("Commands\n");
|
||||||
|
printf(" a: Add files to dat-file. Create new if dat-file not exist\n");
|
||||||
|
printf(" x: Extract files from dat-file\n");
|
||||||
|
printf(" d: Delete files from dat-file (only info about files)\n");
|
||||||
|
printf(" l: List files in dat-file\n");
|
||||||
|
printf(" k: Shrink dat-file\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Options\n");
|
||||||
|
printf(" -s: create Fallout 1 dat-file\n");
|
||||||
|
printf(" -r: recurse into directories\n");
|
||||||
|
printf(" -0..9: Compression method\n");
|
||||||
|
printf(" (Fallout1: 0 - store, other numbers - compress (default)\n");
|
||||||
|
printf(" (Fallout2: 0 - store, 1 - best speed, 9 - best compression (default)\n");
|
||||||
|
printf(" -p: extract without paths\n");
|
||||||
|
printf(" -d: extract files into specified directory\n");
|
||||||
|
printf(" -t: add files to specified directory of dat-file\n");
|
||||||
|
printf(" --: end of options\n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParseCommandLine(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Command
|
||||||
|
if (memcmp(argv[1], "a", lstrlen(argv[1])) == 0) {
|
||||||
|
g_Command = COMMAND_ADD;
|
||||||
|
}
|
||||||
|
else if (memcmp(argv[1], "x", lstrlen(argv[1])) == 0) {
|
||||||
|
g_Command = COMMAND_EXTRACT;
|
||||||
|
}
|
||||||
|
else if (memcmp(argv[1], "d", lstrlen(argv[1])) == 0) {
|
||||||
|
g_Command = COMMAND_DELETE;
|
||||||
|
}
|
||||||
|
else if (memcmp(argv[1], "l", lstrlen(argv[1])) == 0) {
|
||||||
|
g_Command = COMMAND_LIST;
|
||||||
|
}
|
||||||
|
else if (memcmp(argv[1], "k", lstrlen(argv[1])) == 0) {
|
||||||
|
g_Command = COMMAND_SHRINK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while((c = getopt(argc, argv, "r0123456789pd:st:")) != EOF) {
|
||||||
|
switch(c) {
|
||||||
|
case 'r':
|
||||||
|
g_bRecurseIntoDir = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
g_nCompressMethod = c - '0';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
g_bExtractWithoutPaths = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
g_strOutFolder = optarg;
|
||||||
|
|
||||||
|
if ((!g_strOutFolder.IsEmpty()) && (g_strOutFolder.Right(1) != "\\")) {
|
||||||
|
g_strOutFolder += "\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
g_bFallout1Dat = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
g_strTargetDir = optarg;
|
||||||
|
|
||||||
|
if ((!g_strTargetDir.IsEmpty()) && (g_strTargetDir.Right(1) != "\\")) {
|
||||||
|
g_strTargetDir += "\\";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
default: // No more options
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dat-file
|
||||||
|
if (optind < argc) {
|
||||||
|
g_strDatFileName = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strDatFileName.IsEmpty()) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((g_strDatFileName.Right(4).MakeLower() != ".dat") || (g_strDatFileName == ".dat")) {
|
||||||
|
g_strDatFileName += ".dat";
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of files
|
||||||
|
CString strArgument;
|
||||||
|
|
||||||
|
for(int i = optind + 1; i < argc; i++) {
|
||||||
|
strArgument = argv[i];
|
||||||
|
|
||||||
|
int nArglength = strArgument.GetLength();
|
||||||
|
|
||||||
|
if ((i == optind + 1) && (nArglength > 1) && (strArgument[0] == '@')) {
|
||||||
|
CStdioFile fileResponse;
|
||||||
|
|
||||||
|
if (!fileResponse.Open(strArgument.Right(nArglength - 1), CFile::modeRead | CFile::shareDenyWrite | CFile::typeText)) {
|
||||||
|
return -5;
|
||||||
|
};
|
||||||
|
|
||||||
|
CArchive arResponse(&fileResponse, CArchive::load);
|
||||||
|
|
||||||
|
while(arResponse.ReadString(strArgument)) {
|
||||||
|
if (!strArgument.IsEmpty()) {
|
||||||
|
g_FileList.Add(strArgument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_FileList.Add(strArgument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((g_FileList.GetSize() == 0)) {
|
||||||
|
if (g_Command == COMMAND_EXTRACT) {
|
||||||
|
g_FileList.Add("*");
|
||||||
|
}
|
||||||
|
else if ((g_Command != COMMAND_LIST) && (g_Command != COMMAND_SHRINK)) {
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for(int i = 0; i < g_FileList.GetSize(); i++) {
|
||||||
|
// printf("g_FileList[%d] = %s\n", i, g_FileList[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user