Save clients, ports and dicts

This commit is contained in:
Nedko Arnaudov 2009-09-21 00:17:41 +03:00
parent 20a9f12362
commit 9e9a127a15
8 changed files with 407 additions and 23 deletions

View File

@ -191,4 +191,9 @@ bool ladish_dict_iterate(ladish_dict_handle dict_handle, void * context, bool (*
return true;
}
bool ladish_dict_is_empty(ladish_dict_handle dict_handle)
{
return list_empty(&dict_ptr->entries);
}
#undef dict_ptr

View File

@ -38,5 +38,6 @@ const char * ladish_dict_get(ladish_dict_handle dict_handle, const char * key);
void ladish_dict_drop(ladish_dict_handle dict_handle, const char * key);
void ladish_dict_clear(ladish_dict_handle dict_handle);
bool ladish_dict_iterate(ladish_dict_handle dict_handle, void * context, bool (* callback)(void * context, const char * key, const char * value));
bool ladish_dict_is_empty(ladish_dict_handle dict_handle);
#endif /* #ifndef DICT_H__12A321F8_A361_482B_9255_66CCD4D3C31F__INCLUDED */

View File

@ -805,7 +805,7 @@ ladish_graph_iterate_nodes(
ladish_graph_handle graph_handle,
void * callback_context,
bool
(* client_callback)(
(* client_begin_callback)(
void * context,
ladish_client_handle client_handle,
const char * client_name,
@ -819,7 +819,13 @@ ladish_graph_iterate_nodes(
ladish_port_handle port_handle,
const char * port_name,
uint32_t port_type,
uint32_t port_flags))
uint32_t port_flags),
bool
(* client_end_callback)(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr))
{
struct list_head * client_node_ptr;
struct ladish_graph_client * client_ptr;
@ -830,7 +836,7 @@ ladish_graph_iterate_nodes(
list_for_each(client_node_ptr, &graph_ptr->clients)
{
client_ptr = list_entry(client_node_ptr, struct ladish_graph_client, siblings);
if (!client_callback(callback_context, client_ptr->client, client_ptr->name, &client_context))
if (!client_begin_callback(callback_context, client_ptr->client, client_ptr->name, &client_context))
{
return false;
}
@ -852,6 +858,11 @@ ladish_graph_iterate_nodes(
return false;
}
}
if (!client_end_callback(callback_context, client_ptr->client, client_ptr->name, &client_context))
{
return false;
}
}
return true;

View File

@ -72,7 +72,7 @@ ladish_graph_iterate_nodes(
ladish_graph_handle graph_handle,
void * callback_context,
bool
(* client_callback)(
(* client_begin_callback)(
void * context,
ladish_client_handle client_handle,
const char * client_name,
@ -86,7 +86,13 @@ ladish_graph_iterate_nodes(
ladish_port_handle port_handle,
const char * port_name,
uint32_t port_type,
uint32_t port_flags));
uint32_t port_flags),
bool
(* client_end_callback)(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr));
extern const struct dbus_interface_descriptor g_interface_patchbay;

View File

@ -105,6 +105,11 @@ ladish_dict_handle ladish_port_get_dict(ladish_port_handle port_handle)
return port_ptr->dict;
}
void ladish_port_get_uuid(ladish_port_handle port_handle, uuid_t uuid)
{
uuid_copy(uuid, port_ptr->uuid);
}
void ladish_port_set_jack_id(ladish_port_handle port_handle, uint64_t jack_id)
{
port_ptr->jack_id = jack_id;

View File

@ -34,7 +34,7 @@ typedef struct ladish_port_tag { int unused; } * ladish_port_handle;
bool ladish_port_create(uuid_t uuid_ptr, ladish_port_handle * port_handle_ptr);
void ladish_port_destroy(ladish_port_handle port_handle);
ladish_dict_handle ladish_port_get_dict(ladish_port_handle port_handle);
void ladish_port_get_uuid(ladish_port_handle port_handle, uuid_t uuid);
void ladish_port_set_jack_id(ladish_port_handle port_handle, uint64_t jack_id);
uint64_t ladish_port_get_jack_id(ladish_port_handle port_handle);

View File

@ -36,11 +36,17 @@
#include "escape.h"
#include "studio_internal.h"
#define PARSE_CONTEXT_ROOT 0
#define PARSE_CONTEXT_STUDIO 1
#define PARSE_CONTEXT_JACK 2
#define PARSE_CONTEXT_CONF 3
#define PARSE_CONTEXT_PARAMETER 4
#define PARSE_CONTEXT_ROOT 0
#define PARSE_CONTEXT_STUDIO 1
#define PARSE_CONTEXT_JACK 2
#define PARSE_CONTEXT_CONF 3
#define PARSE_CONTEXT_PARAMETER 4
#define PARSE_CONTEXT_CLIENTS 5
#define PARSE_CONTEXT_CLIENT 6
#define PARSE_CONTEXT_PORTS 7
#define PARSE_CONTEXT_PORT 8
#define PARSE_CONTEXT_DICT 9
#define PARSE_CONTEXT_KEY 10
#define MAX_STACK_DEPTH 10
#define MAX_DATA_SIZE 1024
@ -137,6 +143,48 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
return;
}
if (strcmp(el, "clients") == 0)
{
//log_info("<clients>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CLIENTS;
return;
}
if (strcmp(el, "client") == 0)
{
//log_info("<client>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_CLIENT;
return;
}
if (strcmp(el, "ports") == 0)
{
//log_info("<ports>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_PORTS;
return;
}
if (strcmp(el, "port") == 0)
{
//log_info("<port>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_PORT;
return;
}
if (strcmp(el, "dict") == 0)
{
//log_info("<dict>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_DICT;
return;
}
if (strcmp(el, "key") == 0)
{
//log_info("<key>");
context_ptr->element[++context_ptr->depth] = PARSE_CONTEXT_KEY;
return;
}
lash_dbus_error(context_ptr->call_ptr, LASH_DBUS_ERROR_GENERIC, "unknown element \"%s\"", el);
context_ptr->error = XML_TRUE;
}

