1 /* 2 * SPDX-FileCopyrightText: 2017-2017 CSSlayer <wengxt@gmail.com> 3 * 4 * SPDX-License-Identifier: LGPL-2.1-or-later 5 * 6 */ 7 #ifndef _FCITX_UTILS_INPUTBUFFER_H_ 8 #define _FCITX_UTILS_INPUTBUFFER_H_ 9 10 #include <cstring> 11 #include <memory> 12 #include <string> 13 #include <fcitx-utils/flags.h> 14 #include <fcitx-utils/macros.h> 15 #include "fcitxutils_export.h" 16 17 /// \addtogroup FcitxUtils 18 /// \{ 19 /// \file 20 /// \brief Generic InputBuffer to be used to handle user's preedit. 21 22 namespace fcitx { 23 class InputBufferPrivate; 24 25 enum class InputBufferOption { 26 /// No option. 27 NoOption = 0, 28 /// The input buffer is ascii character only, non ascii char will raise 29 /// exception. 30 AsciiOnly = 1, 31 /// Whether the input buffer only supports cursor at the end of buffer. 32 FixedCursor = 1 << 1 33 }; 34 35 using InputBufferOptions = Flags<InputBufferOption>; 36 37 /// A string buffer that come with convinient functions to handle use input. 38 class FCITXUTILS_EXPORT InputBuffer { 39 public: 40 /// Create a input buffer with options. 41 /// \see InputBufferOption 42 InputBuffer(InputBufferOptions options = InputBufferOption::NoOption); 43 virtual ~InputBuffer(); 44 45 /// Get the buffer option. 46 InputBufferOptions options() const; 47 48 /// Type a C-String with length into buffer. type(const char * s,size_t length)49 bool type(const char *s, size_t length) { return typeImpl(s, length); } 50 /// Type an std::stirng to buffer. type(const std::string & s)51 bool type(const std::string &s) { return type(s.c_str(), s.size()); } 52 /// Type a C-String to buffer. type(const char * s)53 bool type(const char *s) { return type(s, std::strlen(s)); } 54 /// Type a ucs4 character to buffer. 55 bool type(uint32_t unicode); 56 57 /// Erase a range of character. 58 virtual void erase(size_t from, size_t to); 59 /// Set cursor position, by character. 60 virtual void setCursor(size_t cursor); 61 62 /// Get the max size of the buffer. 63 size_t maxSize() const; 64 65 /// Set max size of the buffer. 66 void setMaxSize(size_t s); 67 68 /// Utf8 string in the buffer. 69 const std::string &userInput() const; 70 71 /// Cursor position by utf8 character. 72 size_t cursor() const; 73 74 /// Cursor position by char (byte). 75 size_t cursorByChar() const; 76 77 /// Size of buffer, by number of utf8 character. 78 size_t size() const; 79 80 /// UCS-4 char in the buffer. Will raise exception if i is out of range. 81 uint32_t charAt(size_t i) const; 82 83 /// Byte range for character at position i. 84 std::pair<size_t, size_t> rangeAt(size_t i) const; 85 86 /// Byte size at position i. 87 size_t sizeAt(size_t i) const; 88 89 /// Whether buffer is empty. empty()90 bool empty() const { return size() == 0; } 91 92 /// Helper function to implement "delete" key. del()93 inline bool del() { 94 auto c = cursor(); 95 if (c < size()) { 96 erase(c, c + 1); 97 return true; 98 } 99 return false; 100 } 101 102 /// Helper function to implement "backspace" key. backspace()103 inline bool backspace() { 104 auto c = cursor(); 105 if (c > 0) { 106 erase(c - 1, c); 107 return true; 108 } 109 return false; 110 } 111 112 /// Clear all buffer. clear()113 void clear() { erase(0, size()); } 114 115 /// Save memory by call shrink to fit to internal buffer. 116 void shrinkToFit(); 117 118 protected: 119 /// Type a certain length of utf8 character to the buffer. [s, s+length] 120 /// need to be valid utf8 string. 121 virtual bool typeImpl(const char *s, size_t length); 122 123 private: 124 std::unique_ptr<InputBufferPrivate> d_ptr; 125 FCITX_DECLARE_PRIVATE(InputBuffer); 126 }; 127 } // namespace fcitx 128 129 #endif // _FCITX_UTILS_INPUTBUFFER_H_ 130