From 95ae85a8ef45d11e222acc8021bc35c55ae39fa6 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Tue, 9 Mar 2021 05:23:37 +0100 Subject: Import project --- CMakeLists.txt | 28 +++++++++ FileSystem.c | 41 ++++++++++++ FileSystem.h | 13 ++++ Hamcore.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Hamcore.h | 37 +++++++++++ Memory.c | 13 ++++ Memory.h | 17 +++++ 7 files changed, 342 insertions(+) create mode 100755 CMakeLists.txt create mode 100755 FileSystem.c create mode 100755 FileSystem.h create mode 100644 Hamcore.c create mode 100644 Hamcore.h create mode 100644 Memory.c create mode 100644 Memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..d508b1a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.11) + +project(libhamcore LANGUAGES C) + +include(TestBigEndian) + +add_library(libhamcore STATIC) + +test_big_endian(BIG_ENDIAN) +if(BIG_ENDIAN) + target_compile_definitions(libhamcore PRIVATE "BYTE_ORDER_BIG_ENDIAN") +endif() + +target_include_directories(libhamcore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_sources(libhamcore + PRIVATE + FileSystem.c + FileSystem.h + Hamcore.c + Memory.c + Memory.h + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/Hamcore.h +) + +find_package(ZLIB REQUIRED) +target_link_libraries(libhamcore PRIVATE ZLIB::ZLIB) diff --git a/FileSystem.c b/FileSystem.c new file mode 100755 index 0000000..b691746 --- /dev/null +++ b/FileSystem.c @@ -0,0 +1,41 @@ +#include "FileSystem.h" + +FILE *FileOpen(const char *path) +{ + if (!path) + { + return NULL; + } + + return fopen(path, "rb"); +} + +bool FileClose(FILE *file) +{ + if (!file) + { + return false; + } + + return fclose(file) == 0; +} + +bool FileRead(FILE *file, void *dst, const size_t size) +{ + if (!file || !dst || size == 0) + { + return false; + } + + return fread(dst, 1, size, file) == size; +} + +bool FileSeek(FILE *file, const size_t offset) +{ + if (!file) + { + return false; + } + + return fseek(file, offset, SEEK_SET) == 0; +} diff --git a/FileSystem.h b/FileSystem.h new file mode 100755 index 0000000..3d61408 --- /dev/null +++ b/FileSystem.h @@ -0,0 +1,13 @@ +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include +#include + +FILE *FileOpen(const char *path); +bool FileClose(FILE *file); + +bool FileRead(FILE *file, void *dst, const size_t size); +bool FileSeek(FILE *file, const size_t offset); + +#endif diff --git a/Hamcore.c b/Hamcore.c new file mode 100644 index 0000000..d32fa71 --- /dev/null +++ b/Hamcore.c @@ -0,0 +1,193 @@ +#include "Hamcore.h" + +#include "FileSystem.h" +#include "Memory.h" + +#include +#include +#include + +#include + +HAMCORE *HamcoreOpen(const char *path) +{ + if (!path) + { + return NULL; + } + + HAMCORE *hamcore = malloc(sizeof(HAMCORE)); + memset(hamcore, 0, sizeof(HAMCORE)); + + hamcore->File = FileOpen(path); + if (!hamcore->File) + { + free(hamcore); + return NULL; + } + + bool ok = false; + + uint8_t header[HAMCORE_HEADER_SIZE]; + if (!FileRead(hamcore->File, header, sizeof(header))) + { + goto FINAL; + } + + if (memcmp(header, HAMCORE_HEADER_DATA, sizeof(header)) != 0) + { + goto FINAL; + } + + uint32_t tmp; + if (!FileRead(hamcore->File, &tmp, sizeof(tmp))) + { + goto FINAL; + } + + HAMCORE_FILES *files = &hamcore->Files; + + files->Num = BigEndian32(tmp); + files->List = malloc(sizeof(HAMCORE_FILE) * files->Num); + memset(files->List, 0, sizeof(HAMCORE_FILE) * files->Num); + + for (size_t i = 0; i < files->Num; ++i) + { + if (!FileRead(hamcore->File, &tmp, sizeof(tmp))) + { + goto FINAL; + } + + HAMCORE_FILE *file = &files->List[i]; + + tmp = BigEndian32(tmp); + file->Path = malloc(tmp); + if (tmp >= 1) + { + memset(file->Path, 0, tmp); + --tmp; + } + + if (!FileRead(hamcore->File, file->Path, tmp)) + { + goto FINAL; + } + + if (!FileRead(hamcore->File, &tmp, sizeof(tmp))) + { + goto FINAL; + } + + file->OriginalSize = BigEndian32(tmp); + + if (!FileRead(hamcore->File, &tmp, sizeof(tmp))) + { + goto FINAL; + } + + file->Size = BigEndian32(tmp); + + if (!FileRead(hamcore->File, &tmp, sizeof(tmp))) + { + goto FINAL; + } + + file->Offset = BigEndian32(tmp); + } + + ok = true; +FINAL: + if (!ok) + { + HamcoreClose(hamcore); + hamcore = NULL; + } + + return hamcore; +} + +void HamcoreClose(HAMCORE *hamcore) +{ + if (!hamcore) + { + return; + } + + FileClose(hamcore->File); + + HAMCORE_FILES *files = &hamcore->Files; + if (!files->List) + { + return; + } + + for (size_t i = 0; i < files->Num; ++i) + { + HAMCORE_FILE *file = &files->List[i]; + if (file->Path) + { + free(file->Path); + } + } + + free(files->List); + free(hamcore); +} + +const HAMCORE_FILE *HamcoreFind(const HAMCORE *hamcore, const char *path) +{ + if (!hamcore || !path) + { + return NULL; + } + + const HAMCORE_FILES *files = &hamcore->Files; + + for (size_t i = 0; i < files->Num; ++i) + { + const HAMCORE_FILE *file = &files->List[i]; + if (strcmp(file->Path, path) == 0) + { + return file; + } + } + + return NULL; +} + +bool HamcoreRead(HAMCORE *hamcore, void *dst, const HAMCORE_FILE *hamcore_file) +{ + if (!hamcore || !dst || !hamcore_file) + { + return false; + } + + if (!FileSeek(hamcore->File, hamcore_file->Offset)) + { + return false; + } + + bool ok = false; + + void *buf = malloc(hamcore_file->Size); + if (!FileRead(hamcore->File, buf, hamcore_file->Size)) + { + goto FINAL; + } + + uLong dst_size = (uLong)hamcore_file->OriginalSize; + if (uncompress(dst, &dst_size, buf, (uLong)hamcore_file->Size) != Z_OK) + { + goto FINAL; + } + + if (dst_size != hamcore_file->OriginalSize) + { + goto FINAL; + } + + ok = true; +FINAL: + free(buf); + return ok; +} diff --git a/Hamcore.h b/Hamcore.h new file mode 100644 index 0000000..8a2e248 --- /dev/null +++ b/Hamcore.h @@ -0,0 +1,37 @@ +#ifndef HAMCORE_H +#define HAMCORE_H + +#include +#include +#include + +#define HAMCORE_HEADER_DATA "HamCore" +#define HAMCORE_HEADER_SIZE 7 + +typedef struct HAMCORE_FILE +{ + char *Path; + size_t Offset; + size_t Size; + size_t OriginalSize; +} HAMCORE_FILE; + +typedef struct HAMCORE_FILES +{ + size_t Num; + HAMCORE_FILE *List; +} HAMCORE_FILES; + +typedef struct HAMCORE +{ + FILE *File; + HAMCORE_FILES Files; +} HAMCORE; + +HAMCORE *HamcoreOpen(const char *path); +void HamcoreClose(HAMCORE *hamcore); + +const HAMCORE_FILE *HamcoreFind(const HAMCORE *hamcore, const char *path); +bool HamcoreRead(HAMCORE *hamcore, void *dst, const HAMCORE_FILE *file); + +#endif diff --git a/Memory.c b/Memory.c new file mode 100644 index 0000000..b7ef7fc --- /dev/null +++ b/Memory.c @@ -0,0 +1,13 @@ +#include "Memory.h" + +size_t CompressionBufferSize(const size_t original_size) { return original_size * 2 + 256; } + +uint32_t Swap32(const uint32_t value) +{ + uint32_t swapped; + ((uint8_t *)&swapped)[0] = ((uint8_t *)&value)[3]; + ((uint8_t *)&swapped)[1] = ((uint8_t *)&value)[2]; + ((uint8_t *)&swapped)[2] = ((uint8_t *)&value)[1]; + ((uint8_t *)&swapped)[3] = ((uint8_t *)&value)[0]; + return swapped; +} diff --git a/Memory.h b/Memory.h new file mode 100644 index 0000000..afb7655 --- /dev/null +++ b/Memory.h @@ -0,0 +1,17 @@ +#ifndef MEMORY_H +#define MEMORY_H + +#include +#include + +#ifdef BYTE_ORDER_BIG_ENDIAN +#define BigEndian32 +#else +#define BigEndian32 Swap32 +#endif + +size_t CompressionBufferSize(const size_t original_size); + +uint32_t Swap32(const uint32_t value); + +#endif -- cgit v1.2.3