2 Copyright (C) 2017 Timo Wischer
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackInternalSessionLoader.h"
22 #include "JackLockedEngine.h"
28 JackInternalSessionLoader::JackInternalSessionLoader(JackServer
* const server
) :
33 int JackInternalSessionLoader::Load(const char* file
)
35 std::ifstream
infile(file
);
37 if (!infile
.is_open()) {
38 jack_error("JACK internal session file %s does not exist or cannot be opened for reading.", file
);
44 while (std::getline(infile
, line
))
48 std::istringstream
iss(line
);
51 if ( !(iss
>> command
) ) {
52 /* ignoring empty line or line only filled with spaces */
56 /* convert command to lower case to accept any case of the letters in the command */
57 std::transform(command
.begin(), command
.end(), command
.begin(), ::tolower
);
59 if ( (command
.compare("c") == 0) || (command
.compare("con") == 0) ) {
60 ConnectPorts(iss
, linenr
);
61 } else if ( (command
.compare("l") == 0) || (command
.compare("load") == 0) ) {
62 LoadClient(iss
, linenr
);
64 /* NOTE: c++11 only */
65 } else if (command
.front() == '#') {
67 } else if (command
[0] == '#') {
69 /* ignoring commented lines.
70 * The # can be followed by non spaces.
71 * Therefore only compare the first letter of the command.
74 jack_error("JACK internal session file %s line %u contains unknown command '%s'. Ignoring the line!", file
, linenr
, line
.c_str());
81 void JackInternalSessionLoader::LoadClient(std::istringstream
& iss
, const int linenr
)
83 std::string client_name
;
84 if ( !(iss
>> client_name
) ) {
85 jack_error("Cannot read client name from internal session file line %u '%s'. Ignoring the line!", linenr
, iss
.str().c_str());
90 if ( !(iss
>> lib_name
) ) {
91 jack_error("Cannot read client library name from internal session file line %u '%s'. Ignoring the line!", linenr
, iss
.str().c_str());
95 /* get the rest of the line */
96 std::string parameters
;
97 if ( std::getline(iss
, parameters
) ) {
98 /* remove the leading spaces */
99 const std::size_t start
= parameters
.find_first_not_of(" \t");
100 if (start
== std::string::npos
) {
101 /* Parameters containing only spaces.
102 * Use empty parameter string.
106 parameters
= parameters
.substr(start
);
111 /* jackctl_server_load_internal() can not be used
112 * because it calls jack_internal_initialize()
113 * instead of jack_initialize()
117 if (fServer
->InternalClientLoad1(client_name
.c_str(), lib_name
.c_str(), parameters
.c_str(), (JackLoadName
|JackUseExactName
|JackLoadInit
), &refnum
, -1, &status
) < 0) {
118 /* Due to the JackUseExactName option JackNameNotUnique will always handled as a failure.
119 * See JackEngine::ClientCheck().
121 if (status
& JackNameNotUnique
) {
122 jack_error("Internal client name `%s' not unique", client_name
.c_str());
124 /* An error message for JackVersionError will already
125 * be printed by JackInternalClient::Open().
126 * Therefore no need to handle it here.
129 jack_error("Cannot load client %s from internal session file line %u. Ignoring the line!", client_name
.c_str(), linenr
);
133 /* status has not to be checked for JackFailure
134 * because JackServer::InternalClientLoad1() will return a value < 0
135 * and this is handled by the previous if-clause.
138 jack_info("Internal client %s successfully loaded", client_name
.c_str());
141 void JackInternalSessionLoader::ConnectPorts(std::istringstream
& iss
, const int linenr
)
143 std::string src_port
;
144 if ( !(iss
>> src_port
) ) {
145 jack_error("Cannot read first port from internal session file line %u '%s'. Ignoring the line!",
146 linenr
, iss
.str().c_str());
150 std::string dst_port
;
151 if ( !(iss
>> dst_port
) ) {
152 jack_error("Cannot read second port from internal session file line %u '%s'. Ignoring the line!",
153 linenr
, iss
.str().c_str());
157 /* use the client reference of the source port */
158 const jack_port_id_t src_port_index
= fServer
->GetGraphManager()->GetPort(src_port
.c_str());
159 if (src_port_index
>= NO_PORT
) {
160 jack_error("Source port %s does not exist! Ignoring internal session file line %u '%s'.",
161 src_port
.c_str(), linenr
, iss
.str().c_str());
164 const int src_refnum
= fServer
->GetGraphManager()->GetOutputRefNum(src_port_index
);
166 if (fServer
->GetEngine()->PortConnect(src_refnum
, src_port
.c_str(), dst_port
.c_str()) < 0) {
167 jack_error("Cannot connect ports of internal session file line %u '%s'.\n"
168 "Possibly the destination port does not exist. Ignoring the line!",
169 linenr
, iss
.str().c_str());
173 jack_info("Ports connected: %s -> %s", src_port
.c_str(), dst_port
.c_str());