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.

177 lines
6.0KB

  1. /*
  2. Copyright (C) 2017 Timo Wischer
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include <fstream>
  16. #include "JackInternalSessionLoader.h"
  17. #include "JackLockedEngine.h"
  18. namespace Jack
  19. {
  20. JackInternalSessionLoader::JackInternalSessionLoader(JackServer* const server) :
  21. fServer(server)
  22. {
  23. }
  24. int JackInternalSessionLoader::Load(const char* file)
  25. {
  26. std::ifstream infile(file);
  27. if (!infile.is_open()) {
  28. jack_error("JACK internal session file %s does not exist or cannot be opened for reading.", file);
  29. return -1;
  30. }
  31. std::string line;
  32. int linenr = -1;
  33. while (std::getline(infile, line))
  34. {
  35. linenr++;
  36. std::istringstream iss(line);
  37. std::string command;
  38. if ( !(iss >> command) ) {
  39. /* ignoring empty line or line only filled with spaces */
  40. continue;
  41. }
  42. /* convert command to lower case to accept any case of the letters in the command */
  43. std::transform(command.begin(), command.end(), command.begin(), ::tolower);
  44. if ( (command.compare("c") == 0) || (command.compare("con") == 0) ) {
  45. ConnectPorts(iss, linenr);
  46. } else if ( (command.compare("l") == 0) || (command.compare("load") == 0) ) {
  47. LoadClient(iss, linenr);
  48. #if 0
  49. /* NOTE: c++11 only */
  50. } else if (command.front() == '#') {
  51. #else
  52. } else if (command[0] == '#') {
  53. #endif
  54. /* ignoring commented lines.
  55. * The # can be followed by non spaces.
  56. * Therefore only compare the first letter of the command.
  57. */
  58. } else {
  59. jack_error("JACK internal session file %s line %u contains unknown command '%s'. Ignoring the line!", file, linenr, line.c_str());
  60. }
  61. }
  62. return 0;
  63. }
  64. void JackInternalSessionLoader::LoadClient(std::istringstream& iss, const int linenr)
  65. {
  66. std::string client_name;
  67. if ( !(iss >> client_name) ) {
  68. jack_error("Cannot read client name from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  69. return;
  70. }
  71. std::string lib_name;
  72. if ( !(iss >> lib_name) ) {
  73. jack_error("Cannot read client library name from internal session file line %u '%s'. Ignoring the line!", linenr, iss.str().c_str());
  74. return;
  75. }
  76. /* get the rest of the line */
  77. std::string parameters;
  78. if ( std::getline(iss, parameters) ) {
  79. /* remove the leading spaces */
  80. const std::size_t start = parameters.find_first_not_of(" \t");
  81. if (start == std::string::npos) {
  82. /* Parameters containing only spaces.
  83. * Use empty parameter string.
  84. */
  85. parameters = "";
  86. } else {
  87. parameters = parameters.substr(start);
  88. }
  89. }
  90. /* jackctl_server_load_internal() can not be used
  91. * because it calls jack_internal_initialize()
  92. * instead of jack_initialize()
  93. */
  94. int status = 0;
  95. int refnum = 0;
  96. if (fServer->InternalClientLoad1(client_name.c_str(), lib_name.c_str(), parameters.c_str(), (JackLoadName|JackUseExactName|JackLoadInit), &refnum, -1, &status) < 0) {
  97. /* Due to the JackUseExactName option JackNameNotUnique will always handled as a failure.
  98. * See JackEngine::ClientCheck().
  99. */
  100. if (status & JackNameNotUnique) {
  101. jack_error("Internal client name `%s' not unique", client_name.c_str());
  102. }
  103. /* An error message for JackVersionError will already
  104. * be printed by JackInternalClient::Open().
  105. * Therefore no need to handle it here.
  106. */
  107. jack_error("Cannot load client %s from internal session file line %u. Ignoring the line!", client_name.c_str(), linenr);
  108. return;
  109. }
  110. /* status has not to be checked for JackFailure
  111. * because JackServer::InternalClientLoad1() will return a value < 0
  112. * and this is handled by the previous if-clause.
  113. */
  114. jack_info("Internal client %s successfully loaded", client_name.c_str());
  115. }
  116. void JackInternalSessionLoader::ConnectPorts(std::istringstream& iss, const int linenr)
  117. {
  118. std::string src_port;
  119. if ( !(iss >> src_port) ) {
  120. jack_error("Cannot read first port from internal session file line %u '%s'. Ignoring the line!",
  121. linenr, iss.str().c_str());
  122. return;
  123. }
  124. std::string dst_port;
  125. if ( !(iss >> dst_port) ) {
  126. jack_error("Cannot read second port from internal session file line %u '%s'. Ignoring the line!",
  127. linenr, iss.str().c_str());
  128. return;
  129. }
  130. /* use the client reference of the source port */
  131. const jack_port_id_t src_port_index = fServer->GetGraphManager()->GetPort(src_port.c_str());
  132. if (src_port_index >= NO_PORT) {
  133. jack_error("Source port %s does not exist! Ignoring internal session file line %u '%s'.",
  134. src_port.c_str(), linenr, iss.str().c_str());
  135. return;
  136. }
  137. const int src_refnum = fServer->GetGraphManager()->GetOutputRefNum(src_port_index);
  138. if (fServer->GetEngine()->PortConnect(src_refnum, src_port.c_str(), dst_port.c_str()) < 0) {
  139. jack_error("Cannot connect ports of internal session file line %u '%s'.\n"
  140. "Possibly the destination port does not exist. Ignoring the line!",
  141. linenr, iss.str().c_str());
  142. return;
  143. }
  144. jack_info("Ports connected: %s -> %s", src_port.c_str(), dst_port.c_str());
  145. }
  146. }