-
-
Save mlhaufe/99c18766acdb2807d5cc to your computer and use it in GitHub Desktop.
Tiny File System
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _WIN32 | |
#define _CRT_SECURE_NO_DEPRECATE | |
#endif | |
#define BLOCK_COUNT 16 | |
#include <cctype> | |
#include <fstream> | |
#include <iostream> | |
//#include <pthread.h> | |
#include <sstream> | |
#include <sys/stat.h> | |
#include <vector> | |
#include <map> | |
using namespace std; | |
typedef unsigned char byte; | |
FILE* tfsDisk; | |
//TODO: string or block number? | |
string workingDir; | |
//TODO: lock function that will lock a given block (range?) or wait until it can lock those blocks | |
//a mutex for each block on the disk | |
//static pthread_mutex_t mutexes[BLOCK_COUNT] = { P99_DUPL(BLOCK_COUNT, PTHREAD_MUTEX_INITIALIZER) }; | |
//<http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html> | |
//TODO: instead of structs, use a function :: (block) -> desired info? | |
struct rootDirectory { | |
vector<bool> hasFreeSpace; //[bits 0-3] 0x00 if free space list is empty, 0x0F if non-empty | |
vector<bool> freeSpaceBlockStart; //[bits 4-7] first block of free space list, or 0xF if empty | |
vector<byte> contents; //[bytes 1-10] file and folder names | |
vector<bool> descriptors; //[bytes 11-15] 10 nibbles each representing a block number for a file/dir descriptor | |
}; | |
struct directory{ | |
vector<bool> parentDirectory; //[bits 0-3] block containing parent directory | |
vector<bool> thisBlock; //[bits 4-7] block in which this directory is contained | |
vector<byte> contents; //[bytes 1-10] file and folder names | |
vector<bool> descriptors; //[bytes 11-15] 10 nibbles each representing a block number for a file/dir descriptor | |
}; | |
struct smallFile { | |
byte fileSize; //[byte 0] | |
vector<byte> data0_6; //[byte 1-7] Data bytes 0-6 | |
vector<byte> data7_14;//[byte 8-15] Data bytes 7-14 | |
}; | |
struct bigFile { | |
byte fileSize; // [byte 0] | |
vector<bool> dataBlocks; // [byte 1-7] 14 nibbles. each pointing to a data block containing file data | |
vector<byte> data0_7; //[byte 8-15] Data bytes 0-7 | |
}; | |
bool isValidPath(string& filePath) { | |
FILE* file = fopen(filePath.c_str(), "r"); | |
if (file != NULL) { | |
fclose(file); | |
return true; | |
} else { | |
cerr << "Invalid file path" << endl; | |
return false; | |
} | |
} | |
bool isValidTfsPath(string& tfsPath) { | |
//TODO | |
cout << "isValidTfsPath not implemented" << endl; | |
return true; | |
} | |
byte* loadFile(string& filePath) { | |
ifstream file(filePath); | |
file.seekg(0, ios::end); | |
size_t len = 16*2; | |
char * result = new char[len]; | |
file.seekg(0, ios::beg); | |
file.read(result, len); | |
file.close(); | |
return (byte *) result; | |
} | |
vector<string> parseCommand() { | |
vector<string> tokens; | |
char inputBuffer[256]; | |
cin.getline(inputBuffer, sizeof(inputBuffer)); | |
string inputString = inputBuffer; | |
string Buffer; | |
stringstream ss(inputString); | |
while(ss >> Buffer) | |
tokens.push_back(Buffer); | |
return tokens; | |
} | |
bool validArgCount(vector<string> tokens, int size) { | |
if(tokens.size() == size) | |
return true; | |
cerr << "Invalid number of arguments" << endl; | |
return false; | |
} | |
bool diskAvailable() { | |
if(tfsDisk) | |
return true; | |
cerr << "A disk has not been loaded" << endl; | |
return false; | |
} | |
void cmd_import(vector<string> args){ | |
if(validArgCount(args,3) && diskAvailable() && isValidPath(args[1]) && isValidTfsPath(args[2])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_export(vector<string> args){ | |
if(validArgCount(args,3) && diskAvailable() && isValidPath(args[1]) && isValidTfsPath(args[2])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_ls(vector<string> args){ | |
if(validArgCount(args,1) && diskAvailable()) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_cd(vector<string> args){ | |
if(diskAvailable()) { | |
if(args.size() == 1) { | |
//TODO: change the current working directory to the root directory | |
cout << "not implemented" << endl; | |
} else if(args.size() == 2){ | |
string tfsPath = args[1]; | |
if(isValidTfsPath(tfsPath)){ | |
//TODO: change working directory | |
//need another mutex to lock the working director var. | |
//what blocks need to be locked? | |
cout << "not implemented" << endl; | |
} | |
} else { | |
validArgCount(args,2); | |
} | |
} | |
} | |
void cmd_display(vector<string> args) { | |
if(validArgCount(args,1) && diskAvailable()) { | |
cout << "not implemented" << endl; | |
//TODO: | |
/* | |
lock disk | |
0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 //root directory | |
1 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
2 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
3 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // directory takes a whole block | |
4 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
5 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // small file takes a whole block | |
6 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // large file takes a whole block + 1-14 blocks | |
7 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
8 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
9 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
A | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
B | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
C | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
D | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
E | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
F | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
unlock disk | |
*/ | |
} | |
} | |
void cmd_open(vector<string> args){ | |
if(validArgCount(args,2) && isValidPath(args[1])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_create(vector<string> args){ | |
if(validArgCount(args,2) && isValidPath(args[1])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_exit(vector<string> args){ | |
if(validArgCount(args,1)) { | |
//TODO | |
// wait for mutexes to unlock | |
// close file | |
// exit program | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_mkdir(vector<string> args){ | |
if(validArgCount(args,2) && diskAvailable() && isValidTfsPath(args[1])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void cmd_rm(vector<string> args){ | |
if(validArgCount(args,2) && diskAvailable() && isValidTfsPath(args[1])) { | |
//TODO | |
cout << "not implemented" << endl; | |
} | |
} | |
void mountDisk(int argc, char *argv[]) { | |
if(argc == 1) { | |
tfsDisk = 0; | |
} else if(argc == 2) { | |
vector<string> cmd; | |
cmd.push_back("open"); | |
cmd.push_back(argv[1]); | |
cmd_open(cmd); | |
} else { | |
cerr << "usage: " << argv[0] << " [TFS-disk path]" << endl; | |
exit(EXIT_FAILURE); | |
} | |
} | |
/* | |
byte * loadDisk(int argc, char *argv[]) { | |
byte * tfsDisk; | |
if(argc == 1) { | |
tfsDisk = new byte[16*2]; | |
} else if(argc == 2) { | |
string path(argv[1]); | |
if(!validPath(path)) { | |
cerr << "Invalid TFS-Disk"; | |
exit(EXIT_FAILURE); | |
} else { | |
tfsDisk = loadFile(path); | |
} | |
} else { | |
cerr << "usage: " << argv[0] << " [TFS-disk path]"; | |
exit(EXIT_FAILURE); | |
} | |
return tfsDisk; | |
}*/ | |
typedef void (*function)(vector<string>); //function pointer type | |
typedef map<string,function> commandMap; | |
int main(int argc, char *argv[]) { | |
commandMap cmdMap; | |
cmdMap.insert(make_pair("import",&cmd_import)); | |
cmdMap.insert(make_pair("export",&cmd_export)); | |
cmdMap.insert(make_pair("ls",&cmd_ls)); | |
cmdMap.insert(make_pair("cd",&cmd_cd)); | |
cmdMap.insert(make_pair("display",&cmd_display)); | |
cmdMap.insert(make_pair("open",&cmd_open)); | |
cmdMap.insert(make_pair("create",&cmd_create)); | |
cmdMap.insert(make_pair("exit",&cmd_exit)); | |
cmdMap.insert(make_pair("mkdir",&cmd_mkdir)); | |
cmdMap.insert(make_pair("rm",&cmd_rm)); | |
mountDisk(argc,argv); | |
workingDir = ""; | |
//TODO: reset mutex array | |
while(true) { | |
cout << "TFS " << "<dir>" << ": "; | |
vector<string> tokens = parseCommand(); | |
if(tokens.size() == 0 || tokens.size() > 3) { | |
cerr << "Invalid command" << endl; | |
} else { | |
//TODO: create a new thread for each command? | |
//https://stackoverflow.com/questions/13203307/variable-number-of-threads-c | |
string cmd = tokens[0]; | |
if(cmdMap.count(cmd)){ | |
commandMap::const_iterator iter = cmdMap.find(cmd); | |
(*iter->second)(tokens); | |
} else { | |
cerr << "Invalid command" << endl; | |
} | |
} | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
04425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E2500000004425248450000000000001E25000000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment