/usr/include/dawgdic/completer.h is in libdawgdic-dev 0.4.5-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | #ifndef DAWGDIC_COMPLETER_H
#define DAWGDIC_COMPLETER_H
#include "dictionary.h"
#include "guide.h"
#include <vector>
namespace dawgdic {
class Completer {
public:
Completer()
: dic_(NULL), guide_(NULL), key_(), index_stack_(), last_index_(0) {}
Completer(const Dictionary &dic, const Guide &guide)
: dic_(&dic), guide_(&guide), key_(), index_stack_(), last_index_(0) {}
void set_dic(const Dictionary &dic) {
dic_ = &dic;
}
void set_guide(const Guide &guide) {
guide_ = &guide;
}
const Dictionary &dic() const {
return *dic_;
}
const Guide &guide() const {
return *guide_;
}
// These member functions are available only when Next() returns true.
const char *key() const {
return reinterpret_cast<const char *>(&key_[0]);
}
SizeType length() const {
return key_.size() - 1;
}
ValueType value() const {
return dic_->value(last_index_);
}
// Starts completing keys from given index and prefix.
void Start(BaseType index, const char *prefix = "") {
SizeType length = 0;
for (const char *p = prefix; *p != '\0'; ++p) {
++length;
}
Start(index, prefix, length);
}
void Start(BaseType index, const char *prefix, SizeType length) {
key_.resize(length + 1);
for (SizeType i = 0; i < length; ++i) {
key_[i] = prefix[i];
}
key_[length] = '\0';
index_stack_.clear();
if (guide_->size() != 0) {
index_stack_.push_back(index);
last_index_ = dic_->root();
}
}
// Gets the next key.
bool Next() {
if (index_stack_.empty()) {
return false;
}
BaseType index = index_stack_.back();
if (last_index_ != dic_->root()) {
UCharType child_label = guide_->child(index);
if (child_label != '\0') {
// Follows a transition to the first child.
if (!Follow(child_label, &index))
return false;
} else {
for ( ; ; ) {
UCharType sibling_label = guide_->sibling(index);
// Moves to the previous node.
if (key_.size() > 1) {
key_.resize(key_.size() - 1);
key_.back() = '\0';
}
index_stack_.resize(index_stack_.size() - 1);
if (index_stack_.empty()) {
return false;
}
index = index_stack_.back();
if (sibling_label != '\0') {
// Follows a transition to the next sibling.
if (!Follow(sibling_label, &index)) {
return false;
}
break;
}
}
}
}
// Finds a terminal.
return FindTerminal(index);
}
private:
const Dictionary *dic_;
const Guide *guide_;
std::vector<UCharType> key_;
std::vector<BaseType> index_stack_;
BaseType last_index_;
// Disallows copies.
Completer(const Completer &);
Completer &operator=(const Completer &);
// Follows a transition.
bool Follow(UCharType label, BaseType *index) {
if (!dic_->Follow(label, index)) {
return false;
}
key_.back() = label;
key_.push_back('\0');
index_stack_.push_back(*index);
return true;
}
// Finds a terminal.
bool FindTerminal(BaseType index) {
while (!dic_->has_value(index)) {
UCharType label = guide_->child(index);
if (!dic_->Follow(label, &index)) {
return false;
}
key_.back() = label;
key_.push_back('\0');
index_stack_.push_back(index);
}
last_index_ = index;
return true;
}
};
} // namespace dawgdic
#endif // DAWGDIC_COMPLETER_H
|