Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
584 changes: 538 additions & 46 deletions core/file_io.cpp

Large diffs are not rendered by default.

197 changes: 196 additions & 1 deletion core/file_io.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,210 @@
#pragma once
#include <stdio.h>
#include <memory>
#include <string>
#include <iostream>

#ifndef __cplusplus
#error "This header requires C++. Please compile with a C++ compiler."
#endif

struct FileDeleter {
void operator()(FILE* f) const noexcept {
if (f) fclose(f);
}
};

// 基础类型定义
using UniqueFile = std::unique_ptr<FILE, FileDeleter>;

// 格式化状态标志
enum class NumberBase {
Dec,
Hex,
Oct
};

// 增强的文件类,支持运算符重载
class EnhancedFile {
private:
UniqueFile file;

// 格式化状态
struct FormatState {
NumberBase base = NumberBase::Dec;
bool showbase = false; // 显示进制前缀 (0x, 0)
bool uppercase = false; // 十六进制大写字母
bool boolalpha = false; // true/false 而不是 1/0
bool skipws = true; // 跳过空白字符
int width = 0; // 字段宽度 (0=无限制)
int precision = 6; // 浮点数精度
char fill = ' '; // 填充字符
} format;

public:
// 构造函数
EnhancedFile() noexcept = default;
explicit EnhancedFile(FILE* f) noexcept;
explicit EnhancedFile(UniqueFile&& f) noexcept;

// 移动语义
EnhancedFile(EnhancedFile&& other) noexcept = default;
EnhancedFile& operator=(EnhancedFile&& other) noexcept = default;

// 禁止拷贝
EnhancedFile(const EnhancedFile&) = delete;
EnhancedFile& operator=(const EnhancedFile&) = delete;

// 析构函数
~EnhancedFile() = default;

// 运算符重载
explicit operator bool() const noexcept;
bool operator!() const noexcept;
operator FILE*() const noexcept;
FILE* operator->() const noexcept;

// 成员函数
FILE* get() const noexcept;
UniqueFile release() noexcept;
void reset(FILE* f = nullptr) noexcept;
void close() noexcept;
bool flush() noexcept;
long tell() const noexcept;
bool seek(long offset, int origin) noexcept;
bool eof() const noexcept;
bool error() const noexcept;
void clearerr() noexcept;

// 读写操作
size_t write(const void* buffer, size_t size, size_t count) noexcept;
size_t read(void* buffer, size_t size, size_t count) noexcept;
int putc(int ch) noexcept;
int getc() noexcept;
bool puts(const char* str) noexcept;
char* gets(char* buffer, int maxSize) noexcept;
int printf(const char* format, ...) noexcept;
int scanf(const char* format, ...) noexcept;

// 格式化状态设置
void set_base(NumberBase base) noexcept { format.base = base; }
void set_hex(bool enable) noexcept { format.base = enable ? NumberBase::Hex : NumberBase::Dec; }
void set_oct(bool enable) noexcept { format.base = enable ? NumberBase::Oct : NumberBase::Dec; }
void set_dec(bool enable) noexcept { if (enable) format.base = NumberBase::Dec; }
void set_showbase(bool enable) noexcept { format.showbase = enable; }
void set_uppercase(bool enable) noexcept { format.uppercase = enable; }
void set_boolalpha(bool enable) noexcept { format.boolalpha = enable; }
void set_skipws(bool enable) noexcept { format.skipws = enable; }
void set_width(int w) noexcept { format.width = w; }
void set_precision(int p) noexcept { format.precision = p; }
void set_fill(char c) noexcept { format.fill = c; }

// 格式化状态获取
NumberBase base() const noexcept { return format.base; }
bool is_hex() const noexcept { return format.base == NumberBase::Hex; }
bool is_oct() const noexcept { return format.base == NumberBase::Oct; }
bool is_dec() const noexcept { return format.base == NumberBase::Dec; }
bool showbase() const noexcept { return format.showbase; }
bool uppercase() const noexcept { return format.uppercase; }
bool boolalpha() const noexcept { return format.boolalpha; }
bool skipws() const noexcept { return format.skipws; }
int width() const noexcept { return format.width; }
int precision() const noexcept { return format.precision; }
char fill() const noexcept { return format.fill; }
};

// 工厂函数
EnhancedFile oxfopen_enhanced(const char* fn, const char* mode);
EnhancedFile my_oxfopen_enhanced(const char* fn, const char* mode);

// 原有的函数声明
FILE* oxfopen(const char* fn, const char* mode);
FILE* my_oxfopen(const char* fn, const char* mode);
UniqueFile oxfopen_unique(const char* fn, const char* mode);
UniqueFile my_oxfopen_unique(const char* fn, const char* mode);
UniqueFile my_oxfopen_unique(const char* fn, const char* mode);

