pmt: reformat code and improve

This commit is contained in:
2025-08-13 09:54:11 +03:00
parent d74f385a68
commit 0bc5f70294
14 changed files with 127 additions and 77 deletions

View File

@@ -3902,9 +3902,9 @@ get_default_flag_values(const std::string &str);
/// Get a vector of short names, one of long names, and a single name /// Get a vector of short names, one of long names, and a single name
CLI11_INLINE CLI11_INLINE
std::tuple<std::vector<std::string>, std::vector<std::string>, std::string> std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
get_names(const std::vector<std::string> &input, get_names(const std::vector<std::string> &input,
bool allow_non_standard = false); bool allow_non_standard = false);
} // namespace detail } // namespace detail
@@ -3995,8 +3995,8 @@ get_default_flag_values(const std::string &str) {
} }
CLI11_INLINE CLI11_INLINE
std::tuple<std::vector<std::string>, std::vector<std::string>, std::string> std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
get_names(const std::vector<std::string> &input, bool allow_non_standard) { get_names(const std::vector<std::string> &input, bool allow_non_standard) {
std::vector<std::string> short_names; std::vector<std::string> short_names;
std::vector<std::string> long_names; std::vector<std::string> long_names;

View File

@@ -17,9 +17,9 @@
#ifndef LIBPMT_LIB_HPP #ifndef LIBPMT_LIB_HPP
#define LIBPMT_LIB_HPP #define LIBPMT_LIB_HPP
#include <CLI/CLI11.hpp>
#include <libhelper/lib.hpp> #include <libhelper/lib.hpp>
#include <libpartition_map/lib.hpp> #include <libpartition_map/lib.hpp>
#include <CLI/CLI11.hpp>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -40,14 +40,17 @@ std::vector<std::string> splitIfHasDelim(const std::string &s, const char delim,
} }
void setupBufferSize(uint64_t &size, const std::string &entry) { void setupBufferSize(uint64_t &size, const std::string &entry) {
if (Variables->PartMap->hasPartition(entry) && Variables->PartMap->sizeOf(entry) % size != 0) { if (Variables->PartMap->hasPartition(entry) &&
println("%sWARNING%s: Specified buffer size is invalid for %s! Using different buffer size for %s.", Variables->PartMap->sizeOf(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! Using "
"different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data()); YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1; size = Variables->PartMap->sizeOf(entry) % 4096 == 0 ? 4096 : 1;
} else if (Helper::fileIsExists(entry)) { } else if (Helper::fileIsExists(entry)) {
if (Helper::fileSize(entry) % size != 0) { if (Helper::fileSize(entry) % size != 0) {
println("%sWARNING%s: Specified buffer size is invalid for %s! using different buffer size for %s.", println("%sWARNING%s: Specified buffer size is invalid for %s! using "
YELLOW, STYLE_RESET, entry.data(), entry.data()); "different buffer size for %s.",
YELLOW, STYLE_RESET, entry.data(), entry.data());
size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1; size = Helper::fileSize(entry) % 4096 == 0 ? 4096 : 1;
} }
} }

View File

@@ -40,8 +40,10 @@ basic_variables::basic_variables()
: logFile("/sdcard/Documents/last_pmt_logs.log"), onLogical(false), : logFile("/sdcard/Documents/last_pmt_logs.log"), onLogical(false),
quietProcess(false), verboseMode(false), viewVersion(false), quietProcess(false), verboseMode(false), viewVersion(false),
forceProcess(false) { forceProcess(false) {
try { PartMap = new PartitionMap::BuildMap(); } try {
catch (std::exception&) {} PartMap = new PartitionMap::BuildMap();
} catch (std::exception &) {
}
} }
int Main(int argc, char **argv) { int Main(int argc, char **argv) {
@@ -98,7 +100,8 @@ int Main(int argc, char **argv) {
AppMain); AppMain);
FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain); FuncManager.registerFunction(std::make_unique<typeFunction>(), AppMain);
FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain); FuncManager.registerFunction(std::make_unique<rebootFunction>(), AppMain);
// FuncManager.registerFunction(std::make_unique<memoryTestFunction>(), AppMain); // FuncManager.registerFunction(std::make_unique<memoryTestFunction>(),
// AppMain);
CLI11_PARSE(AppMain, argc, argv); CLI11_PARSE(AppMain, argc, argv);
@@ -116,7 +119,7 @@ int Main(int argc, char **argv) {
"(--search-path)"); "(--search-path)");
if (!Helper::hasSuperUser()) { if (!Helper::hasSuperUser()) {
if (!((FuncManager.isUsed("rebootFunction") || FuncManager.isUsed("memoryTestFunction")) && Helper::hasAdbPermissions())) if (!((FuncManager.isUsed("rebootFunction") /* || FuncManager.isUsed("memoryTestFunction") */) && Helper::hasAdbPermissions()))
throw Error( throw Error(
"Partition Manager Tool is requires super-user privileges!\n"); "Partition Manager Tool is requires super-user privileges!\n");
} }

View File

@@ -28,7 +28,8 @@
namespace PartitionManager { namespace PartitionManager {
pair backupFunction::runAsync(const std::string &partitionName, pair backupFunction::runAsync(const std::string &partitionName,
const std::string &outputName, const uint64_t bufferSize) { const std::string &outputName,
const uint64_t bufferSize) {
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -75,7 +76,7 @@ pair backupFunction::runAsync(const std::string &partitionName,
LOGN(BFUN, INFO) << "Writing partition " << partitionName LOGN(BFUN, INFO) << "Writing partition " << partitionName
<< " to file: " << outputName << std::endl; << " to file: " << outputName << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize]; auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
@@ -114,9 +115,10 @@ bool backupFunction::init(CLI::App &_app) {
cmd->add_option("-O,--output-directory", outputDirectory, cmd->add_option("-O,--output-directory", outputDirectory,
"Directory to save the partition image(s)") "Directory to save the partition image(s)")
->check(CLI::ExistingDirectory); ->check(CLI::ExistingDirectory);
cmd->add_option( cmd->add_option("-b,--buffer-size", bufferSize,
"-b,--buffer-size", bufferSize, "Buffer size for reading partition(s) and writing to file(s)")
"Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); ->transform(CLI::AsSizeValue(false))
->default_val("4KB");
return true; return true;
} }

View File

@@ -25,7 +25,8 @@ Copyright 2025 Yağız Zengin
#define EFUN "eraseFunction" #define EFUN "eraseFunction"
namespace PartitionManager { namespace PartitionManager {
pair eraseFunction::runAsync(const std::string &partitionName, const uint64_t bufferSize) { pair eraseFunction::runAsync(const std::string &partitionName,
const uint64_t bufferSize) {
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
return {format("Couldn't find partition: %s", partitionName.data()), false}; return {format("Couldn't find partition: %s", partitionName.data()), false};
@@ -62,7 +63,7 @@ pair eraseFunction::runAsync(const std::string &partitionName, const uint64_t bu
LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName LOGN(EFUN, INFO) << "Writing zero bytes to partition: " << partitionName
<< std::endl; << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize]; auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
@@ -93,7 +94,9 @@ bool eraseFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_option("-b,--buffer-size", bufferSize, cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for writing zero bytes to partition(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for writing zero bytes to partition(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
return true; return true;
} }

View File

@@ -26,7 +26,8 @@ Copyright 2025 Yağız Zengin
namespace PartitionManager { namespace PartitionManager {
pair flashFunction::runAsync(const std::string &partitionName, pair flashFunction::runAsync(const std::string &partitionName,
const std::string &imageName, const uint64_t bufferSize) { const std::string &imageName,
const uint64_t bufferSize) {
if (!Helper::fileIsExists(imageName)) if (!Helper::fileIsExists(imageName))
return {format("Couldn't find image file: %s", imageName.data()), false}; return {format("Couldn't find image file: %s", imageName.data()), false};
if (!Variables->PartMap->hasPartition(partitionName)) if (!Variables->PartMap->hasPartition(partitionName))
@@ -73,7 +74,7 @@ pair flashFunction::runAsync(const std::string &partitionName,
LOGN(FFUN, INFO) << "Writing image " << imageName LOGN(FFUN, INFO) << "Writing image " << imageName
<< " to partition: " << partitionName << std::endl; << " to partition: " << partitionName << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize]; auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
memset(buffer, 0x00, bufferSize); memset(buffer, 0x00, bufferSize);
@@ -99,8 +100,10 @@ bool flashFunction::init(CLI::App &_app) {
cmd->add_option("imageFile(s)", rawImageNames, "Name(s) of image file(s)") cmd->add_option("imageFile(s)", rawImageNames, "Name(s) of image file(s)")
->required(); ->required();
cmd->add_option( cmd->add_option(
"-b,--buffer-size", bufferSize, "-b,--buffer-size", bufferSize,
"Buffer size for reading image(s) and writing to partition(s)")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for reading image(s) and writing to partition(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
cmd->add_option("-I,--image-directory", imageDirectory, cmd->add_option("-I,--image-directory", imageDirectory,
"Directory to find image(s) and flash to partition(s)"); "Directory to find image(s) and flash to partition(s)");

View File

@@ -36,13 +36,17 @@ bool infoFunction::init(CLI::App &_app) {
->delimiter(','); ->delimiter(',');
cmd->add_flag("-J,--json", jsonFormat, cmd->add_flag("-J,--json", jsonFormat,
"Print info(s) as JSON body. The body of each partition will " "Print info(s) as JSON body. The body of each partition will "
"be written separately")->default_val(false); "be written separately")
->default_val(false);
cmd->add_option("--json-partition-name", jNamePartition, cmd->add_option("--json-partition-name", jNamePartition,
"Speficy partition name element for JSON body")->default_val("name"); "Speficy partition name element for JSON body")
->default_val("name");
cmd->add_option("--json-size-name", jNameSize, cmd->add_option("--json-size-name", jNameSize,
"Speficy size element name for JSON body")->default_val("size"); "Speficy size element name for JSON body")
->default_val("size");
cmd->add_option("--json-logical-name", jNameLogical, cmd->add_option("--json-logical-name", jNameLogical,
"Speficy logical element name for JSON body")->default_val("isLogical"); "Speficy logical element name for JSON body")
->default_val("isLogical");
return true; return true;
} }

View File

@@ -5,7 +5,7 @@ Copyright 2025 Yağız Zengin
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,56 +14,73 @@ Copyright 2025 Yağız Zengin
limitations under the License. limitations under the License.
*/ */
#include <chrono>
#include <random>
#include <fcntl.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "functions.hpp" #include "functions.hpp"
#include <PartitionManager/PartitionManager.hpp> #include <PartitionManager/PartitionManager.hpp>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <random>
#include <unistd.h>
#define MTFUN "memoryTestFunction" #define MTFUN "memoryTestFunction"
namespace PartitionManager { namespace PartitionManager {
bool memoryTestFunction::init(CLI::App &_app) { bool memoryTestFunction::init(CLI::App &_app) {
LOGN(MTFUN, INFO) << "Initializing variables of memory test function." << std::endl; LOGN(MTFUN, INFO) << "Initializing variables of memory test function."
<< std::endl;
cmd = _app.add_subcommand("memtest", "Test your write/read speed of device."); cmd = _app.add_subcommand("memtest", "Test your write/read speed of device.");
cmd->add_option("testDirectory", testPath, "Path to test directory")->default_val("/data/local/tmp")->check([&](const std::string &val) { cmd->add_option("testDirectory", testPath, "Path to test directory")
if (val != "/data/local/tmp" && !Helper::directoryIsExists(val)) ->default_val("/data/local/tmp")
return std::string("Couldn't find directory: " + val + ", no root? Try executing in ADB shell."); ->check([&](const std::string &val) {
return std::string(); if (val != "/data/local/tmp" && !Helper::directoryIsExists(val))
}); return std::string("Couldn't find directory: " + val +
cmd->add_option("-b,--buffer-size", bufferSize, "Buffer size for reading partition(s) and writing to file(s)")->transform(CLI::AsSizeValue(false))->default_val("4MB"); ", no root? Try executing in ADB shell.");
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")->transform(CLI::AsSizeValue(false))->default_val("1GB"); return std::string();
cmd->add_flag("--no-write-test", doNotWriteTest, "Don't write test data to disk")->default_val(false); });
cmd->add_flag("--no-read-test", doNotReadTest, "Don't read test data from disk")->default_val(false); cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for reading partition(s) and writing to file(s)")
->transform(CLI::AsSizeValue(false))
->default_val("4MB");
cmd->add_option("-s,--file-size", testFileSize, "File size of test file")
->transform(CLI::AsSizeValue(false))
->default_val("1GB");
cmd->add_flag("--no-write-test", doNotWriteTest,
"Don't write test data to disk")
->default_val(false);
cmd->add_flag("--no-read-test", doNotReadTest,
"Don't read test data from disk")
->default_val(false);
return true; return true;
} }
bool memoryTestFunction::run() { bool memoryTestFunction::run() {
if (doNotReadTest && doNotWriteTest) if (doNotReadTest && doNotWriteTest)
throw Error("There must be at least one test transaction, but all of them are blocked"); throw Error("There must be at least one test transaction, but all of them "
"are blocked");
LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl; LOGN(MTFUN, INFO) << "Starting memory test on " << testPath << std::endl;
Helper::garbageCollector collector; Helper::garbageCollector collector;
const std::string test = testPath + "/test.bin"; const std::string test = testPath + "/test.bin";
LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl; LOGN(MTFUN, INFO) << "Generating random data for testing" << std::endl;
auto *buffer = new(std::nothrow) char[bufferSize]; auto *buffer = new (std::nothrow) char[bufferSize];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
std::mt19937 rng(std::random_device{}()); std::mt19937 rng(std::random_device{}());
std::uniform_int_distribution<int> dist(0, 255); std::uniform_int_distribution<int> dist(0, 255);
for (size_t i = 0; i < bufferSize; i++) buffer[i] = static_cast<char>(dist(rng)); for (size_t i = 0; i < bufferSize; i++)
buffer[i] = static_cast<char>(dist(rng));
if (!doNotWriteTest) { if (!doNotWriteTest) {
const int wfd = Helper::openAndAddToCloseList(test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); const int wfd = Helper::openAndAddToCloseList(
if (wfd < 0) throw Error("Can't open/create test file: %s", strerror(errno)); test, collector, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);
if (wfd < 0)
throw Error("Can't open/create test file: %s", strerror(errno));
LOGN(MTFUN, INFO) << "Write test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential write test started!" << std::endl;
const auto startWrite = std::chrono::high_resolution_clock::now(); const auto startWrite = std::chrono::high_resolution_clock::now();
ssize_t bytesWritten = 0; ssize_t bytesWritten = 0;
while (bytesWritten < testFileSize) { while (bytesWritten < testFileSize) {
@@ -73,23 +90,31 @@ bool memoryTestFunction::run() {
} }
const auto endWrite = std::chrono::high_resolution_clock::now(); const auto endWrite = std::chrono::high_resolution_clock::now();
const double writeTime = std::chrono::duration<double>(endWrite - startWrite).count(); const double writeTime =
println("Write speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / writeTime); std::chrono::duration<double>(endWrite - startWrite).count();
LOGN(MTFUN, INFO) << "Write test done!" << std::endl; println("Sequential write speed: %f MB/s",
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
writeTime);
LOGN(MTFUN, INFO) << "Sequential write test done!" << std::endl;
} }
if (!doNotReadTest) { if (!doNotReadTest) {
const int rfd = Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC); const int rfd =
Helper::openAndAddToCloseList(test, collector, O_RDONLY | O_SYNC);
if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno)); if (rfd < 0) throw Error("Can't open test file: %s", strerror(errno));
LOGN(MTFUN, INFO) << "Read test started!" << std::endl; LOGN(MTFUN, INFO) << "Sequential read test started!" << std::endl;
const auto startRead = std::chrono::high_resolution_clock::now(); const auto startRead = std::chrono::high_resolution_clock::now();
while (read(rfd, buffer, bufferSize) > 0) {} while (read(rfd, buffer, bufferSize) > 0) {
}
const auto endRead = std::chrono::high_resolution_clock::now(); const auto endRead = std::chrono::high_resolution_clock::now();
const double read_time = std::chrono::duration<double>(endRead - startRead).count(); const double read_time =
println("Read speed: %f MB/s", (static_cast<double>(testFileSize) / (1024.0 * 1024.0)) / read_time); std::chrono::duration<double>(endRead - startRead).count();
LOGN(MTFUN, INFO) << "Read test done!" << std::endl; println("Sequential read speed: %f MB/s",
(static_cast<double>(testFileSize) / (1024.0 * 1024.0)) /
read_time);
LOGN(MTFUN, INFO) << "Sequential read test done!" << std::endl;
} }
Helper::eraseEntry(test); Helper::eraseEntry(test);

View File

@@ -36,16 +36,21 @@ bool partitionSizeFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_flag("--as-byte", asByte, cmd->add_flag("--as-byte", asByte,
"Tell input size of partition list as byte.")->default_val(false); "Tell input size of partition list as byte.")
->default_val(false);
cmd->add_flag("--as-kilobyte", asKiloBytes, cmd->add_flag("--as-kilobyte", asKiloBytes,
"Tell input size of partition list as kilobyte.")->default_val(false); "Tell input size of partition list as kilobyte.")
->default_val(false);
cmd->add_flag("--as-megabyte", asMega, cmd->add_flag("--as-megabyte", asMega,
"Tell input size of partition list as megabyte.")->default_val(false); "Tell input size of partition list as megabyte.")
->default_val(false);
cmd->add_flag("--as-gigabyte", asGiga, cmd->add_flag("--as-gigabyte", asGiga,
"Tell input size of partition list as gigabyte.")->default_val(false); "Tell input size of partition list as gigabyte.")
->default_val(false);
cmd->add_flag("--only-size", onlySize, cmd->add_flag("--only-size", onlySize,
"Tell input size of partition list as not printing multiple " "Tell input size of partition list as not printing multiple "
"and partition name.")->default_val(false); "and partition name.")
->default_val(false);
return true; return true;
} }

View File

@@ -27,11 +27,15 @@ bool typeFunction::init(CLI::App &_app) {
->required() ->required()
->delimiter(','); ->delimiter(',');
cmd->add_option("-b,--buffer-size", bufferSize, cmd->add_option("-b,--buffer-size", bufferSize,
"Buffer size for max seek depth")->transform(CLI::AsSizeValue(false))->default_val("4KB"); "Buffer size for max seek depth")
->transform(CLI::AsSizeValue(false))
->default_val("4KB");
cmd->add_flag("--only-check-android-magics", onlyCheckAndroidMagics, cmd->add_flag("--only-check-android-magics", onlyCheckAndroidMagics,
"Only check Android magic values.")->default_val(false); "Only check Android magic values.")
->default_val(false);
cmd->add_flag("--only-check-filesystem-magics", onlyCheckFileSystemMagics, cmd->add_flag("--only-check-filesystem-magics", onlyCheckFileSystemMagics,
"Only check filesystem magic values.")->default_val(false); "Only check filesystem magic values.")
->default_val(false);
return true; return true;
} }

View File

@@ -286,8 +286,8 @@ public:
/** /**
* Get Map_t object reference * Get Map_t object reference
*/ */
Map_t& operator*(); Map_t &operator*();
const Map_t& operator*() const; const Map_t &operator*() const;
}; };
using Error = Helper::Error; using Error = Helper::Error;

View File

@@ -89,7 +89,7 @@ bool hasMagic(const uint64_t magic, const ssize_t buf,
return false; return false;
} }
auto *buffer = new(std::nothrow) uint8_t[buf]; auto *buffer = new (std::nothrow) uint8_t[buf];
collector.delAfterProgress(buffer); collector.delAfterProgress(buffer);
const ssize_t bytesRead = read(fd, buffer, buf); const ssize_t bytesRead = read(fd, buffer, buf);

View File

@@ -251,11 +251,9 @@ bool basic_partition_map_builder::operator()(const std::string_view path) {
return readDirectory(path); return readDirectory(path);
} }
Map_t& basic_partition_map_builder::operator*() { Map_t &basic_partition_map_builder::operator*() { return _current_map; }
return _current_map;
}
const Map_t& basic_partition_map_builder::operator*() const { const Map_t &basic_partition_map_builder::operator*() const {
return _current_map; return _current_map;
} }