From c68e39d2a10fbc051e79bc84c2a5ffdc3019be70 Mon Sep 17 00:00:00 2001
From: Deorder <31899960+deorder@users.noreply.github.com>
Date: Wed, 8 May 2019 23:48:46 +0200
Subject: [PATCH] Added way to add files from any source path (without using a
shared/common root) bsa_add_file_from_disk is now bsa_add_file_from_disk_root
Fixed issues with using libbsarch with GCC
---
cpp.hint | 7 ++
libbsarch-visualstudio-test.cpp | 6 +-
libbsarch.cpp | 20 ++--
libbsarch.def | 1 +
libbsarch.dpr | 46 +++++----
libbsarch.dproj | 3 +-
libbsarch.h | 49 +++++-----
libbsarch.vcxproj | 1 +
libbsarch.vcxproj.filters | 1 +
wbBSArchive.pas | 163 +++++++++++++++++---------------
10 files changed, 172 insertions(+), 125 deletions(-)
create mode 100644 cpp.hint
diff --git a/cpp.hint b/cpp.hint
new file mode 100644
index 0000000..460536c
--- /dev/null
+++ b/cpp.hint
@@ -0,0 +1,7 @@
+// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
+// such as names of functions and macros.
+// For more information see https://go.microsoft.com/fwlink/?linkid=865984
+#define PACKED(datastructure) datastructure __attribute__((__packed__))
+#define PACKED(datastructure) __pragma(pack(push, 1)) datastructure __pragma(pack(pop))
+#define BSARCH_DLL_API(ReturnType) extern "C" __declspec(dllexport) ReturnType __stdcall
+#define BSARCH_DLL_API(ReturnType) extern "C" __declspec(dllimport) ReturnType __stdcall
diff --git a/libbsarch-visualstudio-test.cpp b/libbsarch-visualstudio-test.cpp
index b0c5b46..ef4e656 100644
--- a/libbsarch-visualstudio-test.cpp
+++ b/libbsarch-visualstudio-test.cpp
@@ -65,9 +65,13 @@ int main() {
{
bsa_entry_list_t entries = bsa_entry_list_create();
bsa_entry_list_add(entries, L"textures\\grass\\test.dds");
+ bsa_entry_list_add(entries, L"textures\\grass\\test2.dds");
bsa_create_archive(archive, L"test_write.bsa", baSSE, entries);
- bsa_add_file_from_disk(archive, L"files", L"files\\textures\\grass\\test.dds");
+ bsa_add_file_from_disk_root(archive, L"", L"textures\\grass\\test.dds");
+ result = bsa_add_file_from_disk(archive, L"textures\\grass\\test2.dds", L"textures\\grass\\test.dds");
+ if (result.code < 0)
+ printf("%ls\n", result.text);
bsa_save(archive);
bsa_close(archive);
diff --git a/libbsarch.cpp b/libbsarch.cpp
index c49da6d..727f26b 100644
--- a/libbsarch.cpp
+++ b/libbsarch.cpp
@@ -32,11 +32,11 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive) {
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *file_path) {
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *filename, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *file_path, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list) {
return { 0 };
}
@@ -44,15 +44,19 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive) {
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *source_path) {
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_buffer_t data) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk_root(bsa_archive_t archive, const wchar_t* root_dir, const wchar_t* source_path) {
return { 0 };
}
-BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *filename) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *file_path, uint32_t size, bsa_buffer_t data) {
+ return { 0 };
+}
+
+BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *file_path) {
return NULL;
}
@@ -60,7 +64,7 @@ BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_record(bsa_
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *filename) {
+BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *file_path) {
return { 0 };
}
@@ -68,7 +72,7 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, b
return { 0 };
}
-BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as) {
+BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *save_as) {
return { 0 };
}
@@ -76,7 +80,7 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bs
return { 0 };
}
-BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *filename) {
+BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *file_path) {
return false;
}
diff --git a/libbsarch.def b/libbsarch.def
index bc4c94f..3953b92 100644
--- a/libbsarch.def
+++ b/libbsarch.def
@@ -12,6 +12,7 @@ EXPORTS
bsa_create_archive
bsa_save
bsa_add_file_from_disk
+ bsa_add_file_from_disk_root
bsa_add_file_from_memory
bsa_find_file_record
bsa_extract_file_data_by_record
diff --git a/libbsarch.dpr b/libbsarch.dpr
index a79b764..5cc7e75 100644
--- a/libbsarch.dpr
+++ b/libbsarch.dpr
@@ -137,22 +137,22 @@ begin
end;
end;
-function bsa_load_from_file(obj: Pointer; const aFileName: PChar): TwbBSResultMessage; stdcall;
+function bsa_load_from_file(obj: Pointer; const aFilePath: PChar): TwbBSResultMessage; stdcall;
begin
Result.code := Ord(BSA_RESULT_NONE);
try
- TwbBSArchive(obj).LoadFromFile(String(aFileName));
+ TwbBSArchive(obj).LoadFromFile(String(aFilePath));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
-function bsa_create_archive(obj: Pointer; const aFileName: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList): TwbBSResultMessage; stdcall;
+function bsa_create_archive(obj: Pointer; const aFilePath: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList): TwbBSResultMessage; stdcall;
begin
Result.code := Ord(BSA_RESULT_NONE);
try
- TwbBSArchive(obj).CreateArchiveCompat(String(aFileName), aType, aFileList);
+ TwbBSArchive(obj).CreateArchiveCompat(String(aFilePath), aType, aFileList);
except
on E: Exception do
exception_handler(E, Result);
@@ -170,32 +170,43 @@ begin
end;
end;
-function bsa_add_file_from_disk(obj: Pointer; const aRootDir, aFileName: PChar): TwbBSResultMessage; stdcall;
+function bsa_add_file_from_disk_root(obj: Pointer; const aRootDir, aSourcePath: PChar): TwbBSResultMessage; stdcall;
begin
Result.code := Ord(BSA_RESULT_NONE);
try
- TwbBSArchive(obj).AddFile(String(aRootDir), String(aFileName));
+ TwbBSArchive(obj).AddFileDiskRoot(String(aRootDir), String(aSourcePath));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
-function bsa_add_file_from_memory(obj: Pointer; const aFileName: PChar; const aSize: Cardinal; const aData: PByte): TwbBSResultMessage; stdcall;
+function bsa_add_file_from_disk(obj: Pointer; const aFilePath, aSourcePath: PChar): TwbBSResultMessage; stdcall;
begin
Result.code := Ord(BSA_RESULT_NONE);
try
- TwbBSArchive(obj).AddFileCompat(String(aFileName), aSize, aData);
+ TwbBSArchive(obj).AddFileDisk(String(aFilePath), String(aSourcePath));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
-function bsa_find_file_record(obj: Pointer; const aFileName: PChar): Pointer; stdcall;
+function bsa_add_file_from_memory(obj: Pointer; const aFilePath: PChar; const aSize: Cardinal; const aData: PByte): TwbBSResultMessage; stdcall;
+begin
+ Result.code := Ord(BSA_RESULT_NONE);
+ try
+ TwbBSArchive(obj).AddFileDataCompat(String(aFilePath), aSize, aData);
+ except
+ on E: Exception do
+ exception_handler(E, Result);
+ end;
+end;
+
+function bsa_find_file_record(obj: Pointer; const aFilePath: PChar): Pointer; stdcall;
begin
try
- Result := TwbBSArchive(obj).FindFileRecord(String(aFileName));
+ Result := TwbBSArchive(obj).FindFileRecord(String(aFilePath));
except
Result := nil
end;
@@ -212,11 +223,11 @@ begin
end;
end;
-function bsa_extract_file_data_by_filename(obj: Pointer; const aFileName: PChar): TwbBSResultMessageBuffer; stdcall;
+function bsa_extract_file_data_by_filename(obj: Pointer; const aFilePath: PChar): TwbBSResultMessageBuffer; stdcall;
begin
Result.message.code := Ord(BSA_RESULT_NONE);
try
- Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(String(aFileName));
+ Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(String(aFilePath));
except
on E: Exception do
buffer_exception_handler(E, Result);
@@ -234,11 +245,11 @@ begin
end;
end;
-function bsa_extract_file(obj: Pointer; const aFileName, aSaveAs: PChar): TwbBSResultMessage; stdcall;
+function bsa_extract_file(obj: Pointer; const aFilePath, aSaveAs: PChar): TwbBSResultMessage; stdcall;
begin
Result.code := Ord(BSA_RESULT_NONE);
try
- TwbBSArchive(obj).ExtractFile(String(aFileName), String(aSaveAs));
+ TwbBSArchive(obj).ExtractFile(String(aFilePath), String(aSaveAs));
except
on E: Exception do
exception_handler(E, Result);
@@ -256,12 +267,12 @@ begin
end;
end;
-function bsa_file_exists(obj: Pointer; const aFileName: string): Boolean; stdcall;
+function bsa_file_exists(obj: Pointer; const aFilePath: string): Boolean; stdcall;
begin
try
- Result := TwbBSArchive(obj).FileExists(aFileName);
+ Result := TwbBSArchive(obj).FileExists(aFilePath);
except
- Result := False;
+ Result := False;
end;
end;
@@ -401,6 +412,7 @@ exports
bsa_extract_file_data_by_record,
bsa_find_file_record,
bsa_add_file_from_memory,
+ bsa_add_file_from_disk_root,
bsa_add_file_from_disk,
bsa_save,
bsa_create_archive,
diff --git a/libbsarch.dproj b/libbsarch.dproj
index 2629f0e..2b868c1 100644
--- a/libbsarch.dproj
+++ b/libbsarch.dproj
@@ -8,7 +8,7 @@
Library
None
18.6
- Win64
+ Win32
true
@@ -157,6 +157,7 @@
True
True
+ False
12
diff --git a/libbsarch.h b/libbsarch.h
index df1aade..f9da4e6 100644
--- a/libbsarch.h
+++ b/libbsarch.h
@@ -34,32 +34,36 @@ typedef struct bsa_dds_info_s {
} bsa_dds_info_t;
PACKED (
-typedef struct bsa_dds_header_s {
+struct bsa_dds_header_s {
uint32_t magic; // DDS_MAGIC
struct DirectX::DDS_HEADER header;
-} bsa_dds_header_t;
-)
+});
+
+typedef struct bsa_dds_header_s bsa_dds_header_t;
PACKED (
-typedef struct bsa_result_message_s {
+struct bsa_result_message_s {
int8_t code; // bsa_result_code_t
wchar_t text[1024];
-} bsa_result_message_t;
-)
+});
+
+typedef struct bsa_result_message_s bsa_result_message_t;
PACKED (
-typedef struct bsa_result_buffer_s {
+struct bsa_result_buffer_s {
uint32_t size;
bsa_buffer_t data;
-} bsa_result_buffer_t;
-)
+});
+
+typedef struct bsa_result_buffer_s bsa_result_buffer_t;
PACKED (
-typedef struct bsa_result_message_buffer_s {
+struct bsa_result_message_buffer_s {
bsa_result_buffer_t buffer;
bsa_result_message_t message;
-} bsa_result_message_buffer_t;
-)
+});
+
+typedef struct bsa_result_message_buffer_s bsa_result_message_buffer_t;
typedef enum bsa_archive_state_e {
stReading, stWriting
@@ -69,8 +73,8 @@ typedef enum bsa_archive_type_e {
baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds
} bsa_archive_type_t;
-typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *filename, bsa_dds_info_t dds_info);
-typedef bool (*bsa_file_iteration_proc_t)(bsa_archive_t archive, const wchar_t *filename, bsa_file_record_t file_record, bsa_folder_record_t folder_record, void *context);
+typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_dds_info_t dds_info);
+typedef bool (*bsa_file_iteration_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_file_record_t file_record, bsa_folder_record_t folder_record, void *context);
BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create();
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list);
@@ -80,18 +84,19 @@ BSARCH_DLL_API(uint32_t) bsa_entry_list_get(bsa_entry_list_t entry_list, uint32_
BSARCH_DLL_API(bsa_archive_t) bsa_create();
BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive);
-BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename);
-BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *filename, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list);
+BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *file_path);
+BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *file_path, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list);
BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive);
-BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename);
-BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_buffer_t data);
-BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *filename);
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *source_path);
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk_root(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *source_path);
+BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *file_path, uint32_t size, bsa_buffer_t data);
+BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *file_path);
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_record(bsa_archive_t archive, bsa_file_record_t file_record);
-BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *filename);
+BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *file_path);
BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, bsa_result_buffer_t file_data_result);
-BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as);
+BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *save_as);
BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context);
-BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *filename);
+BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *file_path);
BSARCH_DLL_API(bsa_result_message_t) bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder);
BSARCH_DLL_API(bsa_result_message_t) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list);
BSARCH_DLL_API(bsa_result_message_t) bsa_close(bsa_archive_t archive);
diff --git a/libbsarch.vcxproj b/libbsarch.vcxproj
index e480e4e..e9b9ef7 100644
--- a/libbsarch.vcxproj
+++ b/libbsarch.vcxproj
@@ -149,6 +149,7 @@
+
diff --git a/libbsarch.vcxproj.filters b/libbsarch.vcxproj.filters
index 502ec7f..e57e1f7 100644
--- a/libbsarch.vcxproj.filters
+++ b/libbsarch.vcxproj.filters
@@ -24,6 +24,7 @@
Resource Files
+
diff --git a/wbBSArchive.pas b/wbBSArchive.pas
index 01bab0b..6c85067 100644
--- a/wbBSArchive.pas
+++ b/wbBSArchive.pas
@@ -193,11 +193,11 @@ type
TBSArchiveType = (baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds);
TBSArchiveState = (stReading, stWriting);
TBSArchiveStates = set of TBSArchiveState;
- TBSFileIterationProcCompat = function(aArchive: Pointer; const aFileName: PChar;
+ TBSFileIterationProcCompat = function(aArchive: Pointer; const aFilePath: PChar;
aFileRecord: Pointer; aFolderRecord: Pointer; aContext: Pointer): Boolean; stdcall;
TDDSInfo = record Width, Height, MipMaps: Integer; end;
- TBSFileDDSInfoProcCompat = procedure(aArchive: Pointer; const aFileName: PChar;
+ TBSFileDDSInfoProcCompat = procedure(aArchive: Pointer; const aFilePath: PChar;
var aInfo: TDDSInfo); stdcall;
TwbBSHeaderTES3 = packed record
@@ -330,9 +330,9 @@ type
function GetArchiveFormatName: string;
function GetFileCount: Cardinal;
procedure SetArchiveFlags(aFlags: Cardinal);
- function FindFileRecordTES3(const aFileName: string; var aFileIdx: Integer): Boolean;
- function FindFileRecordTES4(const aFileName: string; var aFolderIdx, aFileIdx: Integer): Boolean;
- function FindFileRecordFO4(const aFileName: string; var aFileIdx: Integer): Boolean;
+ function FindFileRecordTES3(const aFilePath: string; var aFileIdx: Integer): Boolean;
+ function FindFileRecordTES4(const aFilePath: string; var aFolderIdx, aFileIdx: Integer): Boolean;
+ function FindFileRecordFO4(const aFilePath: string; var aFileIdx: Integer): Boolean;
function GetDDSMipChunkNum(var aDDSInfo: TDDSInfo): Integer;
function CalcDataHash(aData: Pointer; aLen: Cardinal): TPackedDataHash;
function FindPackedData(aSize: Cardinal; aHash: TPackedDataHash; aFileRecord: Pointer): Boolean;
@@ -342,19 +342,20 @@ type
Sync: IReadWriteSync;
constructor Create;
destructor Destroy; override;
- procedure LoadFromFile(const aFileName: string);
- procedure CreateArchiveCompat(const aFileName: string; aType: TBSArchiveType;
+ procedure LoadFromFile(const aFilePath: string);
+ procedure CreateArchiveCompat(const aFilePath: string; aType: TBSArchiveType;
aFilesList: TwbBSEntryList = nil);
procedure Save;
- procedure AddFile(const aRootDir, aFileName: string); overload;
- procedure AddFileCompat(const aFileName: string; const aSize: Cardinal; const aData: PByte);
- function FindFileRecord(const aFileName: string): Pointer;
+ procedure AddFileDisk(const aFilePath, aSourcePath: string);
+ procedure AddFileDiskRoot(const aRootDir, aSourcePath: string);
+ procedure AddFileDataCompat(const aFilePath: string; const aSize: Cardinal; const aData: PByte);
+ function FindFileRecord(const aFilePath: string): Pointer;
function ExtractFileDataCompat(aFileRecord: Pointer): TwbBSResultBuffer; overload;
- function ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer; overload;
+ function ExtractFileDataCompat(const aFilePath: string): TwbBSResultBuffer; overload;
procedure ReleaseFileDataCompat(fileDataResult: TwbBSResultBuffer);
- procedure ExtractFile(const aFileName, aSaveAs: string);
+ procedure ExtractFile(const aFilePath, aSaveAs: string);
procedure IterateFilesCompat(aProc: TBSFileIterationProcCompat; aContext: Pointer = nil);
- function FileExists(const aFileName: string): Boolean;
+ function FileExists(const aFilePath: string): Boolean;
procedure ResourceListCompat(const aEntryResultList: TwbBSEntryList; aFolder: string = '');
procedure ResolveHashCompat(const aHash: UInt64; const aEntryResultList: TwbBSEntryList);
procedure Close;
@@ -371,11 +372,11 @@ type
property DDSInfoProc: TBSFileDDSInfoProcCompat read fDDSInfoProc write fDDSInfoProc;
end;
-function SplitDirName(const aFileName: string; var Dir, Name: string): Integer;
-function SplitNameExt(const aFileName: string; var Name, Ext: string): Integer;
-function CreateHashTES3(const aFileName: string): UInt64;
-function CreateHashTES4(const aFileName: string): UInt64; overload;
-function CreateHashFO4(const aFileName: string): Cardinal;
+function SplitDirName(const aFilePath: string; var Dir, Name: string): Integer;
+function SplitNameExt(const aFilePath: string; var Name, Ext: string): Integer;
+function CreateHashTES3(const aFilePath: string): UInt64;
+function CreateHashTES4(const aFilePath: string): UInt64; overload;
+function CreateHashFO4(const aFilePath: string): Cardinal;
implementation
@@ -594,35 +595,35 @@ begin
end;
end;
-function SplitDirName(const aFileName: string; var Dir, Name: string): Integer;
+function SplitDirName(const aFilePath: string; var Dir, Name: string): Integer;
begin
- Result := LastCharPos(aFileName, '\');
+ Result := LastCharPos(aFilePath, '\');
if Result = 0 then
- Result := LastCharPos(aFileName, '/');
- Dir := Copy(aFileName, 1, Pred(Result));
- Name := Copy(aFileName, Succ(Result), Length(aFileName) - Result);
+ Result := LastCharPos(aFilePath, '/');
+ Dir := Copy(aFilePath, 1, Pred(Result));
+ Name := Copy(aFilePath, Succ(Result), Length(aFilePath) - Result);
end;
-function SplitNameExt(const aFileName: string; var Name, Ext: string): Integer;
+function SplitNameExt(const aFilePath: string; var Name, Ext: string): Integer;
begin
- Result := LastCharPos(aFileName, '.');
+ Result := LastCharPos(aFilePath, '.');
if Result <> 0 then begin
- Name := Copy(aFileName, 1, Pred(Result));
- Ext := Copy(aFileName, Result, Length(aFileName) - Result + 2);
+ Name := Copy(aFilePath, 1, Pred(Result));
+ Ext := Copy(aFilePath, Result, Length(aFilePath) - Result + 2);
end
else begin
- Name := aFileName;
+ Name := aFilePath;
Ext := '';
end;
end;
-function CreateHashTES3(const aFileName: string): UInt64;
+function CreateHashTES3(const aFilePath: string): UInt64;
var
s: AnsiString;
i, l: integer;
sum, off, temp, n: Cardinal;
begin
- s := AnsiString(aFileName);
+ s := AnsiString(aFilePath);
l := Length(s) shr 1;
sum := 0; off := 0;
@@ -689,22 +690,22 @@ begin
Result := Result + UInt64(hash) shl 32;
end;
-function CreateHashTES4(const aFileName: string): UInt64; overload;
+function CreateHashTES4(const aFilePath: string): UInt64; overload;
var
fname, fext: string;
begin
- SplitNameExt(aFileName, fname, fext);
+ SplitNameExt(aFilePath, fname, fext);
Result := CreateHashTES4(fname, fext);
end;
-function CreateHashFO4(const aFileName: string): Cardinal;
+function CreateHashFO4(const aFilePath: string): Cardinal;
var
i: Integer;
s: AnsiString;
c: AnsiChar;
begin
Result := 0;
- s := AnsiString(aFileName);
+ s := AnsiString(aFilePath);
for i := 1 to Length(s) do begin
c := s[i];
if Byte(c) > 127 then Continue;
@@ -777,12 +778,12 @@ begin
fHeaderTES4.Flags := fHeaderTES4.Flags or ARCHIVE_COMPRESS;
end;
-function TwbBSArchive.FindFileRecordTES3(const aFileName: string; var aFileIdx: Integer): Boolean;
+function TwbBSArchive.FindFileRecordTES3(const aFilePath: string; var aFileIdx: Integer): Boolean;
var
h: UInt64;
i: integer;
begin
- h := CreateHashTES3(aFileName);
+ h := CreateHashTES3(aFilePath);
Result := False;
for i := Low(fFilesTES3) to High(fFilesTES3) do
@@ -793,13 +794,13 @@ begin
end;
end;
-function TwbBSArchive.FindFileRecordTES4(const aFileName: string; var aFolderIdx, aFileIdx: Integer): Boolean;
+function TwbBSArchive.FindFileRecordTES4(const aFilePath: string; var aFolderIdx, aFileIdx: Integer): Boolean;
var
fdir, fname, name, ext: string;
h: UInt64;
i, j: integer;
begin
- if SplitDirName(aFileName, fdir, fname) = 0 then
+ if SplitDirName(aFilePath, fdir, fname) = 0 then
Exit(False);
Result := False;
@@ -829,14 +830,14 @@ begin
end;
end;
-function TwbBSArchive.FindFileRecordFO4(const aFileName: string; var aFileIdx: Integer): Boolean;
+function TwbBSArchive.FindFileRecordFO4(const aFilePath: string; var aFileIdx: Integer): Boolean;
var
fdir, fname, name, ext: string;
hdir, hfile: Cardinal;
hext: TMagic4;
i: integer;
begin
- if SplitDirName(aFileName, fdir, fname) = 0 then
+ if SplitDirName(aFilePath, fdir, fname) = 0 then
Exit(False);
SplitNameExt(fname, name, ext);
@@ -855,7 +856,7 @@ begin
end;
end;
-function TwbBSArchive.FindFileRecord(const aFileName: string): Pointer;
+function TwbBSArchive.FindFileRecord(const aFilePath: string): Pointer;
var
i, j: integer;
begin
@@ -863,11 +864,11 @@ begin
case fType of
baTES3:
- if FindFileRecordTES3(aFileName, i) then Result := @fFilesTES3[i];
+ if FindFileRecordTES3(aFilePath, i) then Result := @fFilesTES3[i];
baTES4, baFO3, baSSE:
- if FindFileRecordTES4(aFileName, i, j) then Result := @fFoldersTES4[i].Files[j];
+ if FindFileRecordTES4(aFilePath, i, j) then Result := @fFoldersTES4[i].Files[j];
baFO4, baFO4dds:
- if FindFileRecordFO4(aFileName, i) then Result := @fFilesFO4[i];
+ if FindFileRecordFO4(aFilePath, i) then Result := @fFilesFO4[i];
end;
end;
@@ -951,14 +952,14 @@ begin
Inc(fPackedDataCount);
end;
-procedure TwbBSArchive.LoadFromFile(const aFileName: string);
+procedure TwbBSArchive.LoadFromFile(const aFilePath: string);
var
i, j: Integer;
begin
if fStates * [stReading, stWriting] <> [] then
Close;
- fStream := TwbReadOnlyCachedFileStream.Create(aFileName, fmOpenRead or fmShareDenyWrite);
+ fStream := TwbReadOnlyCachedFileStream.Create(aFilePath, fmOpenRead or fmShareDenyWrite);
// magic
fMagic := Int2Magic(fStream.ReadCardinal);
@@ -1099,7 +1100,7 @@ begin
end;
- fFileName := aFileName;
+ fFileName := aFilePath;
Include(fStates, stReading);
end;
@@ -1131,7 +1132,7 @@ begin
Result := CompareStr(List[Index1], List[Index2]);
end;
-procedure TwbBSArchive.CreateArchiveCompat(const aFileName: string; aType: TBSArchiveType;
+procedure TwbBSArchive.CreateArchiveCompat(const aFilePath: string; aType: TBSArchiveType;
aFilesList: TwbBSEntryList = nil);
var
HashPairs: array of THashPair;
@@ -1371,8 +1372,8 @@ begin
end;
- fStream := TwbWriteCachedFileStream.Create(aFileName, fmCreate);
- fFileName := aFileName;
+ fStream := TwbWriteCachedFileStream.Create(aFilePath, fmCreate);
+ fFileName := aFilePath;
Include(fStates, stWriting);
// reserve space for the header
@@ -1532,7 +1533,9 @@ begin
Close;
end;
-procedure TwbBSArchive.AddFile(const aRootDir, aFileName: string);
+
+
+procedure TwbBSArchive.AddFileDisk(const aFilePath, aSourcePath: string);
var
fname: string;
i: integer;
@@ -1542,18 +1545,12 @@ begin
if not (stWriting in fStates) then
raise Exception.Create('Archive is not in writing mode');
- i := Length(aRootDir);
- if (i > 1) and (aRootDir[Length(aRootDir)] <> '\') then
- Inc(i);
-
- fname := Copy(aFileName, i + 1, Length(aFileName));
-
- stream := TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone);
+ stream := TFileStream.Create(aSourcePath, fmOpenRead + fmShareDenyNone);
try
GetMem(buffer, stream.Size);
try
stream.Read(buffer^, stream.Size);
- AddFileCompat(fname, stream.Size, buffer);
+ AddFileDataCompat(aFilePath, stream.Size, buffer);
finally
if Assigned(buffer) then
FreeMem(buffer);
@@ -1563,8 +1560,22 @@ begin
end;
end;
+procedure TwbBSArchive.AddFileDiskRoot(const aRootDir, aSourcePath: string);
+var
+ fname: string;
+ i: integer;
+begin
+ i := Length(aRootDir);
+ if (i > 1) and (aRootDir[Length(aRootDir)] <> '\') then
+ Inc(i);
+
+ fname := Copy(aSourcePath, i + 1, Length(aSourcePath));
+
+ AddFileDisk(fname, aSourcePath);
+end;
+
// Modified: Version for use in non-Borland C/C++
-procedure TwbBSArchive.AddFileCompat(const aFileName: string; const aSize: Cardinal; const aData: PByte);
+procedure TwbBSArchive.AddFileDataCompat(const aFilePath: string; const aSize: Cardinal; const aData: PByte);
var
i, j, Off, MipSize, BitsPerPixel: integer;
fdir, fname, name, ext: string;
@@ -1589,8 +1600,8 @@ begin
try
case fType of
baTES3: begin
- if not FindFileRecordTES3(aFileName, i) then
- raise Exception.Create('File not found in files table: ' + aFileName);
+ if not FindFileRecordTES3(aFilePath, i) then
+ raise Exception.Create('File not found in files table: ' + aFilePath);
if FindPackedData(aSize, DataHash, @fFilesTES3[i]) then
Exit;
@@ -1602,8 +1613,8 @@ begin
end;
baTES4, baFO3, baSSE: begin
- if not FindFileRecordTES4(aFileName, i, j) then
- raise Exception.Create('File not found in files table: ' + aFileName);
+ if not FindFileRecordTES4(aFilePath, i, j) then
+ raise Exception.Create('File not found in files table: ' + aFilePath);
if FindPackedData(aSize, DataHash, @fFoldersTES4[i].Files[j]) then
Exit;
@@ -1669,8 +1680,8 @@ begin
end;
baFO4: begin
- if SplitDirName(aFileName, fdir, fname) = 0 then
- raise Exception.Create('File is missing the folder part: ' + aFileName);
+ if SplitDirName(aFilePath, fdir, fname) = 0 then
+ raise Exception.Create('File is missing the folder part: ' + aFilePath);
SplitNameExt(fname, name, ext);
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
@@ -1678,7 +1689,7 @@ begin
i := fHeaderFO4.FileCount;
Inc(fHeaderFO4.FileCount);
// archive2.exe uses /
- fFilesFO4[i].Name := StringReplace(aFileName, '\', '/', [rfReplaceAll]);
+ fFilesFO4[i].Name := StringReplace(aFilePath, '\', '/', [rfReplaceAll]);
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
fFilesFO4[i].NameHash := CreateHashFO4(name);
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
@@ -1711,8 +1722,8 @@ begin
end;
baFO4dds: begin
- if SplitDirName(aFileName, fdir, fname) = 0 then
- raise Exception.Create('File is missing the folder part: ' + aFileName);
+ if SplitDirName(aFilePath, fdir, fname) = 0 then
+ raise Exception.Create('File is missing the folder part: ' + aFilePath);
SplitNameExt(fname, name, ext);
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
@@ -1721,7 +1732,7 @@ begin
i := fHeaderFO4.FileCount;
Inc(fHeaderFO4.FileCount);
// archive2.exe uses /
- fFilesFO4[i].Name := StringReplace(aFileName, '\', '/', [rfReplaceAll]);
+ fFilesFO4[i].Name := StringReplace(aFilePath, '\', '/', [rfReplaceAll]);
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
fFilesFO4[i].NameHash := CreateHashFO4(name);
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
@@ -2197,14 +2208,14 @@ begin
end;
// Modified: Version for use in non-Borland C/C++
-function TwbBSArchive.ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer;
+function TwbBSArchive.ExtractFileDataCompat(const aFilePath: string): TwbBSResultBuffer;
var
FileRecord: Pointer;
begin
if not (stReading in fStates) then
raise Exception.Create('Archive is not loaded');
- FileRecord := FindFileRecord(aFileName);
+ FileRecord := FindFileRecord(aFilePath);
if not Assigned(FileRecord) then
raise Exception.Create('File not found in archive');
@@ -2219,7 +2230,7 @@ begin
fileDataResult.size := 0;
end;
-procedure TwbBSArchive.ExtractFile(const aFileName, aSaveAs: string);
+procedure TwbBSArchive.ExtractFile(const aFilePath, aSaveAs: string);
var
fs: TFileStream;
fileData: TwbBSResultBuffer;
@@ -2229,7 +2240,7 @@ begin
fs := TFileStream.Create(aSaveAs, fmCreate);
try
- fileData := ExtractFileDataCompat(aFileName);
+ fileData := ExtractFileDataCompat(aFilePath);
fs.Write(fileData.data[0], fileData.size);
finally
ReleaseFileDataCompat(fileData);
@@ -2285,9 +2296,9 @@ begin
end;
end;
-function TwbBSArchive.FileExists(const aFileName: string): Boolean;
+function TwbBSArchive.FileExists(const aFilePath: string): Boolean;
begin
- Result := Assigned(FindFileRecord(aFileName));
+ Result := Assigned(FindFileRecord(aFilePath));
end;
procedure TwbBSArchive.Close;