Skip to content

Commit

Permalink
CPyMO Tool Pack API (#43)
Browse files Browse the repository at this point in the history
* add cpymo_tool_package_packer api

* rewrite cpymo pack in cpymo tool pack api

* stricter pack api
Seng-Jik authored May 29, 2023
1 parent e9b0ccb commit e2436e0
Showing 2 changed files with 140 additions and 109 deletions.
218 changes: 109 additions & 109 deletions cpymo-tool/cpymo_tool_package.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "cpymo_tool_prelude.h"
#include "cpymo_tool_package.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -12,13 +13,12 @@ static error_t cpymo_tool_unpack(const char *pak_path, const char *extension, co

error_t err = cpymo_package_open(&pkg, pak_path);
if (err != CPYMO_ERR_SUCC) return err;


uint32_t max_length = 0;
for (uint32_t i = 0; i < pkg.file_count; ++i)
for (uint32_t i = 0; i < pkg.file_count; ++i)
if (pkg.files[i].file_length > max_length)
max_length = pkg.files[i].file_length;

char *buf = malloc(max_length);
if (buf == NULL) {
cpymo_package_close(&pkg);
@@ -73,136 +73,136 @@ static error_t cpymo_tool_unpack(const char *pak_path, const char *extension, co
return CPYMO_ERR_SUCC;
}

static error_t cpymo_tool_pack(const char *out_pack_path, const char **files_to_pack, uint32_t file_count)
error_t cpymo_tool_package_packer_open(
cpymo_tool_package_packer *packer,
const char *path,
size_t max_files_count)
{
cpymo_package_index *index = malloc(sizeof(cpymo_package_index) * file_count);
if (index == NULL) return CPYMO_ERR_OUT_OF_MEM;

uint32_t current_offset = sizeof(uint32_t) + file_count * sizeof(cpymo_package_index);
uint32_t max_length = 0;
packer->current_file_count = 0;
packer->data_section_start_offset =
sizeof(uint32_t) + max_files_count * sizeof(cpymo_package_index);
packer->index_section_start_offset = sizeof(uint32_t);
packer->max_file_count = max_files_count;

packer->stream = fopen(path, "wb");
if (packer->stream == NULL)
return CPYMO_ERR_CAN_NOT_OPEN_FILE;

for (uint32_t i = 0; i < file_count; ++i) {
const char *path = files_to_pack[i];
FILE *file = fopen(path, "rb");
if (file == NULL) {
printf("Can not open file %s\n", path);
free(index);
return CPYMO_ERR_CAN_NOT_OPEN_FILE;
for (long i = 0; i < packer->data_section_start_offset; ++i) {
if (fputc(0, packer->stream) == EOF) {
fclose(packer->stream);
return CPYMO_ERR_BAD_FILE_FORMAT;
}
}

#pragma warning(disable: 6386)
fseek(file, 0, SEEK_END);
index[i].file_length = (uint32_t)ftell(file);
fclose(file);
return CPYMO_ERR_SUCC;
}

index[i].file_offset = current_offset;
error_t cpymo_tool_package_packer_add_data(
cpymo_tool_package_packer *packer,
cpymo_str name,
void *data,
size_t len)
{
if (packer->current_file_count >= packer->max_file_count)
return CPYMO_ERR_NO_MORE_CONTENT;

#pragma warning(disable: 6385)
current_offset += index[i].file_length;
if (fseek(packer->stream, packer->index_section_start_offset, SEEK_SET))
return CPYMO_ERR_UNKNOWN;

if (index[i].file_length > max_length)
max_length = index[i].file_length;
char filename[32] = { '\0' };
cpymo_str_copy(filename, sizeof(filename), name);
size_t written = fwrite(filename, sizeof(filename), 1, packer->stream);
if (written != 1) return CPYMO_ERR_UNKNOWN;

const char *filename_start1 = strrchr(path, '/') + 1;
const char *filename_start2 = strrchr(path, '\\') + 1;
const char *filename = filename_start1;
uint32_t index[2] = {
end_htole32(packer->data_section_start_offset),
end_htole32((uint32_t)len)
};

if (filename_start2 > filename) filename = filename_start2;
if (path > filename) filename = path;
written = fwrite(index, sizeof(index), 1, packer->stream);
if (written != 1) return CPYMO_ERR_UNKNOWN;
long new_index_offset = ftell(packer->stream);

const char *ext_start = strrchr(filename, '.');
if (fseek(packer->stream, packer->data_section_start_offset, SEEK_SET))
return CPYMO_ERR_UNKNOWN;

size_t j = 0;
bool finished = false;
for (; j < 31; ++j) {
if (filename + j == ext_start || filename[j] == '\0') {
finished = true;
break;
}
else
index[i].file_name[j] = toupper(filename[j]);
}
written = fwrite(data, len, 1, packer->stream);
if (written != 1) return CPYMO_ERR_UNKNOWN;
long new_data_offset = ftell(packer->stream);

for (; j < 32; ++j)
index[i].file_name[j] = '\0';
packer->current_file_count++;
packer->data_section_start_offset = new_data_offset;
packer->index_section_start_offset = new_index_offset;
return CPYMO_ERR_SUCC;
}

if (!finished) {
printf("[Warning] File name \"%s\" is too long!\n", index[i].file_name);
error_t cpymo_tool_package_packer_add_file(
cpymo_tool_package_packer *packer,
const char *file)
{
const char *filename_start1 = strrchr(file, '/') + 1;
const char *filename_start2 = strrchr(file, '\\') + 1;
const char *filename = filename_start1;
if (filename_start2 > filename) filename = filename_start2;
if (file > filename) filename = file;
const char *ext_start = strrchr(filename, '.');

char filename_index[32] = { '\0' };

size_t j = 0;
bool finished = false;
for (size_t j = 0; j < 31; ++j) {
if (filename + j == ext_start || filename[j] == '\0') {
finished = true;
break;
}

index[i].file_length = end_htole32(index[i].file_length);
index[i].file_offset = end_htole32(index[i].file_offset);
else
filename_index[j] = toupper(filename[j]);
}

char *buf = malloc(max_length);
if (buf == NULL) {
free(index);
return CPYMO_ERR_OUT_OF_MEM;
}
if (!finished)
printf("[Warning] File name \"%s\" is too long!\n", filename_index);

FILE *out_pak = fopen(out_pack_path, "wb");
if (out_pak == NULL) {
printf("[Error] Can not open %s.\n", out_pack_path);
free(index);
return CPYMO_ERR_CAN_NOT_OPEN_FILE;
}
char *data = NULL;
size_t len;
error_t err = cpymo_utils_loadfile(file, &data, &len);
CPYMO_THROW(err);

uint32_t file_count_store = end_htole32(file_count);
size_t count = fwrite(&file_count_store, sizeof(uint32_t), 1, out_pak);
if (count != 1) {
printf("[Error] Can not write file_count to package.\n");
free(index);
fclose(out_pak);
return CPYMO_ERR_UNKNOWN;
}
err = cpymo_tool_package_packer_add_data(
packer, cpymo_str_pure(filename_index), data, len);
free(data);
return err;
}

count = fwrite(index, sizeof(cpymo_package_index), file_count, out_pak);
free(index);
void cpymo_tool_package_packer_close(
cpymo_tool_package_packer *packer)
{
uint32_t filecount_le32 = end_htole32((uint32_t)packer->current_file_count);
if (fseek(packer->stream, 0, SEEK_SET)) abort();
if (fwrite(&filecount_le32, sizeof(filecount_le32), 1, packer->stream) != 1)
abort();
if (fclose(packer->stream)) abort();
}

if (count != file_count) {
printf("[Error] Can not write file index to package.\n");
fclose(out_pak);
}
static error_t cpymo_tool_pack(const char *out_pack_path, const char **files_to_pack, uint32_t file_count)
{
cpymo_tool_package_packer p;
error_t err = cpymo_tool_package_packer_open(&p, out_pack_path, file_count);
CPYMO_THROW(err);

for (uint32_t i = 0; i < file_count; ++i) {
const char *path = files_to_pack[i];

FILE *f = fopen(path, "rb");
if (f == NULL) {
printf("[Error] Can not open file %s.\n", path);
fclose(out_pak);
free(buf);
return CPYMO_ERR_CAN_NOT_OPEN_FILE;
}

fseek(f, 0, SEEK_END);
uint32_t length = ftell(f);
fseek(f, 0, SEEK_SET);

if (fread(buf, length, 1, f) != 1) {
printf("[Error] Can not read file %s.\n", path);
fclose(out_pak);
fclose(f);
free(buf);
return CPYMO_ERR_CAN_NOT_OPEN_FILE;
}

fclose(f);

if (fwrite(buf, length, 1, out_pak) != 1) {
printf("[Error] Can not write %s to package.\n", path);
fclose(out_pak);
free(buf);
return CPYMO_ERR_UNKNOWN;
printf("%s\n", files_to_pack[i]);
err = cpymo_tool_package_packer_add_file(&p, files_to_pack[i]);
if (err != CPYMO_ERR_SUCC) {
printf("[Error] Can not pack file: %s.\n", files_to_pack[i]);
cpymo_tool_package_packer_close(&p);
return err;
}

printf("%s\n", path);
}

free(buf);
fclose(out_pak);

printf("\n==> %s\n", out_pack_path);
cpymo_tool_package_packer_close(&p);
printf("==> %s\n", out_pack_path);

return CPYMO_ERR_SUCC;
}
@@ -213,7 +213,7 @@ static error_t cpymo_tool_get_file_list(char *** files, size_t * count, const ch
size_t ls_len;
error_t err = cpymo_utils_loadfile(list_file, &ls_buf, &ls_len);
CPYMO_THROW(err);

cpymo_parser parser;
cpymo_parser_init(&parser, ls_buf, ls_len);

31 changes: 31 additions & 0 deletions cpymo-tool/cpymo_tool_package.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef INCLUDE_CPYMO_TOOL_PACKAGE
#define INCLUDE_CPYMO_TOOL_PACKAGE

#include <stdio.h>
#include "../cpymo/cpymo_str.h"

typedef struct {
size_t max_file_count, current_file_count;
long index_section_start_offset, data_section_start_offset;
FILE *stream;
} cpymo_tool_package_packer;

error_t cpymo_tool_package_packer_open(
cpymo_tool_package_packer *packer,
const char *path,
size_t max_files_count);

error_t cpymo_tool_package_packer_add_data(
cpymo_tool_package_packer *packer,
cpymo_str name,
void *data,
size_t len);

error_t cpymo_tool_package_packer_add_file(
cpymo_tool_package_packer *packer,
const char *file);

void cpymo_tool_package_packer_close(
cpymo_tool_package_packer *packer);

#endif

0 comments on commit e2436e0

Please sign in to comment.