Add files via upload
This commit is contained in:
483
source/par2j/json.c
Normal file
483
source/par2j/json.c
Normal file
@@ -0,0 +1,483 @@
|
||||
// json.c
|
||||
// Copyright : 2023-02-06 Yutaka Sawada
|
||||
// License : GPL
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _UNICODE
|
||||
#endif
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600 // Windows Vista or later
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "common2.h"
|
||||
|
||||
/*
|
||||
{
|
||||
"SelectedFile":"Full path of selected recovery file",
|
||||
"BaseDirectory":"Full path of base directory of source files",
|
||||
"RecoveryFile":[
|
||||
"Name of recovery file1",
|
||||
"Name of recovery file2",
|
||||
"Name of recovery file3"
|
||||
],
|
||||
"SourceFile":[
|
||||
"Name of source file1",
|
||||
"Name of source file2",
|
||||
"Name of source file3"
|
||||
],
|
||||
"FoundFile":[
|
||||
"Name of found file1",
|
||||
"Name of found file2"
|
||||
],
|
||||
"ExternalFile":[
|
||||
"Name of external file1",
|
||||
"Name of external file2"
|
||||
],
|
||||
"DamagedFile":[
|
||||
"Name of damaged file1",
|
||||
"Name of damaged file2"
|
||||
],
|
||||
"AppendedFile":[
|
||||
"Name of appended file1",
|
||||
"Name of appended file2"
|
||||
],
|
||||
"MissingFile":[
|
||||
"Name of missing file1",
|
||||
"Name of missing file2"
|
||||
],
|
||||
"MisnamedFile":{
|
||||
"Correct name of misnamed file1":"Wrong name",
|
||||
"Correct name of misnamed file2":"Wrong name"
|
||||
}
|
||||
}
|
||||
*/
|
||||
static FILE *fp_json = NULL; // JSONファイル用
|
||||
|
||||
static wchar_t *list3_buf = NULL; // 検出ファイルの名前リスト
|
||||
static int list3_len, list3_max;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
// JSONファイルを開く
|
||||
void json_open(void)
|
||||
{
|
||||
wchar_t path[MAX_LEN];
|
||||
int len;
|
||||
|
||||
if (fp_json != NULL)
|
||||
return; // 既に開いてる場合はそのまま
|
||||
|
||||
wcscpy(path, ini_path);
|
||||
wcscat(path, offset_file_name(recovery_file));
|
||||
wcscat(path, L".json");
|
||||
//printf("json_path = %ls\n", path);
|
||||
|
||||
// 既に存在する場合は上書きして作り直す
|
||||
fp_json = _wfopen(path, L"wt, ccs=UTF-8");
|
||||
if (fp_json == NULL)
|
||||
return;
|
||||
|
||||
// 基礎情報を書き込む
|
||||
rewind(fp_json); // Remove BOM of UTF-8
|
||||
copy_without_prefix(path, recovery_file);
|
||||
unix_directory(path);
|
||||
if (fwprintf(fp_json, L"{\n\"SelectedFile\":\"%s\"", path) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
len = copy_without_prefix(path, base_dir);
|
||||
path[len - 1] = 0; // 末尾の「\」を取り除く
|
||||
unix_directory(path);
|
||||
if (fwprintf(fp_json, L",\n\"BaseDirectory\":\"%s\"", path) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// JSONファイルを閉じる
|
||||
void json_close(void)
|
||||
{
|
||||
if (fp_json == NULL)
|
||||
return; // 既に閉じてる場合はそのまま
|
||||
|
||||
fputws(L"\n}\n", fp_json);
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
}
|
||||
|
||||
// ファイル一覧
|
||||
void json_file_list(file_ctx_r *files)
|
||||
{
|
||||
wchar_t path[MAX_LEN];
|
||||
int rv, i;
|
||||
|
||||
if (fp_json == NULL)
|
||||
return; // 開いてない場合は何もしない
|
||||
|
||||
// パケットを含む (Good or Damaged) リカバリ・ファイルのリスト
|
||||
// 全くパケットを含まない (Useless) ファイルは除く
|
||||
if (fputws(L",\n\"RecoveryFile\":[", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while (i < recv2_len){
|
||||
if (compare_directory(recovery_file, recv2_buf + i) == 0){
|
||||
// 指定されたリカバリ・ファイルと同じ場所ならファイル名のみ
|
||||
wcscpy(path, offset_file_name(recv2_buf + i));
|
||||
} else {
|
||||
// 異なる場所(External File)ならフルパス
|
||||
copy_without_prefix(path, recv2_buf + i);
|
||||
unix_directory(path);
|
||||
}
|
||||
if (i == 0){
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
while (recv2_buf[i] != 0)
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// ソース・ファイルのリスト
|
||||
if (fputws(L",\n\"SourceFile\":[", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < file_num; i++){
|
||||
wcscpy(path, list_buf + files[i].name);
|
||||
unix_directory(path);
|
||||
if (i == 0){
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ファイルの状態
|
||||
void json_file_state(file_ctx_r *files)
|
||||
{
|
||||
wchar_t path[MAX_LEN], path2[MAX_LEN];
|
||||
int rv, i, flag_item;
|
||||
|
||||
if (fp_json == NULL)
|
||||
return; // 開いてない場合は何もしない
|
||||
|
||||
// 破損ファイル
|
||||
flag_item = 0;
|
||||
for (i = 0; i < file_num; i++){
|
||||
if (files[i].state & 2){
|
||||
wcscpy(path, list_buf + files[i].name);
|
||||
unix_directory(path);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"DamagedFile\":[", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 追加されたファイル
|
||||
flag_item = 0;
|
||||
for (i = 0; i < file_num; i++){
|
||||
if (files[i].state & 16){
|
||||
wcscpy(path, list_buf + files[i].name);
|
||||
unix_directory(path);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"AppendedFile\":[", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 消失ファイル
|
||||
flag_item = 0;
|
||||
for (i = 0; i < file_num; i++){
|
||||
if (files[i].state & 1){
|
||||
wcscpy(path, list_buf + files[i].name);
|
||||
unix_directory(path);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"MissingFile\":[", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 別名ファイルは、"本来の名前":"間違った名前" というセットにする
|
||||
flag_item = 0;
|
||||
for (i = 0; i < file_num; i++){
|
||||
if (files[i].state & 32){
|
||||
// ソースファイルの本来の名前
|
||||
wcscpy(path, list_buf + files[i].name);
|
||||
unix_directory(path);
|
||||
// 別名
|
||||
wcscpy(path2, list_buf + files[i].name2);
|
||||
unix_directory(path2);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"MisnamedFile\":{", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\":\"%s\"", path, path2);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\":\"%s\"", path, path2);
|
||||
}
|
||||
if (rv < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n}", fp_json) < 0){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 検出されたファイル名を保持する
|
||||
void json_add_found(wchar_t *filename, int flag_external)
|
||||
{
|
||||
wchar_t *tmp_p;
|
||||
int len;
|
||||
|
||||
if (fp_json == NULL)
|
||||
return; // 開いてない場合は何もしない
|
||||
|
||||
len = (int)wcslen(filename) + 1;
|
||||
|
||||
if (list3_buf == NULL){
|
||||
list3_max = ALLOC_LEN;
|
||||
list3_len = 0;
|
||||
list3_buf = malloc(list3_max * 2);
|
||||
if (list3_buf == NULL){
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
} else if (list3_len + len >= list3_max){ // 領域が足りなくなるなら拡張する
|
||||
list3_max += ALLOC_LEN;
|
||||
tmp_p = (wchar_t *)realloc(list3_buf, list3_max * 2);
|
||||
if (tmp_p == NULL){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
} else {
|
||||
list3_buf = tmp_p;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_external != 0){
|
||||
list3_buf[list3_len] = 'e';
|
||||
} else {
|
||||
list3_buf[list3_len] = 'f';
|
||||
}
|
||||
wcscpy(list3_buf + list3_len + 1, filename);
|
||||
list3_len += len + 1;
|
||||
}
|
||||
|
||||
// 検出されたファイル名を書き込む
|
||||
void json_save_found(void)
|
||||
{
|
||||
wchar_t path[MAX_LEN];
|
||||
int rv, i, flag_item;
|
||||
|
||||
if (fp_json == NULL)
|
||||
return; // 開いてない場合は何もしない
|
||||
if (list3_buf == NULL)
|
||||
return; // 検出しなかった場合は何もしない
|
||||
|
||||
/*{
|
||||
FILE *fp;
|
||||
fp = fopen("list3.txt", "wb");
|
||||
fwrite(list3_buf, 2, list3_len, fp);
|
||||
fclose(fp);
|
||||
}*/
|
||||
|
||||
// ブロックを検出したファイル
|
||||
flag_item = 0;
|
||||
i = 0;
|
||||
while (i < list3_len){
|
||||
if (list3_buf[i] == 'f'){
|
||||
wcscpy(path, list3_buf + i + 1);
|
||||
unix_directory(path);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"FoundFile\":[", fp_json) < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (list3_buf[i] != 0)
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ブロックを検出した外部ファイル
|
||||
flag_item = 0;
|
||||
i = 0;
|
||||
while (i < list3_len){
|
||||
if (list3_buf[i] == 'e'){
|
||||
copy_without_prefix(path, list3_buf + i + 1);
|
||||
unix_directory(path);
|
||||
if (flag_item == 0){
|
||||
flag_item = 1;
|
||||
if (fputws(L",\n\"ExternalFile\":[", fp_json) < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
rv = fwprintf(fp_json, L"\n\"%s\"", path);
|
||||
} else {
|
||||
rv = fwprintf(fp_json, L",\n\"%s\"", path);
|
||||
}
|
||||
if (rv < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (list3_buf[i] != 0)
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
if (flag_item != 0){
|
||||
if (fputws(L"\n]", fp_json) < 0){
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
fclose(fp_json);
|
||||
fp_json = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 最後にメモリーを開放する
|
||||
free(list3_buf);
|
||||
list3_buf = NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user