Skip to content

Commit

Permalink
refactor: more iolayer abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
mhx committed Dec 26, 2023
1 parent ebc3176 commit 140819c
Show file tree
Hide file tree
Showing 18 changed files with 410 additions and 227 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ list(
add_library(dwarfs ${LIBDWARFS_SRC})
add_library(dwarfs_compression ${LIBDWARFS_COMPRESSION_SRC})
add_library(dwarfs_categorizer ${LIBDWARFS_CATEGORIZER_SRC})
add_library(dwarfs_tool src/dwarfs/tool.cpp)
add_library(dwarfs_tool src/dwarfs/tool.cpp src/dwarfs/iolayer.cpp)

add_library(dwarfs_compression_metadata src/dwarfs/compression_metadata_requirements.cpp)

Expand Down
8 changes: 3 additions & 5 deletions include/dwarfs/console_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,15 @@
namespace dwarfs {

class progress;
class terminal;

class console_writer : public stream_logger {
public:
using get_term_width_type = std::function<size_t()>;

enum display_mode { NORMAL, REWRITE };
enum progress_mode { NONE, SIMPLE, ASCII, UNICODE };

console_writer(std::ostream& os, progress_mode pg_mode,
get_term_width_type get_term_width, level_type threshold,
console_writer(std::shared_ptr<terminal const> term, std::ostream& os,
progress_mode pg_mode, level_type threshold,
display_mode mode = NORMAL, bool verbose = false);

void update(progress& p, bool last);
Expand All @@ -58,7 +57,6 @@ class console_writer : public stream_logger {
double frac_;
std::atomic<size_t> counter_{0};
progress_mode const pg_mode_;
get_term_width_type get_term_width_;
display_mode const mode_;
};
} // namespace dwarfs
8 changes: 4 additions & 4 deletions include/dwarfs/detail/multi_queue_block_merger_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class multi_queue_block_merger_impl : public block_merger_base,
}

void dump_state(std::string what, termcolor color) const {
std::cout << terminal_colored(fmt::format("**** {} ****", what), color)
std::cout << terminal_ansi_colored(fmt::format("**** {} ****", what), color)
<< std::endl;

std::cout << "index: " << active_slot_index_
Expand All @@ -174,11 +174,11 @@ class multi_queue_block_merger_impl : public block_merger_base,
for (size_t i = 0; i < active_slots_.size(); ++i) {
auto const& src = active_slots_[i];
if (src) {
std::cout << terminal_colored(
std::cout << terminal_ansi_colored(
fmt::format("{} ", src.value()),
i == active_slot_index_ ? termcolor::BOLD_GREEN : termcolor::GRAY);
} else {
std::cout << terminal_colored("- ", termcolor::GRAY);
std::cout << terminal_ansi_colored("- ", termcolor::GRAY);
}
}
std::cout << std::endl;
Expand All @@ -205,7 +205,7 @@ class multi_queue_block_merger_impl : public block_merger_base,
fmt::format("blocks({}): {} -> {}", src, q.size(), queued_sizes);

if (src == active_slots_[active_slot_index_]) {
std::cout << terminal_colored(text, termcolor::BOLD_GREEN);
std::cout << terminal_ansi_colored(text, termcolor::BOLD_GREEN);
} else {
std::cout << text;
}
Expand Down
42 changes: 42 additions & 0 deletions include/dwarfs/iolayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz ([email protected])
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include <iosfwd>
#include <memory>

namespace dwarfs {

class os_access;
class terminal;

struct iolayer {
static iolayer const& system_default();

std::shared_ptr<os_access> os;
std::shared_ptr<terminal const> term;
std::istream& in;
std::ostream& out;
std::ostream& err;
};

} // namespace dwarfs
19 changes: 17 additions & 2 deletions include/dwarfs/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

namespace dwarfs {

class terminal;

class logger {
public:
enum level_type : unsigned { ERROR, WARN, INFO, VERBOSE, DEBUG, TRACE };
Expand Down Expand Up @@ -81,8 +83,12 @@ class logger {

class stream_logger : public logger {
public:
stream_logger(std::ostream& os = std::cerr, level_type threshold = WARN,
bool with_context = false);
stream_logger(std::shared_ptr<terminal const> term, std::ostream& os,
level_type threshold = WARN, bool with_context = false);

[[deprecated]] stream_logger(std::ostream& os = std::cerr,
level_type threshold = WARN,
bool with_context = false);

void write(level_type level, const std::string& output, char const* file,
int line) override;
Expand All @@ -99,6 +105,7 @@ class stream_logger : public logger {
std::mutex& log_mutex() const { return mx_; }
bool log_is_colored() const { return color_; }
level_type log_threshold() const { return threshold_.load(); }
terminal const& term() const { return *term_; }

private:
std::ostream& os_;
Expand All @@ -107,6 +114,14 @@ class stream_logger : public logger {
bool const color_;
bool const enable_stack_trace_;
bool with_context_;
std::shared_ptr<terminal const> term_;
};

class null_logger : public logger {
public:
null_logger() = default;

void write(level_type, const std::string&, char const*, int) override {}
};

class level_logger {
Expand Down
27 changes: 20 additions & 7 deletions include/dwarfs/terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#pragma once

#include <iosfwd>
#include <memory>
#include <string>
#include <string_view>

namespace dwarfs {

Expand Down Expand Up @@ -56,17 +59,27 @@ enum class termcolor {

enum class termstyle { NORMAL, BOLD, DIM };

void setup_terminal();
class terminal {
public:
virtual ~terminal() = default;

size_t get_term_width();
static std::unique_ptr<terminal const> create();
static void setup();

bool stream_is_fancy_terminal(std::ostream& os);
virtual size_t width() const = 0;
virtual bool is_fancy(std::ostream& os) const = 0;
virtual std::string_view
color(termcolor color, termstyle style = termstyle::NORMAL) const = 0;
virtual std::string
colored(std::string text, termcolor color, bool enable = true,
termstyle style = termstyle::NORMAL) const = 0;
};

char const*
terminal_color(termcolor color, termstyle style = termstyle::NORMAL);
std::string_view
terminal_ansi_color(termcolor color, termstyle style = termstyle::NORMAL);

std::string
terminal_colored(std::string text, termcolor color, bool enable = true,
termstyle style = termstyle::NORMAL);
terminal_ansi_colored(std::string_view text, termcolor color,
bool enable = true, termstyle style = termstyle::NORMAL);

} // namespace dwarfs
20 changes: 10 additions & 10 deletions include/dwarfs_tool_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#pragma once

#include <iosfwd>
#include <memory>

#include "dwarfs/types.h"

Expand All @@ -34,20 +33,21 @@

namespace dwarfs {

class os_access;
struct iolayer;

struct iolayer {
std::shared_ptr<os_access> os;
std::istream& in;
std::ostream& out;
std::ostream& err;
};

int mkdwarfs_main(int argc, sys_char** argv, iolayer& iol);
int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol);
int mkdwarfs_main(int argc, sys_char** argv);

int dwarfsck_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsck_main(int argc, sys_char** argv);

int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsextract_main(int argc, sys_char** argv);

int dwarfsbench_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfsbench_main(int argc, sys_char** argv);

int dwarfs_main(int argc, sys_char** argv, iolayer const& iol);
int dwarfs_main(int argc, sys_char** argv);

} // namespace dwarfs
30 changes: 15 additions & 15 deletions src/dwarfs/console_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ std::string progress_bar(size_t width, double frac, bool unicode) {
return rv;
}

void output_context_line(std::ostream& os, progress::context& ctx, size_t width,
bool unicode_bar, bool colored) {
void output_context_line(terminal const& term, std::ostream& os,
progress::context& ctx, size_t width, bool unicode_bar,
bool colored) {
auto st = ctx.get_status();
size_t progress_w = 0;
size_t speed_w = 0;
Expand Down Expand Up @@ -133,24 +134,22 @@ void output_context_line(std::ostream& os, progress::context& ctx, size_t width,
}
}

os << terminal_colored(st.context, st.color, colored, termstyle::BOLD);
os << term.colored(st.context, st.color, colored, termstyle::BOLD);

os << terminal_colored(fmt::format("{:<{}} {}{}", st.status_string,
status_w - st.context.size(), progress,
speed),
st.color, colored);
os << term.colored(fmt::format("{:<{}} {}{}", st.status_string,
status_w - st.context.size(), progress, speed),
st.color, colored);
}

} // namespace

console_writer::console_writer(std::ostream& os, progress_mode pg_mode,
get_term_width_type get_term_width,
console_writer::console_writer(std::shared_ptr<terminal const> term,
std::ostream& os, progress_mode pg_mode,
level_type threshold, display_mode mode,
bool with_context)
: stream_logger(os, threshold, with_context)
: stream_logger(term, os, threshold, with_context)
, frac_(0.0)
, pg_mode_(pg_mode)
, get_term_width_(get_term_width)
, mode_(mode) {}

void console_writer::rewind(int next_rewind_lines) {
Expand Down Expand Up @@ -194,7 +193,7 @@ void console_writer::update(progress& p, bool last) {

std::ostringstream oss;

lazy_value width(get_term_width_);
lazy_value<size_t> width([this] { return term().width(); });

bool fancy = pg_mode_ == ASCII || pg_mode_ == UNICODE;

Expand Down Expand Up @@ -224,8 +223,8 @@ void console_writer::update(progress& p, bool last) {
switch (mode_) {
case NORMAL:
if (fancy) {
oss << terminal_colored(p.status(width.get()), termcolor::BOLD_CYAN,
log_is_colored())
oss << term().colored(p.status(width.get()), termcolor::BOLD_CYAN,
log_is_colored())
<< newline;
}

Expand Down Expand Up @@ -332,7 +331,8 @@ void console_writer::update(progress& p, bool last) {
}

for (auto const& c : ctxs) {
output_context_line(oss, *c, w, pg_mode_ == UNICODE, log_is_colored());
output_context_line(term(), oss, *c, w, pg_mode_ == UNICODE,
log_is_colored());
oss << newline;
}

Expand Down
41 changes: 41 additions & 0 deletions src/dwarfs/iolayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz ([email protected])
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/

#include <iostream>

#include "dwarfs/iolayer.h"
#include "dwarfs/os_access_generic.h"
#include "dwarfs/terminal.h"

namespace dwarfs {

iolayer const& iolayer::system_default() {
static iolayer const iol{
.os = std::make_shared<os_access_generic>(),
.term = terminal::create(),
.in = std::cin,
.out = std::cout,
.err = std::cerr,
};
return iol;
}

} // namespace dwarfs
Loading

0 comments on commit 140819c

Please sign in to comment.