Finalize cd in multi level

This commit is contained in:
Baptiste Wicht 2013-12-04 21:36:40 +01:00
parent 99228505b6
commit f291dd0023
6 changed files with 49 additions and 25 deletions

View File

@ -69,8 +69,8 @@ uint64_t free_size();
const disk_descriptor* mounted_disk();
const partition_descriptor* mounted_partition();
const string& current_directory();
void set_current_directory(const string& directory = string());
//TODO It is not a really good practice to directly expose the vector
vector<string>& current_directory();
}

View File

@ -9,7 +9,7 @@ namespace fat32 {
typedef const disks::disk_descriptor& dd;
vector<disks::file> ls(dd disk, const disks::partition_descriptor& partition, const string& path);
vector<disks::file> ls(dd disk, const disks::partition_descriptor& partition, const vector<string>& path);
uint64_t free_size(dd disk, const disks::partition_descriptor& partition);
}

View File

@ -56,6 +56,10 @@ public:
return _size;
}
bool empty() const {
return _size;
}
constexpr size_type capacity() const {
return _capacity;
}
@ -70,7 +74,7 @@ public:
//Modifiers
void push_back(value_type& element){
void push_back(const value_type& element){
if(_capacity == 0){
_capacity = 1;
data = new T[_capacity];
@ -89,6 +93,10 @@ public:
data[_size++] = element;
}
void clear(){
_size = 0;
}
//Iterators
iterator begin(){

View File

@ -45,7 +45,7 @@ const disks::disk_descriptor* _mounted_disk;
const disks::partition_descriptor* _mounted_partition;
//TODO This should be improved to suppport multi level
string pwd;
vector<string> pwd;
} //end of anonymous namespace
@ -228,10 +228,6 @@ uint64_t disks::free_size(){
return fat32::free_size(*_mounted_disk, *_mounted_partition);
}
const string& disks::current_directory(){
const vector<string>& disks::current_directory(){
return pwd;
}
void disks::set_current_directory(const string& directory){
pwd = directory;
}

View File

@ -186,7 +186,7 @@ bool filename_equals(char* name, const string& path){
} //end of anonymous namespace
vector<disks::file> fat32::ls(dd disk, const disks::partition_descriptor& partition, const string& path){
vector<disks::file> fat32::ls(dd disk, const disks::partition_descriptor& partition, const vector<string>& path){
if(cached_disk != disk.uuid || cached_partition != partition.uuid){
partition_start = partition.start;
@ -204,22 +204,38 @@ vector<disks::file> fat32::ls(dd disk, const disks::partition_descriptor& partit
auto cluster_addr = cluster_lba(fat_bs->root_directory_cluster_start);
unique_heap_array<cluster_entry> root_cluster(16 * fat_bs->sectors_per_cluster);
unique_heap_array<cluster_entry> current_cluster(16 * fat_bs->sectors_per_cluster);
if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, root_cluster.get())){
if(path.empty()){
return files(root_cluster);
} else {
for(auto& entry : root_cluster){
k_print_line(path.size());
if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, current_cluster.get())){
for(auto& p : path){
bool found = false;
for(auto& entry : current_cluster){
if(entry_exists(entry) && !is_long_name(entry) && entry.attrib & 0x10){
//entry.name is not a real c_string, cannot be compared
//directly
if(filename_equals(entry.name, path)){
return files(disk, entry.cluster_low + (entry.cluster_high << 16));
if(filename_equals(entry.name, p)){
unique_heap_array<cluster_entry> cluster(16 * fat_bs->sectors_per_cluster);
if(read_sectors(disk, cluster_lba(entry.cluster_low + (entry.cluster_high << 16)),
fat_bs->sectors_per_cluster, cluster.get())){
current_cluster = move(cluster);
found = true;
} else {
return {};
}
}
}
}
if(!found){
return {};
}
}
return files(current_cluster);
}
return {};

View File

@ -475,18 +475,22 @@ void free_command(const vector<string>&){
void pwd_command(const vector<string>&){
auto& cd = disks::current_directory();
if(cd.empty()){
k_print_line("/");
} else {
k_printf("/%s\n", cd.c_str());
k_print('/');
for(auto& p : cd){
k_print(p);
k_print('/');
}
k_print_line();
}
void cd_command(const vector<string>& params){
//If there are no params, go to /
if(params.size() == 1){
disks::set_current_directory();
disks::current_directory().clear();
} else {
disks::set_current_directory(params[1]);
disks::current_directory().push_back(params[1]);
}
}