Skip to content

Commit e5fc372

Browse files
Big refactoring, bug fixes, optimizations
1 parent 01afac3 commit e5fc372

4 files changed

Lines changed: 125 additions & 102 deletions

File tree

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@ set(CMAKE_CXX_EXTENSIONS OFF)
99
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O1")
1010

1111
add_executable(binedit src/bin_editor.cpp)
12+
13+
add_custom_target(clear
14+
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/CMakeFiles
15+
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/CMakeCache.txt
16+
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/*.cmake
17+
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/Makefile
18+
DEPENDS binedit
19+
)

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# How compile:
2+
23
* `mkdir build`, `cd build`, `cmake ..`, `cmake --build .`
4+
* Or to delete all build files except executable: `mkdir build`, `cd build`, `cmake ..`, `cmake --build . --target clear`
35

46
**If you found any bugs in program, please create new** [**issue**](https://github.com/ScriptScorpion/BinEdit/issues/new) **on the Issues page**.

src/bin_editor.cpp

Lines changed: 104 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
#include <iostream>
22
#include <cstdlib>
33
#include <cctype>
4+
#include <cstring>
45
#include <filesystem>
56
#include <fstream>
7+
#include <list>
8+
#include <algorithm>
69
#include <bitset>
710
#include <sstream>
11+
#include "key_map.h"
12+
813
#ifdef _WIN32
914
#include <conio.h>
1015
#include <windows.h>
@@ -43,32 +48,20 @@
4348
}
4449
#endif
4550

46-
void out_of_the_bounds(const char val) {
47-
if (val == '\0') {
51+
void out_of_the_bounds(const std::list<std::string>::iterator val, const std::list <std::string> all_vals) {
52+
if (val == all_vals.end()) {
4853
enable(false);
4954
std::exit(0);
5055
}
5156
}
52-
void write_to_file(std::string &insiders, const char *filename) {
57+
void write_to_file(const std::list <std::string> all_vals, const char *filename) {
5358
std::ofstream output(filename, std::ios::binary);
54-
std::istringstream iss(insiders);
55-
std::string byte_str;
56-
while (iss >> byte_str) {
57-
std::bitset<8> bits(byte_str);
58-
unsigned char byte = static_cast<unsigned char>(bits.to_ulong());
59+
for (const std::string &s : all_vals) {
60+
unsigned char byte = static_cast<unsigned char>(std::stoi(s, nullptr, 2));
5961
output.write(reinterpret_cast<char*>(&byte), sizeof(byte));
6062
}
6163
output.close();
6264
}
63-
unsigned int show_all(const std::string arg) {
64-
unsigned int counter = 0;
65-
for (const char c : arg) {
66-
if (c == ' ') {
67-
counter++;
68-
}
69-
}
70-
return counter;
71-
}
7265
std::string remove_special_chars(const std::string name) {
7366
std::string name_copy;
7467
name_copy.reserve(name.length());
@@ -79,127 +72,136 @@ std::string remove_special_chars(const std::string name) {
7972
}
8073
return name_copy;
8174
}
75+
8276
int main(int argc, char *argv[]) {
77+
if (argc != 2) {
78+
std::cerr << "Only 2 arguments are possible " << "(type <" << argv[0] << " -h> for more help)" << std::endl;
79+
return 1;
80+
}
81+
if (strcmp(argv[1], "-h") == 0) {
82+
std::cout << "Usage: " << argv[0] << " <FILE>\n\n";
83+
std::cout << "Keybindings: \n\n";
84+
std::cout << " a - list all and exit\n";
85+
std::cout << " b - go backward\n";
86+
std::cout << " e - edit current line\n";
87+
std::cout << " q - exit from the program\n";
88+
std::cout << " s - go forward\n";
89+
std::cout << " w - write to the file\n";
90+
std::cout << std::endl;
91+
return 0;
92+
}
93+
8394
std::ifstream file(argv[1], std::ios::binary);
84-
if (argc != 2 || !file.good()) {
85-
std::cerr << "Only 2 arguments, example: " << argv[0] << " <file>" << std::endl;
95+
if (!file.good()) {
96+
std::cerr << "Error: file don't exists" << std::endl;
8697
return 1;
8798
}
99+
88100
std::filesystem::path file_ext1(argv[0]);
89101
std::filesystem::path file_ext2(argv[1]);
90-
if (remove_special_chars(file_ext1.replace_extension("").string()) == file_ext2.string()) {
102+
if (remove_special_chars(file_ext1.replace_extension("").string()) == remove_special_chars(file_ext2.replace_extension("").string())) {
91103
std::cerr << "Error: incorrect input file" << std::endl;
92104
return 1;
93105
}
94106

95-
std::string insiders = "";
96-
std::string word = "";
107+
std::string word {};
108+
std::list <std::string> all_values;
97109
unsigned char byte;
98110
while (file.read(reinterpret_cast<char*>(&byte), 1)) {
99111
std::bitset <8> bits(byte);
100-
insiders += bits.to_string();
101-
insiders += " ";
112+
all_values.push_back(bits.to_string());
102113
}
103114
file.close();
104-
int index = 0;
105-
int index_tmp = 0;
106-
bool edit = false;
107-
bool is_first = true;
108-
int key = 0;
109-
int iteration = 0;
110-
int bit_i = 0;
111-
std::cout << "press 's' to see a bits, press 'e' to edit this bits, press 'a' to see all values at once, press 'w' to write edited values in the file\n";
115+
std::list<std::string>::iterator index {all_values.begin()};
116+
bool edit {false};
117+
bool running {true};
118+
int key {0};
119+
unsigned int pos {1};
120+
uint8_t inline_index {0};
112121
enable(true);
113-
while (true) {
114-
std::cout << iteration << '/' << show_all(insiders) << std::endl;
115-
out_of_the_bounds(insiders[index]);
116-
iteration++;
122+
std::cout << pos << '/' << all_values.size() << '\n';
123+
while (running) {
124+
out_of_the_bounds(index, all_values);
125+
if (!edit) {
126+
std::cout << "Current value: " << *index << " " << static_cast<char>(std::stoi(*index, nullptr, 2)) << '\n';
127+
}
128+
117129
key = _getch();
130+
118131
if (edit) {
119132
std::cout << "Entered bits: ";
120133
std::cout << (char)key;
121-
if ((key == 48 || key == 49) && insiders[index] != ' ') {
122-
insiders[index] = (char)key;
123-
word[bit_i] = (char)key;
124-
index++;
125-
bit_i++;
134+
if ((key == Keys::zero || key == Keys::one) && inline_index < word.size()) {
135+
word[inline_index] = static_cast<char>(key);
126136
std::cout << '\n' << word << " " << static_cast<char>(std::stoi(word, nullptr, 2)) << '\n';
137+
++inline_index;
127138
}
128139
else {
140+
if (word != (*index)) {
141+
std::replace(all_values.begin(), all_values.end(), *index, word);
142+
}
129143
std::cout << "\n\nEditing finished\n";
130-
std::cout << "press 's' to see a bits, press 'e' to edit this bits, press 'a' to see all values at once, press 'w' to write edited values in the file" << std::endl;
131144
edit = false;
132-
word = "";
133-
bit_i = 0;
145+
inline_index = 0;
146+
word.clear();
134147
}
148+
continue;
135149
}
136150
else {
137-
if (key == 115) { // s
138-
if (iteration == 2) {
139-
is_first = false;
140-
}
141-
word = "";
142-
while (insiders[index] != ' ') {
143-
std::cout << insiders[index];
144-
word += insiders[index];
145-
index++;
146-
}
147-
std::cout << ' ' << static_cast<char>(std::stoi(word, nullptr, 2)) << std::endl;
148-
index++;
149-
}
150-
else if (key == 101) { // e
151-
edit = true;
152-
word = "";
153-
std::cout << " \nEntered editing mode\n";
154-
std::cout << "(Press 1 or 0 to edit bits)\n\n";
155-
if (is_first) {
156-
is_first = false;
157-
index_tmp = 0;
158-
while (insiders[index_tmp] != ' ') {
159-
word += insiders[index_tmp];
160-
index_tmp++;
151+
switch(key) {
152+
case Keys::s: {
153+
if (pos < all_values.size()) {
154+
++pos;
155+
++index;
156+
std::cout << pos << '/' << all_values.size() << '\n';
161157
}
162-
std::cout << "Current value: " << word << '\n';
163-
continue;
158+
break;
164159
}
165-
else {
166-
index -= 2;
167-
while (insiders[index] != ' ') {
168-
index--;
169-
}
170-
index++;
171-
index_tmp = index;
172-
while (insiders[index_tmp] != ' ') {
173-
word += insiders[index_tmp];
174-
index_tmp++;
160+
161+
case Keys::b: {
162+
if (pos > 1) {
163+
--pos;
164+
--index;
165+
std::cout << pos << '/' << all_values.size() << '\n';
175166
}
176-
std::cout << "Current value: " << word << '\n';
177-
continue;
167+
break;
178168
}
179-
}
180-
else if (key == 97) { // a
181-
for (char x : insiders) {
182-
if (isspace(x)) {
183-
std::cout << " ";
184-
}
185-
else {
186-
std::cout << x;
169+
170+
case Keys::e: {
171+
edit = true;
172+
word = (*index);
173+
std::cout << " \nEntered editing mode\n";
174+
std::cout << "(Press 1 or 0 to edit bits)\n\n";
175+
break;
176+
}
177+
178+
case Keys::w: {
179+
write_to_file(all_values, argv[1]);
180+
std::cout << "File overwrited successfully" << std::endl;
181+
running = false;
182+
break;
183+
}
184+
185+
case Keys::q: {
186+
running = false;
187+
break;
188+
}
189+
case Keys::a: {
190+
for (const std::string &s : all_values) {
191+
std::cout << s << " ";
187192
}
193+
std::cout << std::endl;
194+
running = false;
195+
break;
196+
}
197+
198+
default: {
199+
std::cout << "\nInvalid command\n";
200+
break;
188201
}
189-
std::cout << std::endl;
190-
break;
191-
}
192-
else if (key == 119) { // w
193-
write_to_file(insiders, argv[1]);
194-
std::cout << "File overwrited successfully" << std::endl;
195-
break;
196-
}
197-
else {
198-
std::cout << "\nInvalid command\n";
199-
break;
200202
}
201203
}
202204
}
203205
enable(false);
204206
return 0;
205-
}
207+
}

src/key_map.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
enum Keys {
3+
zero = 48,
4+
one = 49,
5+
a = 97,
6+
b = 98,
7+
e = 101,
8+
q = 113,
9+
s = 115,
10+
w = 119
11+
};

0 commit comments

Comments
 (0)