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