main.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "status_codes.h"
  2. #include <call_rpc_list.h>
  3. #include <input_list.h>
  4. #include <request_list.h>
  5. #include <response_list.h>
  6. #include <rpcdb.h>
  7. #include <cstring>
  8. #include <iostream>
  9. #include <stdexcept>
  10. #include <unordered_map>
  11. #define WRONG_PARAMS_ERROR "Wrong parameters."
  12. #define USAGE_FORMAT "usage: %s server_host input_file\n"
  13. #define INTERACTIVE_OPTION "-i"
  14. #define EXEC_ARG 0
  15. #define HOST_ARG 1
  16. #define FILENAME_ARG 2
  17. #define OPTION_ARG 2
  18. #define ARG_COUNT 3
  19. #define LOGIN_COMMAND "login"
  20. #define LOGOUT_COMMAND "logout"
  21. #define LOAD_COMMAND "load"
  22. #define STORE_COMMAND "store"
  23. #define ADD_COMMAND "add"
  24. #define DELETE_COMMAND "delete"
  25. #define UPDATE_COMMAND "update"
  26. #define READ_COMMAND "read"
  27. #define READ_ALL_COMMAND "read_all"
  28. #define GET_STAT_COMMAND "get_stat"
  29. #define GET_STAT_ALL_COMMAND "get_stat_all"
  30. #define UNRECOGNIZED_COMMAND "Unrecognized command."
  31. #define LINE_BREAK "----------------------------------------"
  32. using std::cerr;
  33. using std::cout;
  34. using std::endl;
  35. using std::strcmp;
  36. using std::bad_alloc;
  37. using std::domain_error;
  38. using std::invalid_argument;
  39. using std::logic_error;
  40. using std::out_of_range;
  41. using std::runtime_error;
  42. using std::unordered_map;
  43. void init_commands(unordered_map<string, command_type> *commands)
  44. {
  45. commands->insert({ LOGIN_COMMAND, LOGIN_CMD });
  46. commands->insert({ LOGOUT_COMMAND, LOGOUT_CMD });
  47. commands->insert({ LOAD_COMMAND, LOAD_CMD });
  48. commands->insert({ STORE_COMMAND, STORE_CMD });
  49. commands->insert({ ADD_COMMAND, ADD_CMD });
  50. commands->insert({ DELETE_COMMAND, DELETE_CMD });
  51. commands->insert({ UPDATE_COMMAND, UPDATE_CMD });
  52. commands->insert({ READ_COMMAND, READ_CMD });
  53. commands->insert({ READ_ALL_COMMAND, READ_ALL_CMD });
  54. commands->insert({ GET_STAT_COMMAND, GET_STAT_CMD });
  55. commands->insert({ GET_STAT_ALL_COMMAND, GET_STAT_ALL_CMD });
  56. }
  57. void destroy_commands(unordered_map<string, command_type> *commands)
  58. {
  59. delete commands;
  60. }
  61. void init_requests(unordered_map<command_type, create_request *> *requests)
  62. {
  63. requests->insert({ LOGIN_CMD, new login_req() });
  64. requests->insert({ LOGOUT_CMD, new logout_req() });
  65. requests->insert({ ADD_CMD, new add_req() });
  66. requests->insert({ UPDATE_CMD, new update_req() });
  67. requests->insert({ DELETE_CMD, new delete_req() });
  68. requests->insert({ READ_CMD, new read_req() });
  69. requests->insert({ GET_STAT_CMD, new get_stat_req() });
  70. requests->insert({ READ_ALL_CMD, new read_all_req() });
  71. requests->insert({ GET_STAT_ALL_CMD, new get_stat_all_req() });
  72. requests->insert({ LOAD_CMD, new load_req() });
  73. requests->insert({ STORE_CMD, new store_req() });
  74. }
  75. void destroy_requests(unordered_map<command_type, create_request *> *requests)
  76. {
  77. for (auto it = requests->begin(); it != requests->end(); it++)
  78. delete it->second;
  79. delete requests;
  80. }
  81. void init_responses(unordered_map<command_type, interpret_response *> *responses)
  82. {
  83. responses->insert({ LOGIN_CMD, new login_res() });
  84. responses->insert({ LOGOUT_CMD, new logout_res() });
  85. responses->insert({ LOAD_CMD, new load_res() });
  86. responses->insert({ STORE_CMD, new store_res() });
  87. responses->insert({ ADD_CMD, new add_res() });
  88. responses->insert({ DELETE_CMD, new delete_res() });
  89. responses->insert({ UPDATE_CMD, new update_res() });
  90. responses->insert({ READ_CMD, new read_res() });
  91. responses->insert({ READ_ALL_CMD, new read_all_res() });
  92. responses->insert({ GET_STAT_CMD, new get_stat_res() });
  93. responses->insert({ GET_STAT_ALL_CMD, new get_stat_all_res() });
  94. }
  95. void destroy_responses(
  96. unordered_map<command_type, interpret_response *> *responses)
  97. {
  98. for (auto it = responses->begin(); it != responses->end(); it++)
  99. delete it->second;
  100. delete responses;
  101. }
  102. int main(int argc, char *argv[])
  103. {
  104. call_rpc *rpc;
  105. input_controller *input;
  106. int code = EXIT_SUCCESS;
  107. unordered_map<string, command_type> *commands;
  108. unordered_map<command_type, create_request *> *requests;
  109. unordered_map<command_type, interpret_response *> *responses;
  110. try {
  111. if (argc < ARG_COUNT)
  112. throw invalid_argument(WRONG_PARAMS_ERROR);
  113. rpc = new call_rpc();
  114. rpc->init(argv[HOST_ARG]);
  115. if (strcmp(argv[OPTION_ARG], INTERACTIVE_OPTION) == 0)
  116. input = new stdin_input();
  117. else
  118. input = new file_input(argv[FILENAME_ARG]);
  119. commands = new unordered_map<string, command_type>();
  120. init_commands(commands);
  121. requests = new unordered_map<command_type, create_request *>();
  122. init_requests(requests);
  123. responses =
  124. new unordered_map<command_type, interpret_response *>();
  125. init_responses(responses);
  126. status_codes::init();
  127. } catch (invalid_argument &e) {
  128. cerr << e.what() << endl;
  129. fprintf(stderr, USAGE_FORMAT, argv[EXEC_ARG]);
  130. code = EINVAL;
  131. } catch (bad_alloc &e) {
  132. cerr << e.what() << endl;
  133. code = ENOMEM;
  134. } catch (runtime_error &e) {
  135. cerr << e.what() << endl;
  136. code = EPROTO;
  137. }
  138. if (code != EXIT_SUCCESS)
  139. return code;
  140. while (input->get_next_line()) {
  141. string token;
  142. command_type cmd;
  143. create_request *req;
  144. interpret_response *res;
  145. request gen_req;
  146. response *gen_res;
  147. try {
  148. token = input->get_command();
  149. cmd = commands->at(token);
  150. auto it_req = requests->find(cmd);
  151. req = it_req->second;
  152. auto it_res = responses->find(cmd);
  153. res = it_res->second;
  154. gen_req = req->generate(input->get_command_stream());
  155. gen_res = rpc->get_response(gen_req);
  156. code = res->interpret(gen_res);
  157. } catch (runtime_error &e) {
  158. cout << e.what() << endl;
  159. } catch (out_of_range &e) {
  160. cout << UNRECOGNIZED_COMMAND << endl;
  161. } catch (domain_error &e) {
  162. cerr << e.what() << endl;
  163. } catch (logic_error &e) {
  164. cerr << e.what() << endl;
  165. code = -1;
  166. break;
  167. }
  168. cout << LINE_BREAK << endl;
  169. }
  170. delete rpc;
  171. delete input;
  172. destroy_commands(commands);
  173. destroy_requests(requests);
  174. destroy_responses(responses);
  175. status_codes::destroy();
  176. return code;
  177. }