View File

@ -35,6 +35,13 @@
#include "escape.h"
#include "studio_internal.h"
struct save_context
{
int fd;
void * call_ptr;
const char * indent;
};
#define STUDIO_HEADER_TEXT BASE_NAME " Studio configuration.\n"
bool
@ -142,21 +149,168 @@ write_jack_parameter(
return true;
}
static
bool
save_jack_client(
write_dict_entry(
void * context,
const char * key,
const char * value);
bool
write_dict(
int fd,
const char * indent,
ladish_dict_handle dict,
void * call_ptr)
{
struct save_context context;
if (ladish_dict_is_empty(dict))
{
return true;
}
if (!write_string(fd, indent, call_ptr))
{
return false;
}
context.fd = fd;
context.call_ptr = call_ptr;
context.indent = indent;
if (!write_string(fd, "<dict>\n", call_ptr))
{
return false;
}
if (!ladish_dict_iterate(dict, &context, write_dict_entry))
{
return false;
}
if (!write_string(fd, indent, call_ptr))
{
return false;
}
if (!write_string(fd, "</dict>\n", call_ptr))
{
return false;
}
return true;
}
#define fd (((struct save_context *)context)->fd)
#define call_ptr (((struct save_context *)context)->call_ptr)
#define indent (((struct save_context *)context)->indent)
static
bool
write_dict_entry(
void * context,
const char * key,
const char * value)
{
if (!write_string(fd, indent, call_ptr))
{
return false;
}
if (!write_string(fd, " <key name=\"", call_ptr))
{
return false;
}
if (!write_string(fd, key, call_ptr))
{
return false;
}
if (!write_string(fd, "\">", call_ptr))
{
return false;
}
if (!write_string(fd, value, call_ptr))
{
return false;
}
if (!write_string(fd, "</key>\n", call_ptr))
{
return false;
}
return true;
}
bool
save_jack_client_begin(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
{
#if 0
uuid_t uuid;
char str[37];
ladish_client_get_uuid(client_handle, uuid);
uuid_unparse(uuid, str);
#endif
log_info("saving jack client '%s'", client_name);
log_info("saving jack client '%s' (%s)", client_name, str);
if (!write_string(fd, " <client name=\"", call_ptr))
{
return false;
}
if (!write_string(fd, client_name, call_ptr))
{
return false;
}
if (!write_string(fd, "\" guid=\"", call_ptr))
{
return false;
}
if (!write_string(fd, str, call_ptr))
{
return false;
}
if (!write_string(fd, "\">\n", call_ptr))
{
return false;
}
if (!write_string(fd, " <ports>\n", call_ptr))
{
return false;
}
return true;
}
bool
save_jack_client_end(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr)
{
if (!write_string(fd, " </ports>\n", call_ptr))
{
return false;
}
if (!write_string(fd, " </client>\n", call_ptr))
{
return false;
}
return true;
}
@ -171,25 +325,112 @@ save_jack_port(
uint32_t port_type,
uint32_t port_flags)
{
log_info("saving jack port '%s':'%s'", client_name, port_name);
uuid_t uuid;
char str[37];
ladish_port_get_uuid(port_handle, uuid);
uuid_unparse(uuid, str);
log_info("saving jack port '%s':'%s' (%s)", client_name, port_name, str);
if (!write_string(fd, " <port name=\"", call_ptr))
{
return false;
}
if (!write_string(fd, port_name, call_ptr))
{
return false;
}
if (!write_string(fd, "\" guid=\"", call_ptr))
{
return false;
}
if (!write_string(fd, str, call_ptr))
{
return false;
}
if (!write_string(fd, "\" />\n", call_ptr))
{
return false;
}
return true;
}
bool
save_studio_client(
save_studio_client_begin(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void ** client_iteration_context_ptr_ptr)
{
#if 0
uuid_t uuid;
char str[37];
ladish_client_get_uuid(client_handle, uuid);
uuid_unparse(uuid, str);
#endif
log_info("saving studio client '%s'", client_name);
log_info("saving studio client '%s' (%s)", client_name, str);
if (!write_string(fd, " <client name=\"", call_ptr))
{
return false;
}
if (!write_string(fd, client_name, call_ptr))
{
return false;
}
if (!write_string(fd, "\" guid=\"", call_ptr))
{
return false;
}
if (!write_string(fd, str, call_ptr))
{
return false;
}
if (!write_string(fd, "\">\n", call_ptr))
{
return false;
}
if (!write_string(fd, " <ports>\n", call_ptr))
{
return false;
}
return true;
}
bool
save_studio_client_end(
void * context,
ladish_client_handle client_handle,
const char * client_name,
void * client_iteration_context_ptr)
{
if (!write_string(fd, " </ports>\n", call_ptr))
{
return false;
}
if (!write_dict(fd, " ", ladish_client_get_dict(client_handle), call_ptr))
{
return false;
}
if (!write_string(fd, " </client>\n", call_ptr))
{
return false;
}
return true;
}
@ -204,10 +445,68 @@ save_studio_port(
uint32_t port_type,
uint32_t port_flags)
{
log_info("saving studio port '%s':'%s'", client_name, port_name);
uuid_t uuid;
char str[37];
ladish_dict_handle dict;
ladish_port_get_uuid(port_handle, uuid);
uuid_unparse(uuid, str);
log_info("saving studio port '%s':'%s' (%s)", client_name, port_name, str);
if (!write_string(fd, " <port name=\"", call_ptr))
{
return false;
}
if (!write_string(fd, port_name, call_ptr))
{
return false;
}
if (!write_string(fd, "\" guid=\"", call_ptr))
{
return false;
}
if (!write_string(fd, str, call_ptr))
{
return false;
}
dict = ladish_port_get_dict(port_handle);
if (ladish_dict_is_empty(dict))
{
if (!write_string(fd, "\" />\n", call_ptr))
{
return false;
}
}
else
{
if (!write_string(fd, "\">\n", call_ptr))
{
return false;
}
if (!write_dict(fd, " ", dict, call_ptr))
{
return false;
}
if (!write_string(fd, " </port>\n", call_ptr))
{
return false;
}
}
return true;
}
#undef indent
#undef fd
#undef call_ptr
bool studio_save(void * call_ptr)
{
struct list_head * node_ptr;
@ -220,6 +519,7 @@ bool studio_save(void * call_ptr)
char * bak_filename; /* filename of the backup file */
char * old_filename; /* filename where studio was persisted before save */
struct stat st;
struct save_context context;
time(&timestamp);
ctime_r(&timestamp, timestamp_str);
@ -357,7 +657,10 @@ bool studio_save(void * call_ptr)
goto close;
}
if (!ladish_graph_iterate_nodes(g_studio.jack_graph, call_ptr, save_jack_client, save_jack_port))
context.fd = fd;
context.call_ptr = call_ptr;
if (!ladish_graph_iterate_nodes(g_studio.jack_graph, &context, save_jack_client_begin, save_jack_port, save_jack_client_end))
{
log_error("ladish_graph_iterate_nodes() failed");
goto close;
@ -378,7 +681,7 @@ bool studio_save(void * call_ptr)
goto close;
}
if (!ladish_graph_iterate_nodes(g_studio.studio_graph, call_ptr, save_studio_client, save_studio_port))
if (!ladish_graph_iterate_nodes(g_studio.studio_graph, &context, save_studio_client_begin, save_studio_port, save_studio_client_end))
{
log_error("ladish_graph_iterate_nodes() failed");
goto close;
@ -389,6 +692,11 @@ bool studio_save(void * call_ptr)
goto close;
}
if (!write_dict(fd, " ", ladish_graph_get_dict(g_studio.studio_graph), call_ptr))
{
return false;
}
if (!write_string(fd, "</studio>\n", call_ptr))
{
goto close;