// 自定义操纵符
namespace file_manip {
// 进制操纵符
struct hex_tag {}; inline constexpr hex_tag hex;
struct dec_tag {}; inline constexpr dec_tag dec;
struct oct_tag {}; inline constexpr oct_tag oct;

// 格式操纵符
struct showbase_tag {}; inline constexpr showbase_tag showbase;
struct noshowbase_tag {}; inline constexpr noshowbase_tag noshowbase;
struct uppercase_tag {}; inline constexpr uppercase_tag uppercase;
struct nouppercase_tag {}; inline constexpr nouppercase_tag nouppercase;
struct boolalpha_tag {}; inline constexpr boolalpha_tag boolalpha;
struct noboolalpha_tag {}; inline constexpr noboolalpha_tag noboolalpha;
struct skipws_tag {}; inline constexpr skipws_tag skipws;
struct noskipws_tag {}; inline constexpr noskipws_tag noskipws;

// 流操纵符
struct endl_tag {}; inline constexpr endl_tag endl;
struct flush_tag {}; inline constexpr flush_tag flush;
}

// 进制操纵符重载
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::hex_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::dec_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::oct_tag);

// 格式操纵符重载
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::showbase_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::noshowbase_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::uppercase_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::nouppercase_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::boolalpha_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::noboolalpha_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::skipws_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::noskipws_tag);

// 流操纵符重载
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::endl_tag);
EnhancedFile& operator<<(EnhancedFile& ef, file_manip::flush_tag);

// 标准库兼容的操纵符重载(可选)
EnhancedFile& operator<<(EnhancedFile& ef, std::ostream& (*manip)(std::ostream&));

// 流式输出运算符 (<<)
EnhancedFile& operator<<(EnhancedFile& ef, const char* str);
EnhancedFile& operator<<(EnhancedFile& ef, const std::string& str);
EnhancedFile& operator<<(EnhancedFile& ef, int val);
EnhancedFile& operator<<(EnhancedFile& ef, unsigned int val);
EnhancedFile& operator<<(EnhancedFile& ef, long val);
EnhancedFile& operator<<(EnhancedFile& ef, unsigned long val);
EnhancedFile& operator<<(EnhancedFile& ef, long long val);
EnhancedFile& operator<<(EnhancedFile& ef, unsigned long long val);
EnhancedFile& operator<<(EnhancedFile& ef, float val);
EnhancedFile& operator<<(EnhancedFile& ef, double val);
EnhancedFile& operator<<(EnhancedFile& ef, long double val);
EnhancedFile& operator<<(EnhancedFile& ef, char c);
EnhancedFile& operator<<(EnhancedFile& ef, unsigned char c);
EnhancedFile& operator<<(EnhancedFile& ef, bool val);
EnhancedFile& operator<<(EnhancedFile& ef, const void* ptr);

// 流式输入运算符 (>>)
EnhancedFile& operator>>(EnhancedFile& ef, std::string& str);
EnhancedFile& operator>>(EnhancedFile& ef, int& val);
EnhancedFile& operator>>(EnhancedFile& ef, unsigned int& val);
EnhancedFile& operator>>(EnhancedFile& ef, long& val);
EnhancedFile& operator>>(EnhancedFile& ef, unsigned long& val);
EnhancedFile& operator>>(EnhancedFile& ef, long long& val);
EnhancedFile& operator>>(EnhancedFile& ef, unsigned long long& val);
EnhancedFile& operator>>(EnhancedFile& ef, float& val);
EnhancedFile& operator>>(EnhancedFile& ef, double& val);
EnhancedFile& operator>>(EnhancedFile& ef, long double& val);
EnhancedFile& operator>>(EnhancedFile& ef, char& c);
EnhancedFile& operator>>(EnhancedFile& ef, unsigned char& c);
EnhancedFile& operator>>(EnhancedFile& ef, bool& val);

// 从 UniqueFile 创建 EnhancedFile
inline EnhancedFile to_enhanced(UniqueFile&& uf) {
return EnhancedFile(std::move(uf));
}

