mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: move json parser to utils
Add unit test Add escape function
This commit is contained in:
		
							parent
							
								
									77791bd427
								
							
						
					
					
						commit
						62cdec8448
					
				
					 8 changed files with 211 additions and 5 deletions
				
			
		| 
						 | 
					@ -100,6 +100,7 @@ spa_utils_headers = [
 | 
				
			||||||
  'utils/defs.h',
 | 
					  'utils/defs.h',
 | 
				
			||||||
  'utils/dict.h',
 | 
					  'utils/dict.h',
 | 
				
			||||||
  'utils/hook.h',
 | 
					  'utils/hook.h',
 | 
				
			||||||
 | 
					  'utils/json.h',
 | 
				
			||||||
  'utils/keys.h',
 | 
					  'utils/keys.h',
 | 
				
			||||||
  'utils/list.h',
 | 
					  'utils/list.h',
 | 
				
			||||||
  'utils/names.h',
 | 
					  'utils/names.h',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +94,7 @@ static inline int spa_json_next(struct spa_json * iter, const char **value)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				--iter->depth;
 | 
									--iter->depth;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			case '-': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9':
 | 
								case '-': case '+': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9':
 | 
				
			||||||
				*value = iter->cur;
 | 
									*value = iter->cur;
 | 
				
			||||||
				iter->state = __BARE;
 | 
									iter->state = __BARE;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -271,6 +271,8 @@ static inline int spa_json_parse_string(const char *val, int len, char *result)
 | 
				
			||||||
				*result++ = '\b';
 | 
									*result++ = '\b';
 | 
				
			||||||
			else if (*p == 't')
 | 
								else if (*p == 't')
 | 
				
			||||||
				*result++ = '\t';
 | 
									*result++ = '\t';
 | 
				
			||||||
 | 
								else if (*p == 'f')
 | 
				
			||||||
 | 
									*result++ = '\f';
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				*result++ = *p;
 | 
									*result++ = *p;
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
| 
						 | 
					@ -289,6 +291,39 @@ static inline int spa_json_get_string(struct spa_json *iter, char *res, int maxl
 | 
				
			||||||
	return spa_json_parse_string(value, len, res);
 | 
						return spa_json_parse_string(value, len, res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int spa_json_encode_string(char *str, int size, const char *val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int len = 0;
 | 
				
			||||||
 | 
					#define __PUT(c) { if (len < size) *str++ = c; len++; }
 | 
				
			||||||
 | 
						__PUT('"');
 | 
				
			||||||
 | 
						while (*val) {
 | 
				
			||||||
 | 
							switch (*val) {
 | 
				
			||||||
 | 
							case '\n':
 | 
				
			||||||
 | 
								__PUT('\\'); __PUT('n');
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '\r':
 | 
				
			||||||
 | 
								__PUT('\\'); __PUT('r');
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '\b':
 | 
				
			||||||
 | 
								__PUT('\\'); __PUT('b');
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '\t':
 | 
				
			||||||
 | 
								__PUT('\\'); __PUT('t');
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '\f':
 | 
				
			||||||
 | 
								__PUT('\\'); __PUT('f');
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								__PUT(*val);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							val++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						__PUT('"');
 | 
				
			||||||
 | 
						__PUT('\0');
 | 
				
			||||||
 | 
						return len-1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
} /* extern "C" */
 | 
					} /* extern "C" */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ test_apps = [
 | 
				
			||||||
	'test-node',
 | 
						'test-node',
 | 
				
			||||||
	'test-pod',
 | 
						'test-pod',
 | 
				
			||||||
	'test-utils',
 | 
						'test-utils',
 | 
				
			||||||
 | 
						'test-json',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
foreach a : test_apps
 | 
					foreach a : test_apps
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										169
									
								
								spa/tests/test-json.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								spa/tests/test-json.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,169 @@
 | 
				
			||||||
 | 
					/* Simple Plugin API
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright © 2020 Wim Taymans <wim.taymans@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice (including the next
 | 
				
			||||||
 | 
					 * paragraph) shall be included in all copies or substantial portions of the
 | 
				
			||||||
 | 
					 * Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
				
			||||||
 | 
					 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
				
			||||||
 | 
					 * DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <spa/utils/defs.h>
 | 
				
			||||||
 | 
					#include <spa/utils/json.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_abi(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						spa_assert(sizeof(struct spa_json) == 32);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_OBJECT	0
 | 
				
			||||||
 | 
					#define TYPE_ARRAY	1
 | 
				
			||||||
 | 
					#define TYPE_STRING	2
 | 
				
			||||||
 | 
					#define TYPE_BOOL	3
 | 
				
			||||||
 | 
					#define TYPE_NULL	4
 | 
				
			||||||
 | 
					#define TYPE_TRUE	5
 | 
				
			||||||
 | 
					#define TYPE_FALSE	6
 | 
				
			||||||
 | 
					#define TYPE_FLOAT	7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void check_type(int type, const char *value, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_object(value, len) == (type == TYPE_OBJECT));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_array(value, len) == (type == TYPE_ARRAY));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_string(value, len) == (type == TYPE_STRING));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_bool(value, len) ==
 | 
				
			||||||
 | 
								(type == TYPE_BOOL || type == TYPE_TRUE || type == TYPE_FALSE));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_null(value, len) == (type == TYPE_NULL));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_true(value, len) == (type == TYPE_TRUE || type == TYPE_BOOL));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_false(value, len) == (type == TYPE_FALSE || type == TYPE_BOOL));
 | 
				
			||||||
 | 
						spa_assert(spa_json_is_float(value, len) == (type == TYPE_FLOAT));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void expect_type(struct spa_json *it, int type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *value;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
						spa_assert((len = spa_json_next(it, &value)) > 0);
 | 
				
			||||||
 | 
						check_type(type, value, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void expect_string(struct spa_json *it, const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *value;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
						char *s;
 | 
				
			||||||
 | 
						spa_assert((len = spa_json_next(it, &value)) > 0);
 | 
				
			||||||
 | 
						check_type(TYPE_STRING, value, len);
 | 
				
			||||||
 | 
						s = alloca(len);
 | 
				
			||||||
 | 
						spa_json_parse_string(value, len, s);
 | 
				
			||||||
 | 
						spa_assert(strcmp(s, str) == 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void expect_float(struct spa_json *it, float val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *value;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
						float f;
 | 
				
			||||||
 | 
						spa_assert((len = spa_json_next(it, &value)) > 0);
 | 
				
			||||||
 | 
						check_type(TYPE_FLOAT, value, len);
 | 
				
			||||||
 | 
						spa_assert(spa_json_parse_float(value, len, &f) > 0);
 | 
				
			||||||
 | 
						spa_assert(f == val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_parse(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct spa_json it[5];
 | 
				
			||||||
 | 
						const char *json = " { "
 | 
				
			||||||
 | 
								"\"foo\": \"bar\","
 | 
				
			||||||
 | 
								"\"foo\\\"  \":   true,       "
 | 
				
			||||||
 | 
								"\"foo \\n\\r\\t\": false,"
 | 
				
			||||||
 | 
								"  \"  arr\": [ true, false, null, 5, 5.7, \"str]\"],"
 | 
				
			||||||
 | 
								"\"foo 2\":     null,"
 | 
				
			||||||
 | 
								"\"foo 3\": 1,"
 | 
				
			||||||
 | 
								"  \"obj\": { \"ba } z\": false, \"empty\": [], \"foo\": { }, \"1.9\", 1.9 },"
 | 
				
			||||||
 | 
								"\"foo 4\"   : 1.8,   "
 | 
				
			||||||
 | 
								"\"foo 5\": -1.8  , "
 | 
				
			||||||
 | 
								"\"foo 6\":   +2.8   ,"
 | 
				
			||||||
 | 
								" } ", *value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_json_init(&it[0], json, strlen(json));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expect_type(&it[0], TYPE_OBJECT);
 | 
				
			||||||
 | 
						spa_json_enter(&it[0], &it[1]);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo");
 | 
				
			||||||
 | 
						expect_string(&it[1], "bar");
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo\"  ");
 | 
				
			||||||
 | 
						expect_type(&it[1], TYPE_TRUE);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo \n\r\t");
 | 
				
			||||||
 | 
						expect_type(&it[1], TYPE_FALSE);
 | 
				
			||||||
 | 
						expect_string(&it[1], "  arr");
 | 
				
			||||||
 | 
						expect_type(&it[1], TYPE_ARRAY);
 | 
				
			||||||
 | 
						spa_json_enter(&it[1], &it[2]);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo 2");
 | 
				
			||||||
 | 
						expect_type(&it[1], TYPE_NULL);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo 3");
 | 
				
			||||||
 | 
						expect_float(&it[1], 1.f);
 | 
				
			||||||
 | 
						expect_string(&it[1], "obj");
 | 
				
			||||||
 | 
						expect_type(&it[1], TYPE_OBJECT);
 | 
				
			||||||
 | 
						spa_json_enter(&it[1], &it[3]);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo 4");
 | 
				
			||||||
 | 
						expect_float(&it[1], 1.8f);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo 5");
 | 
				
			||||||
 | 
						expect_float(&it[1], -1.8f);
 | 
				
			||||||
 | 
						expect_string(&it[1], "foo 6");
 | 
				
			||||||
 | 
						expect_float(&it[1], +2.8f);
 | 
				
			||||||
 | 
						/* in the array */
 | 
				
			||||||
 | 
						expect_type(&it[2], TYPE_TRUE);
 | 
				
			||||||
 | 
						expect_type(&it[2], TYPE_FALSE);
 | 
				
			||||||
 | 
						expect_type(&it[2], TYPE_NULL);
 | 
				
			||||||
 | 
						expect_float(&it[2], 5.f);
 | 
				
			||||||
 | 
						expect_float(&it[2], 5.7f);
 | 
				
			||||||
 | 
						expect_string(&it[2], "str]");
 | 
				
			||||||
 | 
						/* in the object */
 | 
				
			||||||
 | 
						expect_string(&it[3], "ba } z");
 | 
				
			||||||
 | 
						expect_type(&it[3], TYPE_FALSE);
 | 
				
			||||||
 | 
						expect_string(&it[3], "empty");
 | 
				
			||||||
 | 
						expect_type(&it[3], TYPE_ARRAY);
 | 
				
			||||||
 | 
						spa_json_enter(&it[3], &it[4]);
 | 
				
			||||||
 | 
						spa_assert(spa_json_next(&it[4], &value) == 0);
 | 
				
			||||||
 | 
						expect_string(&it[3], "foo");
 | 
				
			||||||
 | 
						expect_type(&it[3], TYPE_OBJECT);
 | 
				
			||||||
 | 
						spa_json_enter(&it[3], &it[4]);
 | 
				
			||||||
 | 
						expect_string(&it[3], "1.9");
 | 
				
			||||||
 | 
						expect_float(&it[3], 1.9f);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_encode(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char dst[1024];
 | 
				
			||||||
 | 
						char dst4[4];
 | 
				
			||||||
 | 
						char dst6[6];
 | 
				
			||||||
 | 
						spa_assert(spa_json_encode_string(dst, sizeof(dst), "test") == 6);
 | 
				
			||||||
 | 
						spa_assert(strcmp(dst, "\"test\"") == 0);
 | 
				
			||||||
 | 
						spa_assert(spa_json_encode_string(dst4, sizeof(dst4), "test") == 6);
 | 
				
			||||||
 | 
						spa_assert(strncmp(dst4, "\"tes", 4) == 0);
 | 
				
			||||||
 | 
						spa_assert(spa_json_encode_string(dst6, sizeof(dst6), "test") == 6);
 | 
				
			||||||
 | 
						spa_assert(strncmp(dst6, "\"test\"", 6) == 0);
 | 
				
			||||||
 | 
						spa_assert(spa_json_encode_string(dst, sizeof(dst), "test\"\n\r \t\b\f\'") == 19);
 | 
				
			||||||
 | 
						spa_assert(strcmp(dst, "\"test\"\\n\\r \\t\\b\\f'\"") == 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						test_abi();
 | 
				
			||||||
 | 
						test_parse();
 | 
				
			||||||
 | 
						test_encode();
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -34,13 +34,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pipewire/pipewire.h"
 | 
					#include "pipewire/pipewire.h"
 | 
				
			||||||
#include "extensions/metadata.h"
 | 
					#include "extensions/metadata.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "media-session.h"
 | 
					#include "media-session.h"
 | 
				
			||||||
#include "json.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME		"default-nodes"
 | 
					#define NAME		"default-nodes"
 | 
				
			||||||
#define SESSION_KEY	"default-nodes"
 | 
					#define SESSION_KEY	"default-nodes"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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/pod/parser.h>
 | 
					#include <spa/pod/parser.h>
 | 
				
			||||||
#include <spa/pod/builder.h>
 | 
					#include <spa/pod/builder.h>
 | 
				
			||||||
#include <spa/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
| 
						 | 
					@ -42,7 +43,6 @@
 | 
				
			||||||
#include "extensions/metadata.h"
 | 
					#include "extensions/metadata.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "media-session.h"
 | 
					#include "media-session.h"
 | 
				
			||||||
#include "json.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME		"default-profile"
 | 
					#define NAME		"default-profile"
 | 
				
			||||||
#define SESSION_KEY	"default-profile"
 | 
					#define SESSION_KEY	"default-profile"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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/pod/parser.h>
 | 
					#include <spa/pod/parser.h>
 | 
				
			||||||
#include <spa/pod/builder.h>
 | 
					#include <spa/pod/builder.h>
 | 
				
			||||||
#include <spa/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
| 
						 | 
					@ -42,7 +43,6 @@
 | 
				
			||||||
#include "extensions/metadata.h"
 | 
					#include "extensions/metadata.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "media-session.h"
 | 
					#include "media-session.h"
 | 
				
			||||||
#include "json.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME		"default-routes"
 | 
					#define NAME		"default-routes"
 | 
				
			||||||
#define SESSION_KEY	"default-routes"
 | 
					#define SESSION_KEY	"default-routes"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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/pod/parser.h>
 | 
					#include <spa/pod/parser.h>
 | 
				
			||||||
#include <spa/pod/builder.h>
 | 
					#include <spa/pod/builder.h>
 | 
				
			||||||
#include <spa/debug/pod.h>
 | 
					#include <spa/debug/pod.h>
 | 
				
			||||||
| 
						 | 
					@ -42,7 +43,6 @@
 | 
				
			||||||
#include "extensions/metadata.h"
 | 
					#include "extensions/metadata.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "media-session.h"
 | 
					#include "media-session.h"
 | 
				
			||||||
#include "json.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME		"restore-stream"
 | 
					#define NAME		"restore-stream"
 | 
				
			||||||
#define SESSION_KEY	"restore-stream"
 | 
					#define SESSION_KEY	"restore-stream"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue