jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
5.0KB

  1. #include <fstream>
  2. #include "JackLoader.h"
  3. #include "JackLockedEngine.h"
  4. namespace Jack
  5. {
  6. JackLoader::JackLoader(JackServer* const server) :
  7. fServer(server)
  8. {
  9. }
  10. int JackLoader::Load(const std::string file)
  11. {
  12. std::ifstream infile(file);
  13. if (!infile.is_open()) {
  14. jack_error("JACK configuration file %s does not exist or cannot be opened for reading.", file.c_str());
  15. return -1;
  16. }
  17. std::string line;
  18. int linenr = -1;
  19. while (std::getline(infile, line))
  20. {
  21. linenr++;
  22. std::istringstream iss(line);
  23. std::string command;
  24. if ( !(iss >> command) ) {
  25. /* ignoring empty line or line only filled with spaces */
  26. continue;
  27. }
  28. /* convert command to lower case to accept any case of the letters in the command */
  29. std::transform(command.begin(), command.end(), command.begin(), ::tolower);
  30. if ( (command.compare("c") == 0) || (command.compare("connect") == 0) ) {
  31. ConnectPorts(iss, linenr);
  32. } else if ( (command.compare("l") == 0) || (command.compare("load") == 0) ) {
  33. LoadClient(iss, linenr);
  34. } else if (command.front() == '#') {
  35. /* ignoring commented lines.
  36. * The # can be followed by non spaces.
  37. * Therefore only compare the first letter of the command.
  38. */
  39. } else {
  40. jack_error("JACK configuration file %s line %u contains unkown command '%s'. Ignoring the line!", file.c_str(), linenr, line.c_str());
  41. }
  42. }
  43. return 0;
  44. }
  45. void JackLoader::LoadClient(std::istringstream& iss, const int linenr)
  46. {
  47. std::string client_name;
  48. if ( !(iss >> client_name) ) {
  49. jack_error("Cannot read client name from configuration file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  50. return;
  51. }
  52. std::string lib_name;
  53. if ( !(iss >> lib_name) ) {
  54. jack_error("Cannot read client library name from configuration file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  55. return;
  56. }
  57. /* get the rest of the line */
  58. std::string parameters;
  59. if ( std::getline(iss, parameters) ) {
  60. /* remove the leading spaces */
  61. const std::size_t start = parameters.find_first_not_of(" \t");
  62. if (start == std::string::npos) {
  63. /* Parameters containing only spaces.
  64. * Use empty parameter string.
  65. */
  66. parameters = "";
  67. } else {
  68. parameters = parameters.substr(start);
  69. }
  70. }
  71. /* jackctl_server_load_internal() can not be used
  72. * because it calls jack_internal_initialize()
  73. * instead of jack_initialize()
  74. */
  75. int status = 0;
  76. int refnum = 0;
  77. if (fServer->InternalClientLoad1(client_name.c_str(), lib_name.c_str(), parameters.c_str(), (JackLoadName|JackUseExactName|JackLoadInit), &refnum, -1, &status) < 0) {
  78. /* Due to the JackUseExactName option JackNameNotUnique will always handled as a failure.
  79. * See JackEngine::ClientCheck().
  80. */
  81. if (status & JackNameNotUnique) {
  82. jack_error("Internal client name `%s' not unique", client_name.c_str());
  83. }
  84. /* An error message for JackVersionError will already
  85. * be printed by JackInternalClient::Open().
  86. * Therefore no need to handle it here.
  87. */
  88. jack_error("Cannot load client %s from configuration file line %u. Ignoring the line!", client_name.c_str(), linenr);
  89. return;
  90. }
  91. /* status has not to be checked for JackFailure
  92. * because JackServer::InternalClientLoad1() will return a value < 0
  93. * and this is handled by the previouse if-clause.
  94. */
  95. jack_info("Internal client %s successfully loaded", client_name.c_str());
  96. }
  97. void JackLoader::ConnectPorts(std::istringstream& iss, const int linenr)
  98. {
  99. std::string src_port;
  100. if ( !(iss >> src_port) ) {
  101. jack_error("Cannot read first port from configuration file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  102. return;
  103. }
  104. std::string dst_port;
  105. if ( !(iss >> dst_port) ) {
  106. jack_error("Cannot read second port from configuration file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  107. return;
  108. }
  109. /* use the client reference of the source port */
  110. const jack_port_id_t src_port_index = fServer->GetGraphManager()->GetPort(src_port.c_str());
  111. if (src_port_index >= NO_PORT) {
  112. jack_error("Source port %s does not exist! Ignoring configuration file line %u '%s'.", src_port.c_str(), linenr, iss.str().c_str());
  113. return;
  114. }
  115. const int src_refnum = fServer->GetGraphManager()->GetOutputRefNum(src_port_index);
  116. if (fServer->GetEngine()->PortConnect(src_refnum, src_port.c_str(), dst_port.c_str()) < 0) {
  117. jack_error("Cannot connect ports of configuration file line %u '%s'.Possibly the destination port does not exist. Ignoring the line!", linenr, iss.str().c_str());
  118. return;
  119. }
  120. jack_info("Ports connected: %s -> %s", src_port.c_str(), dst_port.c_str());
  121. }
  122. }