2 Commits
Author SHA1 Message Date
Deorder 3855899330 Added exception handling making the dll more reliable 2019-04-17 01:36:22 +02:00
Deorder 6c3a9234e4 Cleaned up test source 2019-04-15 04:26:29 +02:00
6 changed files with 338 additions and 145 deletions
+4 -6
View File
@@ -2,16 +2,16 @@
#include "libbsarch.h"
using namespace std::string_literals;
#pragma comment(lib, "libbsarch")
int main() {
bsa_archive_t archive = bsa_create();
bsa_load_from_file(archive, L"test_read.bsa");
bsa_result_message_t result = bsa_load_from_file(archive, L"test_read.bsa");
if(result.code < 0)
printf("%ls\n", result.text);
bsa_close(archive);
bsa_entry_list_t entries = bsa_entry_list_create();
bsa_entry_list_add(entries, L"textures\\grass\\test.dds");
@@ -23,6 +23,4 @@ int main() {
bsa_entry_list_free(entries);
bsa_free(archive);
printf("test\n");
}
+30 -30
View File
@@ -8,16 +8,16 @@ BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create() {
return NULL;
}
BSARCH_DLL_API(void) bsa_entry_list_free(bsa_entry_list_t entry_list) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list) {
return { 0 };
}
BSARCH_DLL_API(uint32_t) bsa_entry_list_count(bsa_entry_list_t entry_list) {
return 0;
}
BSARCH_DLL_API(void) bsa_entry_list_add(bsa_entry_list_t entry_list, const wchar_t *entry_string) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_add(bsa_entry_list_t entry_list, const wchar_t *entry_string) {
return { 0 };
}
BSARCH_DLL_API(uint32_t) bsa_entry_list_get(bsa_entry_list_t entry_list, uint32_t index, uint32_t string_buffer_size, const wchar_t *string_buffer) {
@@ -28,68 +28,68 @@ BSARCH_DLL_API(bsa_archive_t) bsa_create() {
return NULL;
}
BSARCH_DLL_API(void) bsa_free(bsa_archive_t archive) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_create_archive(bsa_archive_t archive, const wchar_t *filename, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list) {
return;
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) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_save(bsa_archive_t archive) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename) {
return;
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) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_file_data_t data) {
return;
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) {
return { 0 };
}
BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *filename) {
return NULL;
}
BSARCH_DLL_API(bsa_file_data_result_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_record(bsa_archive_t archive, bsa_file_record_t file_record) {
return { 0 };
}
BSARCH_DLL_API(bsa_file_data_result_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 *filename) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_file_data_free(bsa_archive_t archive, bsa_file_data_result_t file_data_result) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, bsa_result_buffer_t file_data_result) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context) {
return { 0 };
}
BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *filename) {
return false;
}
BSARCH_DLL_API(void) bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder) {
return;
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) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list) {
return { 0 };
}
BSARCH_DLL_API(void) bsa_close(bsa_archive_t archive) {
return;
BSARCH_DLL_API(bsa_result_message_t) bsa_close(bsa_archive_t archive) {
return { 0 };
}
BSARCH_DLL_API(uint32_t) bsa_filename_get(bsa_archive_t archive, uint32_t string_buffer_size, const wchar_t *string_buffer) {
+212 -47
View File
@@ -8,134 +8,299 @@ uses
wbStreams,
wbBSArchive;
type
TwbBSResultCode = (
BSA_RESULT_NONE = 0,
BSA_RESULT_EXCEPTION = -1
);
TwbBSResultMessage = packed record
code: ShortInt;
text: array[0..1023] of WideChar;
end;
TwbBSResultMessageBuffer = packed record
buffer: TwbBSResultBuffer;
message: TwbBSResultMessage;
end;
{Shared}
function string_to_cstring(aString: String; const aStringBufferSize: Cardinal;
const aStringBuffer: PChar): Cardinal; stdcall;
function string_to_cstring(
aString: String;
const aStringBufferSize: Cardinal;
const aStringBuffer: PChar
): Integer; stdcall;
begin
Result := Min(aStringBufferSize, Length(AString));
if (aStringBuffer <> nil) and (Result > 0) then
Move(AString[1], aStringBuffer^, Result * SizeOf(Char));
Move(AString[1], aStringBuffer^, Result * SizeOf(WideChar));
end;
function string_to_cstring_end(
aString: String;
const aStringBufferSize: Cardinal;
const aStringBuffer: PChar
): Integer; stdcall;
begin
Result := Min(aStringBufferSize - 1, Length(AString));
if (aStringBuffer <> nil) and (Result > 0) then
begin
Move(AString[1], aStringBuffer^, Result * SizeOf(WideChar));
aStringBuffer[Result] := #0;
end;
end;
procedure exception_handler(E: Exception; var Result: TwbBSResultMessage); stdcall;
begin
Result.code := ShortInt(BSA_RESULT_EXCEPTION);
string_to_cstring_end(E.Message, Length(Result.text), Result.text);
end;
procedure buffer_exception_handler(E: Exception; var Result: TwbBSResultMessageBuffer); stdcall;
begin
Result.buffer.size := 0;
Result.buffer.data := nil;
Result.message.code := ShortInt(BSA_RESULT_EXCEPTION);
string_to_cstring_end(E.Message, Length(Result.message.text), Result.message.text);
end;
{BSA File List}
function bsa_entry_list_create:Pointer; stdcall;
begin
Result := TwbBSEntryList.Create;
try
Result := TwbBSEntryList.Create;
except
Result := nil;
end;
end;
procedure bsa_entry_list_free(obj: Pointer); stdcall;
function bsa_entry_list_free(obj: Pointer): TwbBSResultMessage; stdcall;
begin
TwbBSEntryList(obj).Clear();
TwbBSEntryList(obj).free;
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSEntryList(obj).Clear();
TwbBSEntryList(obj).free;
except
on E: Exception do
exception_handler(E, Result);
end;
end;
function bsa_entry_list_count(obj: Pointer): Cardinal; stdcall;
function bsa_entry_list_count(obj: Pointer): Integer; stdcall;
begin
Result := TwbBSEntryList(obj).Count;
try
Result := TwbBSEntryList(obj).Count;
except
Result := Ord(BSA_RESULT_EXCEPTION);
end;
end;
procedure bsa_entry_list_add(obj: Pointer; const aEntryString: PChar); stdcall;
function bsa_entry_list_add(obj: Pointer; const aEntryString: PChar): TwbBSResultMessage; stdcall;
begin
TwbBSEntryList(obj).Add(String(aEntryString));
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSEntryList(obj).Add(String(aEntryString));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
function bsa_entry_list_get(obj: Pointer; const aIndex: Cardinal; const aStringBufferSize: Cardinal; const aStringBuffer: PChar): Cardinal; stdcall;
function bsa_entry_list_get(obj: Pointer; const aIndex: Cardinal; const aStringBufferSize: Cardinal; const aStringBuffer: PChar): Integer; stdcall;
begin
Result := string_to_cstring(TwbBSEntryList(obj).Strings[aIndex], aStringBufferSize, aStringBuffer);
try
Result := string_to_cstring_end(TwbBSEntryList(obj).Strings[aIndex], aStringBufferSize, aStringBuffer);
except
Result := Integer(BSA_RESULT_EXCEPTION);
end;
end;
{BSArchive}
function bsa_create:Pointer; stdcall;
begin
Result := TwbBSArchive.Create;
try
Result := TwbBSArchive.Create;
except
Result := nil;
end;
end;
procedure bsa_free(obj: Pointer); stdcall;
function bsa_free(obj: Pointer): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).free;
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).free;
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_load_from_file(obj: Pointer; const aFileName: PChar); stdcall;
function bsa_load_from_file(obj: Pointer; const aFileName: PChar): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).LoadFromFile(String(aFileName));
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).LoadFromFile(String(aFileName));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_create_archive(obj: Pointer; const aFileName: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList); stdcall;
function bsa_create_archive(obj: Pointer; const aFileName: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).CreateArchiveCompat(String(aFileName), aType, aFileList);
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).CreateArchiveCompat(String(aFileName), aType, aFileList);
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_save(obj: Pointer); stdcall;
function bsa_save(obj: Pointer): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).Save;
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).Save;
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_add_file_from_disk(obj: Pointer; const aRootDir, aFileName: PChar); stdcall;
function bsa_add_file_from_disk(obj: Pointer; const aRootDir, aFileName: PChar): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).AddFile(String(aRootDir), String(aFileName));
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).AddFile(String(aRootDir), String(aFileName));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_add_file_from_memory(obj: Pointer; const aFileName: PChar; const aSize: Cardinal; const aData: PByte); stdcall;
function bsa_add_file_from_memory(obj: Pointer; const aFileName: PChar; const aSize: Cardinal; const aData: PByte): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).AddFileCompat(String(aFileName), aSize, aData);
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).AddFileCompat(String(aFileName), aSize, aData);
except
on E: Exception do
exception_handler(E, Result);
end;
end;
function bsa_find_file_record(obj: Pointer; const aFileName: PChar): Pointer; stdcall;
begin
Result := TwbBSArchive(obj).FindFileRecord(String(aFileName));
try
Result := TwbBSArchive(obj).FindFileRecord(String(aFileName));
except
Result := nil
end;
end;
function bsa_extract_file_data_by_record(obj: Pointer; aFileRecord: Pointer): TwbBSFileDataResult; stdcall;
function bsa_extract_file_data_by_record(obj: Pointer; aFileRecord: Pointer): TwbBSResultMessageBuffer; stdcall;
begin
Result := TwbBSArchive(obj).ExtractFileDataCompat(aFileRecord);
Result.message.code := Ord(BSA_RESULT_NONE);
try
Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(aFileRecord);
except
on E: Exception do
buffer_exception_handler(E, Result);
end;
end;
function bsa_extract_file_data_by_filename(obj: Pointer; const aFileName: PChar): TwbBSFileDataResult; stdcall;
function bsa_extract_file_data_by_filename(obj: Pointer; const aFileName: PChar): TwbBSResultMessageBuffer; stdcall;
begin
Result := TwbBSArchive(obj).ExtractFileDataCompat(String(aFileName));
Result.message.code := Ord(BSA_RESULT_NONE);
try
Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(String(aFileName));
except
on E: Exception do
buffer_exception_handler(E, Result);
end;
end;
procedure bsa_file_data_free(obj: Pointer; fileDataResult: TwbBSFileDataResult); stdcall;
function bsa_file_data_free(obj: Pointer; fileDataResult: TwbBSResultMessageBuffer): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).ReleaseFileDataCompat(fileDataResult);
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).ReleaseFileDataCompat(fileDataResult.buffer);
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_extract_file(obj: Pointer; const aFileName, aSaveAs: PChar); stdcall;
function bsa_extract_file(obj: Pointer; const aFileName, aSaveAs: PChar): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).ExtractFile(String(aFileName), String(aSaveAs));
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).ExtractFile(String(aFileName), String(aSaveAs));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_iterate_files(obj: Pointer; aProc: TBSFileIterationProcCompat; aContext: Pointer); stdcall;
function bsa_iterate_files(obj: Pointer; aProc: TBSFileIterationProcCompat; aContext: Pointer): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).IterateFilesCompat(aProc, aContext);
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).IterateFilesCompat(aProc, aContext);
except
on E: Exception do
exception_handler(E, Result);
end;
end;
function bsa_file_exists(obj: Pointer; const aFileName: string): Boolean; stdcall;
begin
Result := TwbBSArchive(obj).FileExists(aFileName);
try
Result := TwbBSArchive(obj).FileExists(aFileName);
except
Result := False;
end;
end;
procedure bsa_get_resource_list(obj: Pointer; const aEntryResultList: TwbBSEntryList; aFolder: PChar); stdcall;
function bsa_get_resource_list(obj: Pointer; const aEntryResultList: TwbBSEntryList; aFolder: PChar): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).ResourceListCompat(aEntryResultList, String(aFolder));
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).ResourceListCompat(aEntryResultList, String(aFolder));
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_resolve_hash(obj: Pointer; const aHash: UInt64; const aEntryResultList: TwbBSEntryList); stdcall;
function bsa_resolve_hash(obj: Pointer; const aHash: UInt64; const aEntryResultList: TwbBSEntryList): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).ResolveHashCompat(aHash, aEntryResultList);
end;
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).ResolveHashCompat(aHash, aEntryResultList);
except
on E: Exception do
exception_handler(E, Result);
end;
end;
procedure bsa_close(obj: Pointer); stdcall;
function bsa_close(obj: Pointer): TwbBSResultMessage; stdcall;
begin
TwbBSArchive(obj).Close;
Result.code := Ord(BSA_RESULT_NONE);
try
TwbBSArchive(obj).Close;
except
on E: Exception do
exception_handler(E, Result);
end;
end;
function bsa_filename_get(obj: Pointer; const aStringBufferSize: Cardinal; const aStringBuffer: PChar): Cardinal; stdcall;
begin
Result := string_to_cstring(TwbBSArchive(obj).FileName, aStringBufferSize, aStringBuffer);
Result := string_to_cstring_end(TwbBSArchive(obj).FileName, aStringBufferSize, aStringBuffer);
end;
function bsa_archive_type_get(obj: Pointer): TBSArchiveType; stdcall;
@@ -150,7 +315,7 @@ end;
function bsa_format_name_get(obj: Pointer; const aStringBufferSize: Cardinal; const aStringBuffer: PChar): Cardinal; stdcall;
begin
Result := string_to_cstring(TwbBSArchive(obj).FormatName, aStringBufferSize, aStringBuffer);
Result := string_to_cstring_end(TwbBSArchive(obj).FormatName, aStringBufferSize, aStringBuffer);
end;
function bsa_file_count_get(obj: Pointer): Cardinal; stdcall;
+4 -3
View File
@@ -3,12 +3,12 @@
<ProjectGuid>{381E4D59-4D34-46B3-B039-1B3C3ABEC58F}</ProjectGuid>
<MainSource>libbsarch.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Config Condition="'$(Config)'==''">Release</Config>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Library</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>18.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
@@ -121,7 +121,8 @@
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Manifest_File>(None)</Manifest_File>
<DCC_ExeOutput>X64\Debug\</DCC_ExeOutput>
<Debugger_HostApplication>X64\Debug\libbsarch-visualstudio-test.exe</Debugger_HostApplication>
<Debugger_HostApplication>D:\Projects\libbsarch\x64\Debug\libbsarch-visualstudio-test.exe</Debugger_HostApplication>
<Debugger_CWD>D:\Projects\libbsarch\x64\Debug</Debugger_CWD>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
+49 -20
View File
@@ -12,8 +12,19 @@
#define BSARCH_DLL_API(ReturnType) extern "C" __declspec(dllimport) ReturnType __stdcall
#endif
#ifdef __GNUC__
#define PACKED(datastructure) datastructure __attribute__((__packed__))
#else
#define PACKED(datastructure) __pragma(pack(push, 1)) datastructure __pragma(pack(pop))
#endif
typedef enum bsa_result_code_e {
BSA_RESULT_NONE = 0,
BSA_RESULT_EXCEPTION = -1
} bsa_result_code_t;
typedef void* bsa_buffer_t;
typedef void* bsa_archive_t;
typedef void* bsa_file_data_t;
typedef void* bsa_entry_list_t;
typedef void* bsa_file_record_t;
typedef void* bsa_folder_record_t;
@@ -22,15 +33,33 @@ typedef struct bsa_dds_info_s {
uint32_t width, height, mipmaps;
} bsa_dds_info_t;
PACKED (
typedef struct bsa_dds_header_s {
uint32_t magic; // DDS_MAGIC
struct DirectX::DDS_HEADER header;
} bsa_dds_header_t;
)
typedef struct bsa_file_data_result_s {
PACKED (
typedef struct bsa_result_message_s {
int8_t code; // bsa_result_code_t
wchar_t text[1024];
} bsa_result_message_t;
)
PACKED (
typedef struct bsa_result_buffer_s {
uint32_t size;
bsa_file_data_t data;
} bsa_file_data_result_t;
bsa_buffer_t data;
} bsa_result_buffer_t;
)
PACKED (
typedef struct bsa_result_message_buffer_s {
bsa_result_buffer_t buffer;
bsa_result_message_t message;
} bsa_result_message_buffer_t;
)
typedef enum bsa_archive_state_e {
stReading, stWriting
@@ -44,28 +73,28 @@ typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *f
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);
BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create();
BSARCH_DLL_API(void) bsa_entry_list_free(bsa_entry_list_t entry_list);
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list);
BSARCH_DLL_API(uint32_t) bsa_entry_list_count(bsa_entry_list_t entry_list);
BSARCH_DLL_API(void) bsa_entry_list_add(bsa_entry_list_t entry_list, const wchar_t *entry_string);
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_add(bsa_entry_list_t entry_list, const wchar_t *entry_string);
BSARCH_DLL_API(uint32_t) bsa_entry_list_get(bsa_entry_list_t entry_list, uint32_t index, uint32_t string_buffer_size, const wchar_t *string_buffer);
BSARCH_DLL_API(bsa_archive_t) bsa_create();
BSARCH_DLL_API(void) bsa_free(bsa_archive_t archive);
BSARCH_DLL_API(void) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename);
BSARCH_DLL_API(void) 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(void) bsa_save(bsa_archive_t archive);
BSARCH_DLL_API(void) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename);
BSARCH_DLL_API(void) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_file_data_t data);
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_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_file_data_result_t) bsa_extract_file_data_by_record(bsa_archive_t archive, bsa_file_record_t file_record);
BSARCH_DLL_API(bsa_file_data_result_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *filename);
BSARCH_DLL_API(void) bsa_file_data_free(bsa_archive_t archive, bsa_file_data_result_t file_data_result);
BSARCH_DLL_API(void) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as);
BSARCH_DLL_API(void) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context);
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_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_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(void) bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder);
BSARCH_DLL_API(void) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list);
BSARCH_DLL_API(void) bsa_close(bsa_archive_t archive);
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);
BSARCH_DLL_API(uint32_t) bsa_filename_get(bsa_archive_t archive, uint32_t string_buffer_size, const wchar_t *string_buffer);
BSARCH_DLL_API(bsa_archive_type_t) bsa_archive_type_get(bsa_archive_t archive);
+39 -39
View File
@@ -291,9 +291,9 @@ type
end;
PPackedDataInfo = ^TPackedDataInfo;
TwbBSFileDataResult = record
Size: Cardinal;
Data: PByte;
TwbBSResultBuffer = packed record
size: Cardinal;
data: PByte;
end;
TwbBSEntryList = class(TStringList);
@@ -349,9 +349,9 @@ type
procedure AddFile(const aRootDir, aFileName: string); overload;
procedure AddFileCompat(const aFileName: string; const aSize: Cardinal; const aData: PByte);
function FindFileRecord(const aFileName: string): Pointer;
function ExtractFileDataCompat(aFileRecord: Pointer): TwbBSFileDataResult; overload;
function ExtractFileDataCompat(const aFileName: string): TwbBSFileDataResult; overload;
procedure ReleaseFileDataCompat(fileDataResult: TwbBSFileDataResult);
function ExtractFileDataCompat(aFileRecord: Pointer): TwbBSResultBuffer; overload;
function ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer; overload;
procedure ReleaseFileDataCompat(fileDataResult: TwbBSResultBuffer);
procedure ExtractFile(const aFileName, aSaveAs: string);
procedure IterateFilesCompat(aProc: TBSFileIterationProcCompat; aContext: Pointer = nil);
function FileExists(const aFileName: string): Boolean;
@@ -1868,7 +1868,7 @@ begin
end;
// Modified: Version for use in non-Borland C/C++ (Result not automatically freed)
function TwbBSArchive.ExtractFileDataCompat(aFileRecord: Pointer): TwbBSFileDataResult;
function TwbBSArchive.ExtractFileDataCompat(aFileRecord: Pointer): TwbBSResultBuffer;
var
FileTES3: PwbBSFileTES3;
FileTES4: PwbBSFileTES4;
@@ -1892,9 +1892,9 @@ begin
baTES3: begin
FileTES3 := aFileRecord;
fStream.Position := fDataOffset + FileTES3.Offset;
Result.Size := FileTES3.Size;
GetMem(Result.Data, FileTES3.Size);
fStream.ReadBuffer(Result.Data[0], Result.Size);
Result.size := FileTES3.Size;
GetMem(Result.data, FileTES3.Size);
fStream.ReadBuffer(Result.data[0], Result.size);
end;
baTES4, baFO3, baSSE: begin
@@ -1914,19 +1914,19 @@ begin
if bCompressed then begin
// reading uncompressed size
Result.Size := fStream.ReadCardinal;
GetMem(Result.Data, Result.Size);
Result.size := fStream.ReadCardinal;
GetMem(Result.data, Result.size);
dec(size, SizeOf(Cardinal));
if (Result.Size > 0) and (size > 0) then begin
if (Result.size > 0) and (size > 0) then begin
SetLength(Buffer, size);
fStream.ReadBuffer(Buffer[0], Length(Buffer));
if Assigned(Sync) then
Sync.EndWrite;
try
if fType = baSSE then
lz4DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.Data[0], Result.Size)
lz4DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.data[0], Result.size)
else try
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.Data[0], Result.Size);
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.data[0], Result.size);
except
// ignore zlib's Buffer error since it happens in vanilla "Fallout - Misc.bsa"
// Bethesda probably used old buggy zlib version when packing it
@@ -1939,10 +1939,10 @@ begin
end;
end
else begin
Result.Size := size;
GetMem(Result.Data, Result.Size);
Result.size := size;
GetMem(Result.data, Result.size);
if size > 0 then
fStream.ReadBuffer(Result.Data[0], Result.Size);
fStream.ReadBuffer(Result.data[0], Result.size);
end;
end;
@@ -1952,21 +1952,21 @@ begin
if FileFO4.PackedSize <> 0 then begin
SetLength(Buffer, FileFO4.PackedSize);
fStream.ReadBuffer(Buffer[0], Length(Buffer));
Result.Size := FileFO4.Size;
GetMem(Result.Data, Result.Size);
Result.size := FileFO4.Size;
GetMem(Result.data, Result.size);
if Assigned(Sync) then
Sync.EndWrite;
try
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.Data[0], Result.Size);
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.data[0], Result.size);
finally
if Assigned(Sync) then
Sync.BeginWrite;
end;
end
else begin
Result.Size := FileFO4.Size;
GetMem(Result.Data, Result.Size);
fStream.ReadBuffer(Result.Data[0], Result.Size);
Result.size := FileFO4.Size;
GetMem(Result.data, Result.size);
fStream.ReadBuffer(Result.data[0], Result.size);
end;
end;
@@ -1977,10 +1977,10 @@ begin
for i := Low(FileFO4.TexChunks) to High(FileFO4.TexChunks) do
Inc(TexSize, FileFO4.TexChunks[i].Size);
Result.Size := Texsize;
GetMem(Result.Data, Result.Size);
Result.size := Texsize;
GetMem(Result.data, Result.size);
DDSHeader := @Result.Data[0];
DDSHeader := @Result.data[0];
DDSHeader.Magic := MAGIC_DDS;
DDSHeader.dwSize := SizeOf(TDDSHeader) - SizeOf(TMagic4);
DDSHeader.dwWidth := FileFO4.Width;
@@ -1993,7 +1993,7 @@ begin
DDSHeader.dwCaps := DDSHeader.dwCaps or DDSCAPS_MIPMAP or DDSCAPS_COMPLEX;
DDSHeader.dwDepth := 1;
DDSHeaderDX10 := @Result.Data[SizeOf(TDDSHeader)];
DDSHeaderDX10 := @Result.data[SizeOf(TDDSHeader)];
DDSHeaderDX10.resourceDimension := DDS_DIMENSION_TEXTURE2D;
DDSHeaderDX10.arraySize := 1;
@@ -2159,9 +2159,9 @@ begin
end;
TexSize := SizeOf(TDDSHeader);
if DDSHeader.ddspf.dwFourCC = MAGIC_DX10 then begin
ReallocMem(Result.Data, Result.Size + SizeOf(TDDSHeaderDX10));
ReallocMem(Result.data, Result.size + SizeOf(TDDSHeaderDX10));
Inc(TexSize, SizeOf(TDDSHeaderDX10));
Result.Size := TexSize;
Result.size := TexSize;
end;
// append chunks
for i := Low(FileFO4.TexChunks) to High(FileFO4.TexChunks) do with FileFO4.TexChunks[i] do begin
@@ -2173,7 +2173,7 @@ begin
if Assigned(Sync) then
Sync.EndWrite;
try
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.Data[TexSize], Size);
DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result.data[TexSize], Size);
finally
if Assigned(Sync) then
Sync.BeginWrite;
@@ -2181,9 +2181,9 @@ begin
end
// uncompressed chunk
else
fStream.ReadBuffer(Result.Data[TexSize], Size);
fStream.ReadBuffer(Result.data[TexSize], Size);
Inc(TexSize, Size);
Result.Size := TexSize;
Result.size := TexSize;
end;
end
@@ -2197,7 +2197,7 @@ begin
end;
// Modified: Version for use in non-Borland C/C++
function TwbBSArchive.ExtractFileDataCompat(const aFileName: string): TwbBSFileDataResult;
function TwbBSArchive.ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer;
var
FileRecord: Pointer;
begin
@@ -2213,16 +2213,16 @@ begin
end;
// Addded: For use in non-Borland C/C++
procedure TwbBSArchive.ReleaseFileDataCompat(fileDataResult: TwbBSFileDataResult);
procedure TwbBSArchive.ReleaseFileDataCompat(fileDataResult: TwbBSResultBuffer);
begin
FreeAndNil(fileDataResult.Data);
fileDataResult.Size := 0;
FreeAndNil(fileDataResult.data);
fileDataResult.size := 0;
end;
procedure TwbBSArchive.ExtractFile(const aFileName, aSaveAs: string);
var
fs: TFileStream;
fileData: TwbBSFileDataResult;
fileData: TwbBSResultBuffer;
begin
if not (stReading in fStates) then
raise Exception.Create('Archive is not loaded');
@@ -2230,7 +2230,7 @@ begin
fs := TFileStream.Create(aSaveAs, fmCreate);
try
fileData := ExtractFileDataCompat(aFileName);
fs.Write(fileData.Data[0], fileData.Size);
fs.Write(fileData.data[0], fileData.size);
finally
ReleaseFileDataCompat(fileData);
fs.Free;