Files
MultiPar/source/par2j/json.c
2024-11-30 13:06:17 +09:00

484 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// json.c
// Copyright : 2024-11-30 Yutaka Sawada
// License : GPL
#ifndef _UNICODE
#define _UNICODE
#endif
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601 // Windows 7 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;
}