mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	media-session: store config data as json objects
So that we can use the json string escaping functions for keys and use multiline config files.
This commit is contained in:
		
							parent
							
								
									19dc150643
								
							
						
					
					
						commit
						e995d3a832
					
				
					 1 changed files with 45 additions and 30 deletions
				
			
		| 
						 | 
					@ -35,6 +35,7 @@
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <signal.h>
 | 
					#include <signal.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/mman.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#if HAVE_PWD_H
 | 
					#if HAVE_PWD_H
 | 
				
			||||||
#include <pwd.h>
 | 
					#include <pwd.h>
 | 
				
			||||||
| 
						 | 
					@ -43,6 +44,7 @@
 | 
				
			||||||
#include <spa/node/node.h>
 | 
					#include <spa/node/node.h>
 | 
				
			||||||
#include <spa/utils/hook.h>
 | 
					#include <spa/utils/hook.h>
 | 
				
			||||||
#include <spa/utils/result.h>
 | 
					#include <spa/utils/result.h>
 | 
				
			||||||
 | 
					#include <spa/utils/json.h>
 | 
				
			||||||
#include <spa/param/audio/format-utils.h>
 | 
					#include <spa/param/audio/format-utils.h>
 | 
				
			||||||
#include <spa/param/props.h>
 | 
					#include <spa/param/props.h>
 | 
				
			||||||
#include <spa/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
| 
						 | 
					@ -1833,8 +1835,9 @@ int sm_media_session_load_state(struct sm_media_session *sess,
 | 
				
			||||||
		const char *name, const char *prefix, struct pw_properties *props)
 | 
							const char *name, const char *prefix, struct pw_properties *props)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int sfd, fd, count = 0;
 | 
						int sfd, fd, count = 0;
 | 
				
			||||||
	FILE *f;
 | 
						struct stat sbuf;
 | 
				
			||||||
	char line[1024];
 | 
						char *data, key[1024], *val;
 | 
				
			||||||
 | 
						struct spa_json it[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info(NAME" %p: loading state '%s'", sess, name);
 | 
						pw_log_info(NAME" %p: loading state '%s'", sess, name);
 | 
				
			||||||
	if ((sfd = state_dir(sess)) < 0)
 | 
						if ((sfd = state_dir(sess)) < 0)
 | 
				
			||||||
| 
						 | 
					@ -1844,27 +1847,38 @@ int sm_media_session_load_state(struct sm_media_session *sess,
 | 
				
			||||||
		pw_log_debug("can't open file %s: %m", name);
 | 
							pw_log_debug("can't open file %s: %m", name);
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	f = fdopen(fd, "r");
 | 
						if (fstat(fd, &sbuf) < 0) {
 | 
				
			||||||
	while (fgets(line, sizeof(line)-1, f)) {
 | 
							pw_log_debug("can't stat file %s: %m", name);
 | 
				
			||||||
		char *val, *key, *k, *p;
 | 
							return -errno;
 | 
				
			||||||
		val = strrchr(line, '\n');
 | 
						}
 | 
				
			||||||
		if (val)
 | 
						if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
 | 
				
			||||||
			*val = '\0';
 | 
							pw_log_debug("can't mmap file %s: %m", name);
 | 
				
			||||||
 | 
							return -errno;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						spa_json_init(&it[0], data, strlen(data));
 | 
				
			||||||
 | 
						if (spa_json_enter_object(&it[0], &it[1]) < 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		key = k = p = line;
 | 
						while (spa_json_get_string(&it[1], key, sizeof(key)-1)) {
 | 
				
			||||||
		while (*p) {
 | 
							int len;
 | 
				
			||||||
			if (*p == ' ')
 | 
							const char *value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((len = spa_json_next(&it[1], &value)) <= 0)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
			if (*p == '\\')
 | 
					
 | 
				
			||||||
				p++;
 | 
							if (spa_json_is_container(value, len))
 | 
				
			||||||
			*k++ = *p++;
 | 
								len = spa_json_container_len(&it[1], value, len);
 | 
				
			||||||
		}
 | 
					
 | 
				
			||||||
		*k = '\0';
 | 
							if ((val = strndup(value, len)) == NULL)
 | 
				
			||||||
		val = ++p;
 | 
								break;
 | 
				
			||||||
		if (prefix == NULL || strstr(key, prefix) == key)
 | 
					
 | 
				
			||||||
 | 
							if (spa_json_is_string(value, len))
 | 
				
			||||||
 | 
								spa_json_parse_string(value, len, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		count += pw_properties_set(props, key, val);
 | 
							count += pw_properties_set(props, key, val);
 | 
				
			||||||
 | 
							free(val);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fclose(f);
 | 
						munmap(data, sbuf.st_size);
 | 
				
			||||||
	return count;
 | 
						return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1888,17 +1902,18 @@ int sm_media_session_save_state(struct sm_media_session *sess,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = fdopen(fd, "w");
 | 
						f = fdopen(fd, "w");
 | 
				
			||||||
 | 
						fprintf(f, "{ \n");
 | 
				
			||||||
	spa_dict_for_each(it, &props->dict) {
 | 
						spa_dict_for_each(it, &props->dict) {
 | 
				
			||||||
		const char *p = it->key;
 | 
							char key[1024];
 | 
				
			||||||
		if (prefix != NULL && strstr(p, prefix) != p)
 | 
							if (prefix != NULL && strstr(it->key, prefix) != it->key)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		while (*p) {
 | 
					
 | 
				
			||||||
			if (*p == ' ' || *p == '\\')
 | 
							if (spa_json_encode_string(key, sizeof(key)-1, it->key) >= (int)sizeof(key)-1)
 | 
				
			||||||
				fputc('\\', f);
 | 
								continue;
 | 
				
			||||||
			fprintf(f, "%c", *p++);
 | 
					
 | 
				
			||||||
		}
 | 
							fprintf(f, " %s: %s\n", key, it->value);
 | 
				
			||||||
		fprintf(f, " %s\n", it->value);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						fprintf(f, "}\n");
 | 
				
			||||||
	fclose(f);
 | 
						fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (renameat(sfd, tmp_name, sfd, name) < 0) {
 | 
						if (renameat(sfd, tmp_name, sfd, name) < 0) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue