You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
4.7 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. //Buffer.cpp
  2. #include "Buffer.h"
  3. using namespace std;
  4. void Buffer::display() const
  5. {
  6. int ix_stop_line_ = ix_top_line_ + window_height_;
  7. for (int i = ix_top_line_; i < ix_stop_line_; ++i)
  8. {
  9. if (i < v_lines_.size())
  10. cout << std::setw(4) << i+1 << " " << v_lines_[i];
  11. cout << '\n';
  12. }
  13. }
  14. //Pass the string by copy because I don't want to change the original, but still need to manipulate it
  15. void Buffer::split_line(string str)
  16. {
  17. // Split up the lines and then push them onto the line vector
  18. while (str.length() > maximum_length_)
  19. {
  20. //Initialize the substring and set the positions in the string where they need to exist
  21. string str_part = str;
  22. size_t curr_pos = str_part.find(" ");
  23. size_t total_pos = curr_pos;
  24. bool searching = true;
  25. //While searching for the next space in a string
  26. while (searching)
  27. {
  28. str_part = str_part.substr(curr_pos + 1, str_part.length());
  29. curr_pos = str_part.find(" ");
  30. if (curr_pos == -1)
  31. {
  32. searching = false;
  33. }
  34. else if (total_pos + curr_pos + 1 > maximum_length_)
  35. {
  36. searching = false;
  37. }
  38. else
  39. {
  40. total_pos += curr_pos + 1;
  41. }
  42. }
  43. //Check if the string part can still be chopped
  44. if (str_part.length() != str.length())
  45. {
  46. str_part = str.substr(0, total_pos);
  47. str = str.substr(total_pos + 1, str.length());
  48. v_lines_.push_back(str_part);
  49. }
  50. //Break out of the loop because there is no way to make the string shorter
  51. //I also didn't see why I can't use break and would have to use a boolean
  52. else
  53. {
  54. break;
  55. }
  56. }
  57. v_lines_.push_back(str);
  58. }
  59. size_t Buffer::get_tag_(const string & line)
  60. {
  61. size_t p_tag = line.find("<p>");
  62. size_t b_tag = line.find("<br>");
  63. if (p_tag > b_tag)
  64. return b_tag;
  65. else
  66. return p_tag;
  67. }
  68. bool Buffer::open(const string & new_file_name, bool add_to_hist_)
  69. {
  70. std::ifstream file(new_file_name);
  71. if (!file)
  72. return false;
  73. v_links_.clear();
  74. v_lines_.clear();
  75. //Note: the vector is cleared only after we know the file
  76. //opened successfully.
  77. int curr_link = 0;
  78. std::string curr_line, line;
  79. while(getline(file, line))
  80. {
  81. //Find tags and process them.
  82. for(auto tag_loc = line.find("<a "); tag_loc != -1; tag_loc = line.find("<a", tag_loc + 1))
  83. {
  84. ++curr_link;
  85. //Find the length of the tag and pull out the data from the tag.
  86. auto tag_len = line.find_first_of('>', tag_loc) - tag_loc;
  87. std::string link_tag = line.substr(tag_loc + 3, tag_len - 3);
  88. //Separate the link path and link name into separate strings. Assuming no spaces in the link path.
  89. auto second_space_loc = link_tag.find_first_of(' ', 0);
  90. std::string file_name = link_tag.substr(0, second_space_loc);
  91. std::string link_name = link_tag.substr(second_space_loc + 1);
  92. //Adds the link as a pair to a vector of links.
  93. v_links_.push_back({file_name, link_name});
  94. //Reformat the link tag to match specification.
  95. line.replace(tag_loc, tag_len + 1, "<" + link_name + ">[" + to_string(curr_link) + "]");
  96. }
  97. //Search for all paragraphs and breaks in the line and add them to the v_lines vector.
  98. for(auto _tag = get_tag_(line); _tag != -1; _tag = get_tag_(line))
  99. {
  100. //Check to see if we have a paragraph tag, so we can add a blank line.
  101. bool is_p = _tag == line.find("<p>");
  102. int tag_len = is_p ? 3 : 4;
  103. //Separate out text that should stay in the previous line and text that goes in the new line. Delete the tag in the process.
  104. std::string extra_text = line.substr(_tag + tag_len);
  105. line.erase(_tag);
  106. curr_line += line;
  107. //However, if the tag is located at the start of the file, there will be no data, so it shouldn't be added as it will be an empty line.
  108. if(curr_line != "")
  109. {
  110. split_line(curr_line);
  111. curr_line = "";
  112. if(is_p)
  113. {
  114. v_lines_.push_back("");
  115. }
  116. }
  117. //Move any remaining data on the line back into the line variable so that it can be processed.
  118. line = extra_text;
  119. }
  120. curr_line += line;
  121. }
  122. // Push the contents of curr_line as it has the last line in the file.
  123. split_line(curr_line);
  124. ix_top_line_ = 0;
  125. file_name_ = new_file_name;
  126. if(add_to_hist_)
  127. {
  128. v_hist_.push_back(file_name_);
  129. curr_link_itr = v_hist_.end() - 1;
  130. }
  131. return true;
  132. }
  133. bool Buffer::go(int link)
  134. {
  135. string f_name = v_links_[link-1].first;
  136. if(open(f_name))
  137. return true;
  138. else
  139. return false;
  140. }
  141. bool Buffer::back()
  142. {
  143. if(v_hist_.size() <= 1)
  144. return false;
  145. curr_link_itr = curr_link_itr - 1;
  146. v_hist_.erase(curr_link_itr + 1);
  147. open(*curr_link_itr, false);
  148. return true;
  149. }