// 从 EnhancedFile 获取 UniqueFile
inline UniqueFile to_unique(EnhancedFile&& ef) {
return ef.release();
}
15 changes: 8 additions & 7 deletions core/pac_extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,10 +763,10 @@ bool pac_extract(const char* fn, const char* floder)
DEG_LOG(E, "No partition info found in xml");
return false;
}
UniqueFile fi = oxfopen_unique("partitions_temp.xml","w");
EnhancedFile fi = oxfopen_enhanced("partitions_temp.xml","w");
if(fi) {
fwrite(partxml.c_str(), 1, partxml.size(), fi.get());
fi.reset();
fi << partxml;
fi.close();
}
else {
DEG_LOG(E, "Failed to create temporary partitions XML file.");
Expand Down Expand Up @@ -1016,12 +1016,13 @@ bool pac_flash(spdio_t* io, const char* floder)

auto into_func = [=]() mutable
{
UniqueFile fi = oxfopen_unique(fdl1_path.c_str(), "r");
EnhancedFile fi = oxfopen_enhanced(fdl1_path.c_str(), "r");
if (!fi) {
DEG_LOG(W, "File does not exist.\n");
if (isHelperInit) gui_idle_call_wait_drag([](){
showErrorDialog(GTK_WINDOW(helper.getWidget("main_window")), _("Error"), _("File does not exist."));
}, GTK_WINDOW(helper.getWidget("main_window")));
fi.close();
return;
}
send_file(io, fdl1_path.c_str(), fdl1_base_addr, 0, 528, 0, 0);
Expand Down Expand Up @@ -1200,11 +1201,11 @@ bool pac_flash(spdio_t* io, const char* floder)
std::istreambuf_iterator<char>());

std::string partxml = ExtractPartitionsWithTags(content);
UniqueFile f1 = oxfopen_unique("repartition_xml_temp.xml", "w");
EnhancedFile f1 = oxfopen_enhanced("repartition_xml_temp.xml", "w");
if (!f1) ERR_EXIT("Failed to create temporary repartition XML file.\n");
if(f1) {
fwrite(partxml.c_str(), 1, partxml.size(), f1.get());
f1.reset();
f1 << partxml;
f1.close();
}
uint8_t* buf = io->temp_buf;
int n = scan_xml_partitions(io, "repartition_xml_temp.xml", buf, 0xffff);
Expand Down
30 changes: 13 additions & 17 deletions main_console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1815,15 +1815,14 @@ int main_console(int argc, char** argv) {
continue;
}
const char* fn;
UniqueFile fi;
if (argcount <= 2) {
DEG_LOG(W, "read_parts partition_table_file");
argc = 1;
continue;
}
fn = str2[2];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
EnhancedFile fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
argc -= 2;
argv += 2;
Expand All @@ -1836,15 +1835,14 @@ int main_console(int argc, char** argv) {
}
else if(!strcmp(str2[1], "pac")){
const char* fn;
UniqueFile fi;
if (argcount <= 2) {
DEG_LOG(W, "pac FILE");
argc = 1;
continue;
}
fn = str2[2];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
EnhancedFile fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
argc -= 2;
argv += 2;
Expand Down Expand Up @@ -2003,15 +2001,14 @@ int main_console(int argc, char** argv) {
continue;
}
const char* fn;
UniqueFile fi;
if (argcount <= 2) {
DEG_LOG(W, "repartition FILE");
argc = 1;
continue;
}
fn = str2[2];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
EnhancedFile fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
argc -= 2;
argv += 2;
Expand Down Expand Up @@ -2166,16 +2163,16 @@ int main_console(int argc, char** argv) {
continue;
}
const char* fn;
UniqueFile fi;
EnhancedFile fi;
const char* name = str2[2];
if (argcount <= 3) {
DEG_LOG(W, "w/write_part part_name/part_id FILE\n");
argc = 1;
continue;
}
fn = str2[3];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.\n");
argc -= 3;
argv += 3;
Expand Down Expand Up @@ -2240,7 +2237,6 @@ int main_console(int argc, char** argv) {
continue;
}
const char* fn;
UniqueFile fi;
const char* name = str2[2];
if (argcount <= 3) {
DEG_LOG(W, "w_force part_name/part_id FILE");
Expand All @@ -2261,8 +2257,8 @@ int main_console(int argc, char** argv) {
continue;
}
fn = str2[3];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
EnhancedFile fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
argc -= 3;
argv += 3;
Expand Down Expand Up @@ -2299,8 +2295,8 @@ int main_console(int argc, char** argv) {
continue;
}
fn = str2[3];
fi = oxfopen_unique(fn, "r");
if (fi == nullptr) {
EnhancedFile fi = oxfopen_enhanced(fn, "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
argc -= 3;
argv += 3;
Expand Down
2 changes: 1 addition & 1 deletion pages/page_advanced_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static void on_button_clicked_start_repart(GtkWidgetHelper helper) {
ensure_device_attached_or_exit(helper);
GtkWidget *parent = helper.getWidget("main_window");
std::string filePath = helper.getEntryText(helper.getWidget("xml_path"));
UniqueFile fi = oxfopen_unique(filePath.c_str(), "r");
EnhancedFile fi = oxfopen_enhanced(filePath.c_str(), "r");
if (!fi) {
DEG_LOG(E, "File does not exist.");
return;
Expand Down
Loading
Loading