ファイルなしでも開ける様に+:oコマンドの追加
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
## 1.2.0 (2026年05月03日)
|
## 1.2.0 (2026年05月03日)
|
||||||
* Debianでコンパイル出来る様に
|
* Debianでコンパイル出来る様に
|
||||||
* マウス対応の追加
|
* マウス対応の追加
|
||||||
|
* ファイルなしでも開ける様に
|
||||||
|
* `:o`コマンドの追加
|
||||||
|
|
||||||
## 1.1.0 (2025年12月28日)
|
## 1.1.0 (2025年12月28日)
|
||||||
* PgUp・PgDownで使ってページを動ける様に
|
* PgUp・PgDownで使ってページを動ける様に
|
||||||
|
|||||||
10
main.cc
10
main.cc
@@ -39,13 +39,13 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
#include "src/hexeditor.hh"
|
#include "src/hexeditor.hh"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc != 2) {
|
std:: string filename;
|
||||||
std::cerr << "usage: hexagon <filename>\n";
|
|
||||||
return 1;
|
if (argc > 1) filename = argv[1];
|
||||||
}
|
else filename = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HexEditor editor(argv[1]);
|
HexEditor editor(filename);
|
||||||
editor.run();
|
editor.run();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
std::cerr << "エラー: " << e.what() << "\n";
|
std::cerr << "エラー: " << e.what() << "\n";
|
||||||
|
|||||||
134
src/hexeditor.cc
134
src/hexeditor.cc
@@ -80,7 +80,7 @@ const std::vector<HexEditor::FileSignature> HexEditor::signatures = {
|
|||||||
HexEditor::HexEditor(const std::string &filename)
|
HexEditor::HexEditor(const std::string &filename)
|
||||||
: curPos(0), dpOffset(0), bpr(16),
|
: curPos(0), dpOffset(0), bpr(16),
|
||||||
statusMode(Status_Normal), modified(false),
|
statusMode(Status_Normal), modified(false),
|
||||||
running(true),
|
running(true), hasFile(!filename.empty()),
|
||||||
lastSearchDir(Direction_Forward),
|
lastSearchDir(Direction_Forward),
|
||||||
headerLen(0), headerType("") {
|
headerLen(0), headerType("") {
|
||||||
// SIGINT (CTRL + C)を無効に
|
// SIGINT (CTRL + C)を無効に
|
||||||
@@ -123,39 +123,46 @@ HexEditor::HexEditor(const std::string &filename)
|
|||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
// ファイルをバッファーに読み込む
|
// ファイルをバッファーに読み込む
|
||||||
std::ifstream file(filename, std::ios::binary);
|
if (hasFile) {
|
||||||
if (!file) {
|
std::ifstream file(filename, std::ios::binary);
|
||||||
endwin();
|
if (!file) {
|
||||||
throw std::runtime_error("ファイルを開くに失敗");
|
endwin();
|
||||||
}
|
throw std::runtime_error("ファイルを開くに失敗");
|
||||||
|
}
|
||||||
|
|
||||||
buf.assign((std::istreambuf_iterator<char>(file)), {});
|
buf.assign((std::istreambuf_iterator<char>(file)), {});
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (buf.empty()) {
|
if (buf.empty()) {
|
||||||
endwin();
|
endwin();
|
||||||
throw std::runtime_error("ファイルが空です");
|
throw std::runtime_error("ファイルが空です");
|
||||||
}
|
}
|
||||||
|
|
||||||
fname = filename;
|
fname = filename;
|
||||||
|
hasFile = true;
|
||||||
|
|
||||||
// ファイルヘッダー
|
// ファイルヘッダー
|
||||||
for (const auto &sig : signatures) {
|
for (const auto &sig : signatures) {
|
||||||
if (buf.size() >= sig.signature.size()) {
|
if (buf.size() >= sig.signature.size()) {
|
||||||
bool match = true;
|
bool match = true;
|
||||||
for (size_t i = 0; i < sig.signature.size(); ++i) {
|
for (size_t i = 0; i < sig.signature.size(); ++i) {
|
||||||
if (buf[i] != sig.signature[i]) {
|
if (buf[i] != sig.signature[i]) {
|
||||||
match = false;
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
headerLen = sig.signature.size();
|
||||||
|
headerType = sig.type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
|
||||||
headerLen = sig.signature.size();
|
|
||||||
headerType = sig.type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fname = "[No File]";
|
||||||
|
buf.clear();
|
||||||
|
hasFile = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ウィンドウを作成する
|
// ウィンドウを作成する
|
||||||
@@ -516,9 +523,13 @@ void HexEditor::handleCommand() {
|
|||||||
} else if (statusText == "noh") {
|
} else if (statusText == "noh") {
|
||||||
lastSearch = "";
|
lastSearch = "";
|
||||||
isCommand = true;
|
isCommand = true;
|
||||||
|
} else if (statusText.rfind("o ", 0) == 0 || statusText.rfind("open ", 0) == 0) {
|
||||||
|
std::string path = statusText.substr(statusText.find(' ') + 1);
|
||||||
|
handleOpen(path);
|
||||||
|
isCommand = true;
|
||||||
} else {
|
} else {
|
||||||
statusMode = Status_Error;
|
statusMode = Status_Error;
|
||||||
statusText.clear();
|
statusText = "不正なコマンド。";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCommand) {
|
if (isCommand) {
|
||||||
@@ -538,6 +549,67 @@ void HexEditor::handleQuit(bool force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HexEditor::handleOpen(const std::string &path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
statusMode = Status_Error;
|
||||||
|
statusText = "利用方法: :o <filename>";
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(path, std::ios::binary);
|
||||||
|
if (!file) {
|
||||||
|
statusMode = Status_Error;
|
||||||
|
statusText = "ファイルを開くに失敗: " + path;
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> newbuf((std::istreambuf_iterator<char>(file)), {});
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if (newbuf.empty()) {
|
||||||
|
statusMode = Status_Error;
|
||||||
|
statusText = "ファイルは空です。";
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = std::move(newbuf);
|
||||||
|
fname = path;
|
||||||
|
hasFile = true;
|
||||||
|
curPos = 0;
|
||||||
|
dpOffset = 0;
|
||||||
|
modified = false;
|
||||||
|
undoStack.clear();
|
||||||
|
redoStack.clear();
|
||||||
|
lastSearch.clear();
|
||||||
|
lastHexSearch.clear();
|
||||||
|
headerLen = 0;
|
||||||
|
headerType = "";
|
||||||
|
|
||||||
|
for (const auto &sig : signatures) {
|
||||||
|
if (buf.size() >= sig.signature.size()) {
|
||||||
|
bool match = true;
|
||||||
|
for (size_t i = 0; i < sig.signature.size(); ++i) {
|
||||||
|
if (buf[i] != sig.signature[i]) {
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
headerLen = sig.signature.size();
|
||||||
|
headerType = sig.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statusMode = Status_Normal;
|
||||||
|
statusText = path + " を開きました。";
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
void HexEditor::handleSave() {
|
void HexEditor::handleSave() {
|
||||||
std::ofstream file(fname, std::ios::binary);
|
std::ofstream file(fname, std::ios::binary);
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -862,6 +934,14 @@ void HexEditor::input() {
|
|||||||
if (statusMode != Status_Normal && statusMode != Status_Error) continue;
|
if (statusMode != Status_Normal && statusMode != Status_Error) continue;
|
||||||
|
|
||||||
ch = getch();
|
ch = getch();
|
||||||
|
|
||||||
|
if (!hasFile && ch != ':' && ch != 'Z') {
|
||||||
|
statusMode = Status_Error;
|
||||||
|
statusText = "ファイルを読み込んでいません。「:o <file>」を御利用下さい。";
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ch == 'j' || ch == KEY_DOWN) && curPos + bpr < buf.size()) {
|
if ((ch == 'j' || ch == KEY_DOWN) && curPos + bpr < buf.size()) {
|
||||||
curPos += bpr; // 下
|
curPos += bpr; // 下
|
||||||
if (statusMode == Status_Error) statusMode = Status_Normal;
|
if (statusMode == Status_Error) statusMode = Status_Normal;
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class HexEditor {
|
|||||||
bool running;
|
bool running;
|
||||||
std::string lastSearch;
|
std::string lastSearch;
|
||||||
bool isMouse = false;
|
bool isMouse = false;
|
||||||
|
bool hasFile = false;
|
||||||
|
|
||||||
WINDOW *hexPanel;
|
WINDOW *hexPanel;
|
||||||
WINDOW *asciiPanel;
|
WINDOW *asciiPanel;
|
||||||
@@ -102,6 +103,7 @@ class HexEditor {
|
|||||||
void topbar();
|
void topbar();
|
||||||
void statusbar();
|
void statusbar();
|
||||||
void handleCommand();
|
void handleCommand();
|
||||||
|
void handleOpen(const std::string &path);
|
||||||
void handleSave();
|
void handleSave();
|
||||||
void handleQuit(bool force);
|
void handleQuit(bool force);
|
||||||
void handleSearch();
|
void handleSearch();
|
||||||
|
|||||||
Reference in New Issue
Block a user