/ firmware / src / console / history.cpp
history.cpp
  1  #include "history.h"
  2  
  3  #include <SD.h>
  4  #include <string.h>
  5  
  6  //------------------------------------------
  7  //  History
  8  //------------------------------------------
  9  console::History::History(size_t max_entries, bool is_deduplicating)
 10      : count_(0), max_entries_(max_entries > MAX_ENTRIES ? MAX_ENTRIES : max_entries),
 11        current_index_(-1), is_deduplicating_(is_deduplicating) {}
 12  
 13  void console::History::add(const char *command) {
 14    if (!command || command[0] == '\0') return;
 15  
 16    if (is_deduplicating_ && count_ > 0) {
 17      if (strcmp(entries_[count_ - 1], command) == 0) return;
 18    }
 19  
 20    if (count_ >= max_entries_) {
 21      memmove(entries_[0], entries_[1], (count_ - 1) * ENTRY_SIZE);
 22      count_--;
 23    }
 24  
 25    strlcpy(entries_[count_], command, ENTRY_SIZE);
 26    count_++;
 27    current_index_ = -1;
 28  }
 29  
 30  const char *console::History::previous() {
 31    if (count_ == 0) return nullptr;
 32  
 33    if (current_index_ < 0)
 34      current_index_ = (int)count_ - 1;
 35    else if (current_index_ > 0)
 36      current_index_--;
 37  
 38    return entries_[current_index_];
 39  }
 40  
 41  const char *console::History::next() {
 42    if (current_index_ < 0) return nullptr;
 43  
 44    if ((size_t)current_index_ >= count_ - 1) {
 45      current_index_ = -1;
 46      return nullptr;
 47    }
 48  
 49    current_index_++;
 50    return entries_[current_index_];
 51  }
 52  
 53  void console::History::reset_position() {
 54    current_index_ = -1;
 55  }
 56  
 57  void console::History::clear() {
 58    count_ = 0;
 59    current_index_ = -1;
 60  }
 61  
 62  size_t console::History::length() const {
 63    return count_;
 64  }
 65  
 66  bool console::History::is_empty() const {
 67    return count_ == 0;
 68  }
 69  
 70  //------------------------------------------
 71  //  Persistent storage
 72  //------------------------------------------
 73  void console::History::load(const char *path) {
 74    File f = SD.open(path, FILE_READ);
 75    if (!f) return;
 76  
 77    char line[ENTRY_SIZE];
 78    size_t pos = 0;
 79  
 80    while (f.available()) {
 81      char ch = f.read();
 82      if (ch == '\n' || ch == '\r') {
 83        if (pos > 0) {
 84          line[pos] = '\0';
 85          add(line);
 86          pos = 0;
 87        }
 88        continue;
 89      }
 90      if (pos < ENTRY_SIZE - 1)
 91        line[pos++] = ch;
 92    }
 93  
 94    if (pos > 0) {
 95      line[pos] = '\0';
 96      add(line);
 97    }
 98  
 99    f.close();
100    current_index_ = -1;
101  }
102  
103  void console::History::save(const char *path) const {
104    File f = SD.open(path, FILE_WRITE);
105    if (!f) return;
106  
107    for (size_t i = 0; i < count_; i++) {
108      f.println(entries_[i]);
109    }
110  
111    f.close();
112  }