Created
September 18, 2017 19:25
-
-
Save Kylmakalle/40dc046fd971c409f5e98f534b85e51b to your computer and use it in GitHub Desktop.
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
#include <string> | |
#include <vector> | |
#include <iostream> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <termios.h> | |
#include <unistd.h> | |
#include <memory.h> | |
// For blocked reading pressed symbol | |
int getch(){ | |
struct termios oldt, newt; | |
char ch; | |
tcgetattr( STDIN_FILENO, &oldt ); | |
newt = oldt; | |
newt.c_lflag &= ~( ICANON | ECHO ); | |
tcsetattr( STDIN_FILENO, TCSANOW, &newt ); | |
ch = getchar(); | |
tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); | |
return ch; | |
} | |
// Class defines | |
class MenuPoint; | |
class MenuItem; | |
class MenuFunction; | |
// Classes | |
class MenuPoint // Abstract class for menu elements | |
{ | |
protected: | |
std::string name; | |
MenuPoint *parent; | |
void setParent(MenuPoint*); | |
public: | |
MenuPoint(); | |
void setName(std::string); | |
std::string getName(); | |
MenuPoint* getParent(); | |
virtual void action() = 0; // Action method | |
}; | |
class MenuItem: public MenuPoint // Menu Item class | |
{ | |
private: | |
std::string welcome_message; | |
std::vector<MenuPoint*> points; // Array with menu points | |
unsigned int pointer; // Graphical pointer of current menu point | |
public: | |
MenuItem(); | |
MenuItem(std::string); | |
void action(); | |
void setWelcomeMessage(std::string); | |
MenuItem* addItem(std::string); // Add menu item in end of list | |
MenuFunction* addAction(std::string, void(*)()); // Add menu function in end of list | |
void addItem(MenuItem*); // Add menu item in end of list | |
void addAction(MenuFunction*); // Add menu function in end of list | |
MenuItem* insertItem(unsigned int, std::string); // Insert menu item in position | |
MenuFunction* insertAction(unsigned int, std::string, void(*)()); // Insert menu function in position | |
void insertItem(unsigned int, MenuItem*); // Insert menu item in position | |
void insertAction(unsigned int, MenuFunction*); // Insert menu action in position | |
MenuPoint* deletePoint(unsigned int); // Delete any point from position | |
MenuPoint* get(unsigned int); // Get menu element | |
}; | |
class MenuFunction: public MenuPoint | |
{ | |
private: | |
void (*func)(void); | |
MenuPoint *next_point; | |
public: | |
MenuFunction(); | |
MenuFunction(std::string, void(*)()); | |
void action(); | |
void setFunction(void(*)()); | |
void setNextItem(MenuItem*); // Set item that will call after current MenuFunction | |
void setNextAction(MenuFunction*); // Set action that will call after current MenuFunction | |
MenuItem* setNextItem(std::string); // Set item that will call after current MenuFunction | |
MenuFunction* setNextAction(std::string, void(*)()); // Set action that will call after current MenuFunction | |
}; | |
// Class methods | |
// MenuPoint methods | |
MenuPoint::MenuPoint() | |
{ | |
this->parent=0; | |
} | |
void MenuPoint::setParent(MenuPoint* parent) | |
{ | |
this->parent=parent; | |
} | |
void MenuPoint::setName(std::string name) | |
{ | |
this->name=name; | |
} | |
std::string MenuPoint::getName() | |
{ | |
return this->name; | |
} | |
MenuPoint* MenuPoint::getParent() | |
{ | |
return this->parent; | |
} | |
// MenuItem method | |
MenuItem::MenuItem() | |
{ | |
this->pointer=0; | |
this->welcome_message=""; | |
} | |
MenuItem::MenuItem(std::string name) | |
{ | |
this->pointer=0; | |
this->welcome_message=""; | |
this->name=name; | |
} | |
void MenuItem::action() | |
{ | |
// Print cycle | |
while (true) | |
{ | |
system("clear"); // Clear screen (only linux) | |
// Print menu | |
std::cout<<this->welcome_message<<std::endl; | |
unsigned int size=this->points.size(); | |
for (unsigned short i=0; i<size; i++) | |
{ | |
if (this->pointer==i) | |
std::cout<<"* "; | |
else | |
std::cout<<" "; | |
std::cout<<i+1<<". "; | |
std::cout<<this->points[i]->getName()<<std::endl; | |
} | |
if (this->pointer==this->points.size()) | |
std::cout<<"* "; | |
else | |
std::cout<<" "; | |
std::cout<<this->points.size()+1; | |
if (this->parent) | |
std::cout<<". Back"; | |
else | |
std::cout<<". Exit"; | |
std::cout<<std::endl; | |
switch (getch()) | |
{ | |
case 10: // Enter | |
if (this->pointer==this->points.size()) | |
return; | |
this->points[this->pointer]->action(); | |
break; | |
case 65: // Up | |
if (!this->pointer) | |
this->pointer=this->points.size(); | |
else | |
this->pointer--; | |
break; | |
case 66: // Down | |
if (this->pointer==this->points.size()) | |
this->pointer=0; | |
else | |
this->pointer++; | |
break; | |
} | |
} | |
} | |
void MenuItem::setWelcomeMessage(std::string welcome_message) | |
{ | |
this->welcome_message=welcome_message; | |
} | |
MenuItem* MenuItem::addItem(std::string name) | |
{ | |
MenuItem *item=new MenuItem(name); | |
item->setParent(this); | |
this->points.push_back(item); | |
return item; | |
} | |
MenuFunction* MenuItem::addAction(std::string name, void(*func)(void)) | |
{ | |
MenuFunction *mfunc=new MenuFunction(); | |
mfunc->setName(name); | |
mfunc->setFunction(func); | |
this->points.push_back(mfunc); | |
return mfunc; | |
} | |
void MenuItem::addItem(MenuItem *item) | |
{ | |
this->points.push_back(item); | |
} | |
void MenuItem::addAction(MenuFunction *mfunc) | |
{ | |
this->points.push_back(mfunc); | |
} | |
MenuItem* MenuItem::insertItem(unsigned int index, std::string name) | |
{ | |
if (index>this->points.size()) | |
return 0; | |
MenuItem *item=new MenuItem(name); | |
this->points.insert(this->points.begin()+index, item); | |
return item; | |
} | |
MenuFunction* MenuItem::insertAction(unsigned int index, std::string name, void(*func)()) | |
{ | |
if (index>this->points.size()) | |
return 0; | |
MenuFunction *mfunc=new MenuFunction(name, func); | |
this->points.insert(this->points.begin()+index, mfunc); | |
return mfunc; | |
} | |
void MenuItem::insertItem(unsigned int index, MenuItem* item) | |
{ | |
if (index>this->points.size()) | |
return; | |
this->points.insert(this->points.begin()+index, item); | |
} | |
void MenuItem::insertAction(unsigned int index, MenuFunction* mfunc) | |
{ | |
if (index>this->points.size()) | |
return; | |
this->points.insert(this->points.begin()+index, mfunc); | |
} | |
MenuPoint* MenuItem::deletePoint(unsigned int index) | |
{ | |
MenuPoint *point=this->points[index]; | |
this->points.erase(this->points.begin()+index); | |
return point; | |
} | |
MenuPoint* MenuItem::get(unsigned int index) | |
{ | |
return this->points[index]; | |
} | |
// MenuFunction method | |
MenuFunction::MenuFunction() | |
{ | |
this->func=0; | |
this->next_point=0; | |
} | |
MenuFunction::MenuFunction(std::string name, void(*func)()) | |
{ | |
this->name=name; | |
this->func=func; | |
this->next_point=0; | |
} | |
void MenuFunction::action() | |
{ | |
this->func(); | |
if (this->next_point) | |
this->next_point->action(); | |
} | |
void MenuFunction::setFunction(void(*func)()) | |
{ | |
this->func=func; | |
} | |
void MenuFunction::setNextItem(MenuItem *item) | |
{ | |
this->next_point=item; | |
} | |
void MenuFunction::setNextAction(MenuFunction *mfunc) | |
{ | |
this->next_point=mfunc; | |
} | |
MenuItem* MenuFunction::setNextItem(std::string name) | |
{ | |
MenuItem *item=new MenuItem(name); | |
this->next_point=item; | |
return item; | |
} | |
MenuFunction* MenuFunction::setNextAction(std::string name, void(*func)()) | |
{ | |
MenuFunction *mfunc=new MenuFunction(name, func); | |
this->next_point=mfunc; | |
return mfunc; | |
} | |
// Help functions | |
char charToDigit(char c) // Function for convert char to digit | |
{ | |
if (c>47 && c<58) | |
return c-48; | |
else if (c>64 && c<91) | |
return c-54; | |
else | |
return c-86; | |
} | |
void printBytes(char* array, unsigned char size) // Function for print bytes array in binary view | |
{ | |
for (unsigned short i=size; i>0; i--) | |
for (unsigned char j=8; j>0; j--) | |
{ | |
if (array[i-1] & ((char)1<<(j-1))) | |
std::cout<<1; | |
else | |
std::cout<<0; | |
} | |
} | |
unsigned int symbolPosition(std::string string, char c) // Function for check char in string | |
{ | |
unsigned int pos=1; | |
for (std::string::iterator it=string.begin(); it!=string.end(); it++, pos++) | |
if (*it==c) | |
return pos; | |
return 0; | |
} | |
// For integer | |
template <typename T> | |
void doItInteger(unsigned int scale, std::string data) | |
{ | |
T k=1; | |
T result=0; | |
bool sign=(data[0]=='-'); | |
for (unsigned short i=data.size(); i>1*sign; i--, k*=scale) | |
result+=charToDigit(data[i-1])*k*(sign?-1:1); | |
std::cout<<"In type: "<<result<<"\n"; | |
char *bytes=new char[sizeof(T)]; | |
memcpy(bytes, &result, sizeof(T)); | |
std::cout<<"Bytes: "; | |
printBytes(bytes, sizeof(T)); | |
std::cout<<"\n"; | |
getch(); | |
} | |
// For float | |
template <typename T> | |
void doItFloat(unsigned int scale, std::string data) | |
{ | |
T k=0.1; | |
T result=0; | |
bool sign=(data[0]=='-'); | |
unsigned short pp=symbolPosition(data, '.'); | |
if (!pp) | |
pp=data.size()+1; | |
for (unsigned short i=pp; i<data.size(); i++, k/=scale) | |
result+=charToDigit(data[i])*k*(sign?-1:1); | |
k=1; | |
for (unsigned short i=pp-1; i>1*sign; i--, k*=scale) | |
result+=charToDigit(data[i-1])*k*(sign?-1:1); | |
std::cout<<"In type: "<<result<<"\n"; | |
char *bytes=new char[sizeof(T)]; | |
memcpy(bytes, &result, sizeof(T)); | |
std::cout<<"Bytes: "; | |
printBytes(bytes, sizeof(T)); | |
std::cout<<"\n"; | |
getch(); | |
} | |
/* | |
* Main menu | |
* Choose type: | |
* 1. Bool = 0 | |
* 2. Char = 1 | |
* 3. Unsigned char = 2 | |
* 4. Short int = 3 | |
* 5. Unsigned short int = 4 | |
* 6. Int = 5 | |
* 7. Unsigned int = 6 | |
* 8. Long int = 7 | |
* 9. Unsigned long int = 8 | |
* 10. Float = 9 | |
* 12. Double = 10 | |
*/ | |
// Global variables | |
unsigned int scale; | |
std::string symbols; | |
std::string data; | |
unsigned char type; | |
// Main function | |
int main(int argc, char* argv[]) | |
{ | |
MenuItem types; | |
MenuFunction what_a_scale("scale", []() | |
{ | |
symbols.clear(); | |
// Menu for enter scale | |
while (true) | |
{ | |
system("clear"); | |
scale=0; | |
std::cout<<"What number system do you want to use?\nPlease, enter your response (number system may be from 2 to 36): "; | |
if (!(std::cin>>scale)) | |
{ | |
std::cin.clear(); | |
while (std::cin.get()!='\n'); | |
continue; | |
} | |
if (scale>1 && scale<37) | |
{ | |
// Add digits | |
for (unsigned char i=0; i<(scale>10?10:scale); i++) | |
symbols.push_back(48+i); | |
// Letters | |
for (unsigned char i=10; i<scale; i++) | |
{ | |
symbols.push_back(55+i); | |
symbols.push_back(87+i); | |
} | |
break; | |
} | |
} | |
// Input data | |
while (true) | |
{ | |
system("clear"); | |
std::cout<<"Please, enter data: "; | |
std::cin>>data; | |
// Check input data | |
bool p=false; // Point | |
bool pass=true; | |
for (std::string::iterator it=data.begin(); it!=data.end(); it++) | |
if (*it=='-') | |
{ | |
if (it!=data.begin() || type==0 || type==2 || type==4 || type==6 || type==8) | |
{ | |
pass=false; | |
break; | |
} | |
} | |
else if (*it=='.') | |
{ | |
if (it==data.begin() || it==data.end() || *(it-1)=='-' || type<9 || p) | |
{ | |
pass=false; | |
break; | |
} | |
else | |
p=true; | |
} | |
else if (!symbolPosition(symbols, *it)) | |
{ | |
pass=false; | |
break; | |
} | |
if (pass) | |
break; | |
std::cout<<"\nThis data cannot be converted\n"; | |
getch(); | |
getch(); | |
return; | |
} | |
system("clear"); | |
switch (type) | |
{ | |
case 0: | |
doItInteger<bool>(scale, data); | |
break; | |
case 1: | |
doItInteger<char>(scale, data); | |
break; | |
case 2: | |
doItInteger<unsigned char>(scale, data); | |
break; | |
case 3: | |
doItInteger<short int>(scale, data); | |
break; | |
case 4: | |
doItInteger<unsigned short int>(scale, data); | |
break; | |
case 5: | |
doItInteger<int>(scale, data); | |
break; | |
case 6: | |
doItInteger<unsigned int>(scale, data); | |
break; | |
case 7: | |
doItInteger<long int>(scale, data); | |
break; | |
case 8: | |
doItInteger<unsigned long int>(scale, data); | |
break; | |
case 9: | |
doItFloat<float>(scale, data); | |
break; | |
case 10: | |
doItFloat<double>(scale, data); | |
break; | |
} | |
getch(); | |
}); | |
types.setWelcomeMessage("Choose prefer type:"); | |
types.addAction("Bool", [](){type=0;})->setNextAction(&what_a_scale); | |
types.addAction("Char", [](){type=1;})->setNextAction(&what_a_scale); | |
types.addAction("Unsigned char", [](){type=2;})->setNextAction(&what_a_scale); | |
types.addAction("Short int", [](){type=3;})->setNextAction(&what_a_scale); | |
types.addAction("Unsigned short int", [](){type=4;})->setNextAction(&what_a_scale); | |
types.addAction("Int", [](){type=5;})->setNextAction(&what_a_scale); | |
types.addAction("Unsigned int", [](){type=6;})->setNextAction(&what_a_scale); | |
types.addAction("Long int", [](){type=7;})->setNextAction(&what_a_scale); | |
types.addAction("Unsigned long int", [](){type=8;})->setNextAction(&what_a_scale); | |
types.addAction("Float", [](){type=9;})->setNextAction(&what_a_scale); | |
types.addAction("Double", [](){type=10;})->setNextAction(&what_a_scale); | |
types.action(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment