1 // Copyright 2024 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_TOOLS_INTERACTIVE_CLI_H_ 6 #define QUICHE_QUIC_TOOLS_INTERACTIVE_CLI_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "absl/strings/string_view.h" 12 #include "quiche/quic/core/io/quic_event_loop.h" 13 #include "quiche/quic/core/io/socket.h" 14 #include "quiche/common/quiche_callbacks.h" 15 16 namespace quic { 17 18 // InteractiveCli is a tool that lets the user type input while the program is 19 // outputting things into the terminal. Only works on Unix-like platforms. 20 class InteractiveCli : public QuicSocketEventListener { 21 public: 22 using LineCallback = quiche::MultiUseCallback<void(absl::string_view)>; 23 24 // `event_loop` must outlive the object. `line_callback` is called whenever 25 // user enters a line of text into the terminal. 26 InteractiveCli(QuicEventLoop* event_loop, LineCallback line_callback); 27 ~InteractiveCli(); 28 InteractiveCli(InteractiveCli&) = delete; 29 InteractiveCli(InteractiveCli&&) = delete; 30 InteractiveCli& operator=(InteractiveCli&) = delete; 31 InteractiveCli& operator=(InteractiveCli&&) = delete; 32 33 // Outputs a line of text into the terminal, and then restores the user input 34 // prompt. Use this instead of std::cout and other I/O functions. Will crash 35 // if stdin or stdout is not a terminal. Does not support any form of 36 // terminal editing except for backspace. 37 void PrintLine(absl::string_view line); 38 39 // Process kSocketReadable events on STDIN. 40 void OnSocketEvent(QuicEventLoop* event_loop, SocketFd fd, 41 QuicSocketEventMask events) override; 42 43 private: 44 // Clears the current line in the terminal. 45 void ResetLine(); 46 // Prints the pending user input. 47 void RestoreCurrentInputLine(); 48 49 QuicEventLoop* event_loop_; // Not owned. 50 LineCallback line_callback_; 51 // Avoid including termios.h by storing the old termios as an array of bytes. 52 std::unique_ptr<char[]> old_termios_ = nullptr; 53 // Buffered user input. 54 std::string current_input_line_; 55 // Prompt printed before the user input line. 56 std::string prompt_ = "> "; 57 }; 58 59 } // namespace quic 60 61 #endif // QUICHE_QUIC_TOOLS_INTERACTIVE_CLI_H_ 62