Skip to content

Commit

Permalink
Merge pull request #30 from SegFault42/develop
Browse files Browse the repository at this point in the history
0.2
  • Loading branch information
SegFault42 authored Dec 4, 2019
2 parents 7c209e9 + e5cd87c commit 3daa42a
Show file tree
Hide file tree
Showing 13 changed files with 442 additions and 99 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ INCLUDES := include ./libs/log.c/src ./libs/mupdf/include ./libs/mupdf/source/fi
ROMFS := romfs

MAJOR := 0
MINOR := 1
MINOR := 2
MICRO := 0

APP_TITLE := EbookViewerNX
Expand Down
10 changes: 9 additions & 1 deletion include/cbr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
#include <archive.h>
#include <archive_entry.h>

bool extract_cbr(char *path);
typedef struct s_cbr
{
struct archive *handle;
struct archive *dst;
int total_page; // total page number
char *path;
} t_cbr;

bool extract_cbr(char *path, int page_number);

#endif
1 change: 1 addition & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@
#include "controller.h"
#include "init.h"
#include "cbr.h"
#include "file.h"

#endif
1 change: 1 addition & 0 deletions include/ebook.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define PORTRAIT false
#define LANDSCAPE true
#define CONFIG_PATH "/switch/ebookViewerNX/config"
#define EBOOK_PATH "/switch/ebookViewerNX/"

