Implementing a basic directorytree structure that is derived
Implementing a basic directory-tree structure that is derived from a base tree structure.
#ifndef SRC_TREENODE_HPP_
#define SRC_TREENODE_HPP_
#include <iostream>
#include <vector>
//#define USE_OSS
#ifndef USE_OSS
#define OUT std::cout
#else
#include <sstream>
extern std::ostringstream oss;
#define OUT oss
#endif
namespace ensc251 {
static unsigned count = 0;
class TreeNode;
typedef TreeNode* (TreeNode::*action_func)(void);
typedef void (TreeNode::*traverse_func)(const TreeNode*);
class TreeNode
{
typedef std::vector<TreeNode*> TreeNodePVect;
protected:
TreeNodePVect childPVector;
public:
TreeNode() {};
TreeNode(const TreeNode& nodeToCopy) {
// ***** this needs work *****
if (nodeToCopy.childPVector.size())
add_childP(nodeToCopy.childPVector[0]->clone());
}
virtual TreeNode* clone() const { return new TreeNode(*this); };
virtual ~TreeNode() {
// do not modify this insertion on OUT
OUT << \"Destroying TreeNode with \" << childPVector.size() << \" children.\"<< std::endl;
// ***** Complete this member function *****
}
void swap(TreeNode & other) // the swap member function (should never fail!)
{
// ***** fill this in if desired *****
}
TreeNode & operator = (TreeNode other) // note: argument passed by value, copy made!
{
// ***** Complete this code *****
return *this; // by convention, always return *this
}
void add_childP(TreeNode* child) { /* ***** Complete this member function ***** */ }
void add_children(const TreeNodePVect& childPV) { childPVector.insert(childPVector.end(), childPV.begin(), childPV.end()); }
const TreeNodePVect& get_children() const { return childPVector; }
TreeNode* traverse_children_post_order(traverse_func tf, action_func af)
{
for(auto childP : childPVector) {
(childP->*tf)(this); // traverse child\'s children using tf
}
return (this->*af)();
}
TreeNode* traverse_children_pre_order(traverse_func tf, action_func af)
{
// ***** Complete this member function *****
}
TreeNode* traverse_children_in_order(traverse_func tf, action_func af)
{
// ***** Complete this member function *****
}
TreeNode* count_action()
{
count++;
return nullptr;
}
void count_traverse(const TreeNode*)
{
traverse_children_post_order(count_traverse, count_action);
}
void reset_count() { count = 0; }
unsigned get_count() const { return count; }
};
}
#endif /* SRC_TREENODE_HPP_ */
#include \"makeDirectoryTree.hpp\"
using namespace std;
int doStuff()
{
// call function to build directory tree in memory
auto root_dir1P = make_directory_tree(\".\", \"test_dir\");
if (root_dir1P) {
root_dir1P->print_traverse(nullptr);
OUT << endl;
root_dir1P->reset_count();
root_dir1P->count_traverse(nullptr);
OUT << \"Count is \" << root_dir1P->get_count() << \"\ \" << endl;
auto root_dir2 = Directory(*root_dir1P); // copy construction
root_dir2.print_traverse(nullptr);
OUT << endl;
auto root_dir3P = make_directory_tree(\"test_dir\", \"Lectures\");
if (root_dir3P) {
root_dir2 = *root_dir3P; // overloaded copy assignment operation
OUT << endl;
delete root_dir3P;
OUT << endl;
}
root_dir2.print_traverse(nullptr);
OUT << endl;
delete root_dir1P;
OUT << endl;
} // destructor for root_dir2 called.
OUT << endl;
return 0;
}
// don\'t remove the below line.
#ifndef DONT_RUN_MAIN
int main()
{
int rv = doStuff();
#ifdef USE_OSS
std::string s = oss.str();
cout << s << endl;
#endif
return rv;
}
#endif
/* End of dirTree.cpp file */
* makeDirectoryTree.cpp
#include <dirent.h>
#include <sys/stat.h>
#include <algorithm> // for find
#include \"makeDirectoryTree.hpp\"
// The below function may be replaced. Don\'t worry about trying to understand
// this version.
// traverse directories on the filesystem starting at a certain point and build
// a directory tree in memory
Directory *make_directory_tree(const std::string& path, const std::string& dir_name)
{
using namespace std;
static vector<string> ignore_list = {\".\",\"..\"};
auto newPath = path + \"\\\\\" + dir_name;
DIR *dir;
if ((dir = opendir(newPath.c_str())) == nullptr)
{
OUT << newPath.c_str() << \" Error while opening \" << newPath << endl;
return nullptr;
}
auto new_entity = new Directory(dir_name);
struct dirent *dptr;
while ((dptr = readdir(dir)))
{
if(find(ignore_list.begin(), ignore_list.end(), dptr->d_name) != ignore_list.end())
continue;
auto fullPath = newPath + \"\\\\\" + dptr->d_name;
struct stat filestat;
stat(fullPath.c_str(), &filestat);
if(S_ISDIR(filestat.st_mode))
{
auto node = make_directory_tree(newPath, dptr->d_name);
if (!node)
// add directory with no files or subdirs in case of permission problem
node = new Directory(dptr->d_name);
new_entity->add_childP(node);
}
else {
new_entity->add_file(dptr->d_name);
}
}
return new_entity;
}
/*
* makeDirectoryTree.hpp
#ifndef SRC_MAKEDIRECTORYTREE_HPP_
#define SRC_MAKEDIRECTORYTREE_HPP_
#include \"Directory.hpp\"
Directory *make_directory_tree(const std::string& path, const std::string& dir_name)
;
#endif /* SRC_MAKEDIRECTORYTREE_HPP_ */
#include \"TreeNode.hpp\"
#ifdef USE_OSS
std::ostringstream oss;
#define OUT oss
#endif
#ifndef SRC_DIRECTORY_HPP_
#define SRC_DIRECTORY_HPP_
#include \"TreeNode.hpp\"
#include <iomanip>
#include <string>
#include <vector>
class Directory : public ensc251::TreeNode
{
typedef std::vector<std::string> stringVect;
private:
std::string dir_name;
stringVect file_names;
public:
Directory(std::string m_dir_name): dir_name(m_dir_name) {}
Directory(std::string m_dir_name, stringVect m_file_names): dir_name(m_dir_name), file_names(m_file_names) {}
virtual Directory* clone() const { /* ***** Complete this member function ***** */ };
void set_dir_name(const std::string& m_dir_name){ /* ***** Complete this member function ***** */ }
const std::string & get_dir_name() { return dir_name; }
void add_file(const std::string& m_fileName) { /* ***** Complete this member function ***** */ }
void add_multiple_files(const stringVect& m_files) { file_names.insert(file_names.end(), m_files.begin(), m_files.end()); }
const stringVect & get_files() const { return file_names; }
TreeNode* print_action()
{
// Do not modify insertion on OUT in this member function!
OUT << std::setw(20) << dir_name+\"\\t|\" << \" \";
OUT << this->childPVector.size() << \" \";
for (auto file : file_names)
{
OUT << \" -\" << file;
}
OUT << std::endl;
return nullptr;
}
void print_traverse(const TreeNode*)
{
// ***** this needs work *****
// ***** encode the rules in the instructions
traverse_children_post_order(
static_cast<ensc251::traverse_func>(print_traverse),
static_cast<ensc251::action_func>(print_action));
}
};
#endif /* SRC_DIRECTORY_HPP_ */
Solution
Step 1: You get the assembly code reference, particularly you will need to know which mnemonic corresponds to which machine code