typedef struct s_ebook
{
Expand Down
7 changes: 7 additions & 0 deletions include/file.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef FILE_H
#define FILE_H

bool isFileExist(const char *file);
char *get_file_extension(char *str);

#endif
8 changes: 6 additions & 2 deletions include/graphic.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
#define COVER_WIDTH 350
#define COVER_HEIGHT 500

#define APP_NAME "ebookViewerNX v0.1"
#define APP_NAME "ebookViewerNX v0.2.0"

#define COVER 0
#define READ 1

#define DEFAULT 0
#define CBR 1

typedef struct s_ttf
{
TTF_Font *font_small;
Expand All @@ -36,6 +39,7 @@ void print_help(void);
void draw_bar(void);
void draw_loading(void);
void draw_error(char *msg);
void draw_page_number(void);
void draw_page_number(int type);
void draw_message_box(char *msg);

#endif
247 changes: 178 additions & 69 deletions source/cbr.c
Original file line number Diff line number Diff line change
@@ -1,135 +1,244 @@
#include "common.h"

static u64 count_files(const char *path)
extern t_cbr *cbr;

static bool init_cbr(t_cbr *cbr, const char *path)
{
struct archive *handle = NULL;
u64 count = 0;
int ret = 0;
int ret = 0;

handle = archive_read_new();
if (handle == NULL) {
log_warn("%s", archive_error_string(handle));
return (-1);
cbr->handle = archive_read_new();
if (cbr->handle == NULL) {
log_warn("%s", archive_error_string(cbr->handle));
return (false);
}

cbr->dst = archive_write_disk_new();
if (cbr->dst == NULL) {
log_warn("%s", archive_error_string(cbr->dst));
return (false);
}

ret = archive_read_support_format_all(handle);
ret = archive_read_support_format_all(cbr->handle);
if (ret != ARCHIVE_OK) {
log_warn("%s", archive_error_string(handle));
return (-1);
log_warn("%s", archive_error_string(cbr->handle));
return (false);
}

ret = archive_read_open_filename(handle, path, 1024);
ret = archive_read_open_filename(cbr->handle, path, 1024);
if (ret != ARCHIVE_OK) {
printf("%s\n", archive_error_string(handle));
printf("archive_read_open_filename%d\n", ret);
return 1;
log_warn("%s", archive_error_string(cbr->handle));
return (false);
}

log_info("init_cbr() [Success]");

return (true);
}

static void deinit_cbr(t_cbr *cbr)
{
archive_read_free(cbr->handle);
archive_write_free(cbr->dst);

log_info("deinit_cbr() [Success]");
}

static u64 count_files(t_cbr *cbr, const char *path)
{
int ret = 0;
size_t count = 0;

if (init_cbr(cbr, path) == false) {
return (-1);
}

for (;;) {
struct archive_entry *entry = NULL;

ret = archive_read_next_header(handle, &entry);
ret = archive_read_next_header(cbr->handle, &entry);
if (ret == ARCHIVE_EOF) {
break;
}

count++;
}

ret = archive_read_free(handle);
deinit_cbr(cbr);

log_info("count_files() [Success]");
return (count);
}

typedef struct s_cbr
// TODO: review return value
static int write_data(t_cbr *cbr)
{
struct archive *handle;
struct archive *dst;
u64 max;
} t_cbr;
int ret = 0;
size_t total_length = 0;

static bool init_cbr(t_cbr *cbr, char *path)
{
int ret = 0;
for (;;) {
const void *chunk = NULL;
size_t length = 0;
s64 offset = 0;

cbr->handle = archive_read_new();
if (cbr->handle == NULL) {
log_warn("%s", archive_error_string(cbr->handle));
return (false);
ret = archive_read_data_block(cbr->handle, &chunk, &length, &offset);
if (ret == ARCHIVE_EOF)
return ARCHIVE_OK;

if (ret != ARCHIVE_OK)
return ret;

ret = archive_write_data_block(cbr->dst, chunk, length, offset);
if (ret != ARCHIVE_OK)
return ret;
}

cbr->dst = archive_write_disk_new();
if (cbr->handle == NULL) {
log_warn("%s", archive_error_string(cbr->handle));
return (false);
log_info("write_data() [Success]");
return -1;
}

static int myCompare(const void* a, const void* b)
{
return (strcmp(*(const char**)a, *(const char**)b));
}

char **get_archive_content_file_name(char *path, t_cbr *cbr)
{
u64 count = 0;
int ret = 0;
char **array = NULL;

array = (char **)calloc(sizeof(char *), cbr->total_page + 1);
if (array == NULL) {
log_warn("calloc error\n");
return (NULL);
}

ret = archive_read_support_format_all(cbr->handle);
if (ret != ARCHIVE_OK) {
log_warn("%s", archive_error_string(cbr->handle));
return (false);
if (init_cbr(cbr, path) == false) {
return (NULL);
}

ret = archive_read_open_filename(cbr->handle, path, 1024);
if (ret != ARCHIVE_OK) {
log_warn("%s", archive_error_string(cbr->handle));
return (false);
for (;;) {
struct archive_entry *entry = NULL;

ret = archive_read_next_header(cbr->handle, &entry);
if (ret == ARCHIVE_EOF) {
break;
}

const char *entry_path = archive_entry_pathname(entry);
if (entry_path == NULL) {
log_warn("%s", archive_error_string(cbr->handle));
break ;
}
array[count] = strdup(entry_path);

count++;
}

return (true);
deinit_cbr(cbr);

// Sort files name
qsort(array, cbr->total_page, sizeof(const char *), myCompare);

log_info("get_archive_content_file_name() [Success]");

return (array);
}

bool extract_cbr(char *path)
bool extract_cbr(char *path, int page_number)
{
t_cbr cbr = {0};
char **array = NULL;
int ret = 0;
u64 count = 0;

cbr.max = count_files(path);
// create temp directory
if (isFileExist("/tmp") == false) {
if (mkdir("/tmp", 0777) == -1) {
log_warn("%s", strerror(errno));
return (false);
}
}

if (init_cbr(&cbr, path) == false) {
// Count files number in archive
cbr->total_page = count_files(cbr, path);
if (page_number > cbr->total_page) {
log_warn("page %d not exist", page_number);
return (false);
} else if (cbr->total_page == -1) {
log_warn("count_files [Failure]");
return (false);
}

mkdir("/tmp", 0777);
// Sort and store all filename in char **
array = get_archive_content_file_name(path, cbr);
if (array == NULL) {
return (false);
}

if (init_cbr(cbr, path) == false) {
free_2d_array(array);
return (false);
}

for (;;) {
struct archive_entry *entry = NULL;
ret = archive_read_next_header(handle, &cbr.entry);
struct archive_entry *entry = NULL;

ret = archive_read_next_header(cbr->handle, &entry);
if (ret == ARCHIVE_EOF) {
break;
}

if (ret != ARCHIVE_OK) {
Menu_DisplayError("archive_read_next_header failed:", ret);
} else if (ret != ARCHIVE_OK) {
log_warn("%s", archive_error_string(cbr->handle));
if (ret != ARCHIVE_WARN) {
break;
}
}

const char *entry_path = archive_entry_pathname(entry);
char new_path[1024];

ret = snprintf(new_path, sizeof(new_path), "%s/%s", dest_path, entry_path);
ret = archive_entry_update_pathname_utf8(entry, new_path);
if (!ret) {
Menu_DisplayError("archive_entry_update_pathname_utf8:", ret);
break;
if (entry_path == NULL) {
log_warn("%s", archive_error_string(cbr->handle));
ret = -1;
break ;
}

ret = archive_write_disk_set_options(dst, ARCHIVE_EXTRACT_UNLINK);
ret = archive_write_header(dst, entry);
if (ret != ARCHIVE_OK) {
Menu_DisplayError("archive_write_header failed:", ret);
break;
if (!strcmp(array[page_number], entry_path)) {
cbr->path = (char *)calloc(sizeof(char), PATH_MAX + 1);
if (cbr->path == NULL) {
free_2d_array(array);
deinit_cbr(cbr);
return (false);
}

snprintf(cbr->path, PATH_MAX, "%s/%s", EBOOK_PATH, entry_path);

if (isFileExist(cbr->path) == false) {
ret = archive_entry_update_pathname_utf8(entry, cbr->path);
if (!ret) {
log_warn("%s", archive_error_string(cbr->handle));
break;
}

ret = archive_write_disk_set_options(cbr->dst, ARCHIVE_EXTRACT_UNLINK);
ret = archive_write_header(cbr->dst, entry);
if (ret != ARCHIVE_OK) {
log_warn("%s", archive_error_string(cbr->handle));
break;
}

ret = write_data(cbr);
ret = archive_write_finish_entry(cbr->dst);

ret = write_data(cbr);
}

break ;
}

ret = Archive_WriteData(handle, dst);
ret = archive_write_finish_entry(dst);
count++;
}

ret = archive_write_free(cbr.dst);
ret = archive_read_free(cbr.handle);
free_2d_array(array);
deinit_cbr(cbr);

log_info("extract_cbr() [Success]");
return (true);
}
Loading

0 comments on commit 3daa42a

Please sign in to comment.