obs-data.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923
  1. /******************************************************************************
  2. Copyright (C) 2014 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include "util/bmem.h"
  15. #include "util/threading.h"
  16. #include "util/darray.h"
  17. #include "util/platform.h"
  18. #include "graphics/vec2.h"
  19. #include "graphics/vec3.h"
  20. #include "graphics/vec4.h"
  21. #include "graphics/quat.h"
  22. #include "obs-data.h"
  23. #include <jansson.h>
  24. struct obs_data_item {
  25. volatile long ref;
  26. struct obs_data *parent;
  27. struct obs_data_item *next;
  28. enum obs_data_type type;
  29. size_t name_len;
  30. size_t data_len;
  31. size_t data_size;
  32. size_t default_len;
  33. size_t default_size;
  34. size_t autoselect_size;
  35. size_t capacity;
  36. };
  37. struct obs_data {
  38. volatile long ref;
  39. char *json;
  40. struct obs_data_item *first_item;
  41. };
  42. struct obs_data_array {
  43. volatile long ref;
  44. DARRAY(obs_data_t*) objects;
  45. };
  46. struct obs_data_number {
  47. enum obs_data_number_type type;
  48. union {
  49. long long int_val;
  50. double double_val;
  51. };
  52. };
  53. /* ------------------------------------------------------------------------- */
  54. /* Item structure, designed to be one allocation only */
  55. static inline size_t get_align_size(size_t size)
  56. {
  57. const size_t alignment = base_get_alignment();
  58. return (size + alignment - 1) & ~(alignment - 1);
  59. }
  60. /* ensures data after the name has alignment (in case of SSE) */
  61. static inline size_t get_name_align_size(const char *name)
  62. {
  63. size_t name_size = strlen(name) + 1;
  64. size_t alignment = base_get_alignment();
  65. size_t total_size;
  66. total_size = sizeof(struct obs_data_item) + (name_size + alignment-1);
  67. total_size &= ~(alignment-1);
  68. return total_size - sizeof(struct obs_data_item);
  69. }
  70. static inline char *get_item_name(struct obs_data_item *item)
  71. {
  72. return (char*)item + sizeof(struct obs_data_item);
  73. }
  74. static inline void *get_data_ptr(obs_data_item_t *item)
  75. {
  76. return (uint8_t*)get_item_name(item) + item->name_len;
  77. }
  78. static inline void *get_item_data(struct obs_data_item *item)
  79. {
  80. if (!item->data_size && !item->default_size && !item->autoselect_size)
  81. return NULL;
  82. return get_data_ptr(item);
  83. }
  84. static inline void *get_default_data_ptr(obs_data_item_t *item)
  85. {
  86. return (uint8_t*)get_data_ptr(item) + item->data_len;
  87. }
  88. static inline void *get_item_default_data(struct obs_data_item *item)
  89. {
  90. return item->default_size ? get_default_data_ptr(item) : NULL;
  91. }
  92. static inline void *get_autoselect_data_ptr(obs_data_item_t *item)
  93. {
  94. return (uint8_t*)get_default_data_ptr(item) + item->default_len;
  95. }
  96. static inline void *get_item_autoselect_data(struct obs_data_item *item)
  97. {
  98. return item->autoselect_size ? get_autoselect_data_ptr(item) : NULL;
  99. }
  100. static inline size_t obs_data_item_total_size(struct obs_data_item *item)
  101. {
  102. return sizeof(struct obs_data_item) + item->name_len +
  103. item->data_len + item->default_len + item->autoselect_size;
  104. }
  105. static inline obs_data_t *get_item_obj(struct obs_data_item *item)
  106. {
  107. if (!item)
  108. return NULL;
  109. return *(obs_data_t**)get_item_data(item);
  110. }
  111. static inline obs_data_t *get_item_default_obj(struct obs_data_item *item)
  112. {
  113. if (!item || !item->default_size)
  114. return NULL;
  115. return *(obs_data_t**)get_default_data_ptr(item);
  116. }
  117. static inline obs_data_t *get_item_autoselect_obj(struct obs_data_item *item)
  118. {
  119. if (!item || !item->autoselect_size)
  120. return NULL;
  121. return *(obs_data_t**)get_autoselect_data_ptr(item);
  122. }
  123. static inline obs_data_array_t *get_item_array(struct obs_data_item *item)
  124. {
  125. if (!item)
  126. return NULL;
  127. return *(obs_data_array_t**)get_item_data(item);
  128. }
  129. static inline obs_data_array_t *get_item_default_array(
  130. struct obs_data_item *item)
  131. {
  132. if (!item || !item->default_size)
  133. return NULL;
  134. return *(obs_data_array_t**)get_default_data_ptr(item);
  135. }
  136. static inline obs_data_array_t *get_item_autoselect_array(
  137. struct obs_data_item *item)
  138. {
  139. if (!item || !item->autoselect_size)
  140. return NULL;
  141. return *(obs_data_array_t**)get_autoselect_data_ptr(item);
  142. }
  143. static inline void item_data_release(struct obs_data_item *item)
  144. {
  145. if (!obs_data_item_has_user_value(item))
  146. return;
  147. if (item->type == OBS_DATA_OBJECT) {
  148. obs_data_t *obj = get_item_obj(item);
  149. obs_data_release(obj);
  150. } else if (item->type == OBS_DATA_ARRAY) {
  151. obs_data_array_t *array = get_item_array(item);
  152. obs_data_array_release(array);
  153. }
  154. }
  155. static inline void item_default_data_release(struct obs_data_item *item)
  156. {
  157. if (item->type == OBS_DATA_OBJECT) {
  158. obs_data_t *obj = get_item_default_obj(item);
  159. obs_data_release(obj);
  160. } else if (item->type == OBS_DATA_ARRAY) {
  161. obs_data_array_t *array = get_item_default_array(item);
  162. obs_data_array_release(array);
  163. }
  164. }
  165. static inline void item_autoselect_data_release(struct obs_data_item *item)
  166. {
  167. if (item->type == OBS_DATA_OBJECT) {
  168. obs_data_t *obj = get_item_autoselect_obj(item);
  169. obs_data_release(obj);
  170. } else if (item->type == OBS_DATA_ARRAY) {
  171. obs_data_array_t *array = get_item_autoselect_array(item);
  172. obs_data_array_release(array);
  173. }
  174. }
  175. static inline void item_data_addref(struct obs_data_item *item)
  176. {
  177. if (item->type == OBS_DATA_OBJECT) {
  178. obs_data_t *obj = get_item_obj(item);
  179. obs_data_addref(obj);
  180. } else if (item->type == OBS_DATA_ARRAY) {
  181. obs_data_array_t *array = get_item_array(item);
  182. obs_data_array_addref(array);
  183. }
  184. }
  185. static inline void item_default_data_addref(struct obs_data_item *item)
  186. {
  187. if (!item->data_size)
  188. return;
  189. if (item->type == OBS_DATA_OBJECT) {
  190. obs_data_t *obj = get_item_default_obj(item);
  191. obs_data_addref(obj);
  192. } else if (item->type == OBS_DATA_ARRAY) {
  193. obs_data_array_t *array = get_item_default_array(item);
  194. obs_data_array_addref(array);
  195. }
  196. }
  197. static inline void item_autoselect_data_addref(struct obs_data_item *item)
  198. {
  199. if (item->type == OBS_DATA_OBJECT) {
  200. obs_data_t *obj = get_item_autoselect_obj(item);
  201. obs_data_addref(obj);
  202. } else if (item->type == OBS_DATA_ARRAY) {
  203. obs_data_array_t *array = get_item_autoselect_array(item);
  204. obs_data_array_addref(array);
  205. }
  206. }
  207. static struct obs_data_item *obs_data_item_create(const char *name,
  208. const void *data, size_t size, enum obs_data_type type,
  209. bool default_data, bool autoselect_data)
  210. {
  211. struct obs_data_item *item;
  212. size_t name_size, total_size;
  213. if (!name || !data)
  214. return NULL;
  215. name_size = get_name_align_size(name);
  216. total_size = name_size + sizeof(struct obs_data_item) + size;
  217. item = bzalloc(total_size);
  218. item->capacity = total_size;
  219. item->type = type;
  220. item->name_len = name_size;
  221. item->ref = 1;
  222. if (default_data) {
  223. item->default_len = size;
  224. item->default_size = size;
  225. } else if (autoselect_data) {
  226. item->autoselect_size = size;
  227. } else {
  228. item->data_len = size;
  229. item->data_size = size;
  230. }
  231. strcpy(get_item_name(item), name);
  232. memcpy(get_item_data(item), data, size);
  233. item_data_addref(item);
  234. return item;
  235. }
  236. static struct obs_data_item **get_item_prev_next(struct obs_data *data,
  237. struct obs_data_item *current)
  238. {
  239. if (!current || !data)
  240. return NULL;
  241. struct obs_data_item **prev_next = &data->first_item;
  242. struct obs_data_item *item = data->first_item;
  243. while (item) {
  244. if (item == current)
  245. return prev_next;
  246. prev_next = &item->next;
  247. item = item->next;
  248. }
  249. return NULL;
  250. }
  251. static inline void obs_data_item_detach(struct obs_data_item *item)
  252. {
  253. struct obs_data_item **prev_next = get_item_prev_next(item->parent,
  254. item);
  255. if (prev_next) {
  256. *prev_next = item->next;
  257. item->next = NULL;
  258. }
  259. }
  260. static inline void obs_data_item_reattach(struct obs_data_item *old_ptr,
  261. struct obs_data_item *new_ptr)
  262. {
  263. struct obs_data_item **prev_next = get_item_prev_next(new_ptr->parent,
  264. old_ptr);
  265. if (prev_next)
  266. *prev_next = new_ptr;
  267. }
  268. static struct obs_data_item *obs_data_item_ensure_capacity(
  269. struct obs_data_item *item)
  270. {
  271. size_t new_size = obs_data_item_total_size(item);
  272. struct obs_data_item *new_item;
  273. if (item->capacity >= new_size)
  274. return item;
  275. new_item = brealloc(item, new_size);
  276. new_item->capacity = new_size;
  277. obs_data_item_reattach(item, new_item);
  278. return new_item;
  279. }
  280. static inline void obs_data_item_destroy(struct obs_data_item *item)
  281. {
  282. item_data_release(item);
  283. item_default_data_release(item);
  284. item_autoselect_data_release(item);
  285. obs_data_item_detach(item);
  286. bfree(item);
  287. }
  288. static inline void move_data(obs_data_item_t *old_item, void *old_data,
  289. obs_data_item_t *item, void *data, size_t len)
  290. {
  291. ptrdiff_t old_offset = (uint8_t*)old_data - (uint8_t*)old_item;
  292. ptrdiff_t new_offset = (uint8_t*)data - (uint8_t*)item;
  293. if (!old_data)
  294. return;
  295. memmove((uint8_t*)item + new_offset, (uint8_t*)item + old_offset, len);
  296. }
  297. static inline void obs_data_item_setdata(
  298. struct obs_data_item **p_item, const void *data, size_t size,
  299. enum obs_data_type type)
  300. {
  301. if (!p_item || !*p_item)
  302. return;
  303. struct obs_data_item *item = *p_item;
  304. ptrdiff_t old_default_data_pos =
  305. (uint8_t*)get_default_data_ptr(item) - (uint8_t*)item;
  306. item_data_release(item);
  307. item->data_size = size;
  308. item->type = type;
  309. item->data_len = (item->default_size || item->autoselect_size) ?
  310. get_align_size(size) : size;
  311. item = obs_data_item_ensure_capacity(item);
  312. if (item->default_size || item->autoselect_size)
  313. memmove(get_default_data_ptr(item),
  314. (uint8_t*)item + old_default_data_pos,
  315. item->default_len + item->autoselect_size);
  316. if (size) {
  317. memcpy(get_item_data(item), data, size);
  318. item_data_addref(item);
  319. }
  320. *p_item = item;
  321. }
  322. static inline void obs_data_item_set_default_data(
  323. struct obs_data_item **p_item, const void *data, size_t size,
  324. enum obs_data_type type)
  325. {
  326. if (!p_item || !*p_item)
  327. return;
  328. struct obs_data_item *item = *p_item;
  329. void *old_autoselect_data = get_autoselect_data_ptr(item);
  330. item_default_data_release(item);
  331. item->type = type;
  332. item->default_size = size;
  333. item->default_len = item->autoselect_size ?
  334. get_align_size(size) : size;
  335. item->data_len = item->data_size ?
  336. get_align_size(item->data_size) : 0;
  337. item = obs_data_item_ensure_capacity(item);
  338. if (item->autoselect_size)
  339. move_data(*p_item, old_autoselect_data, item,
  340. get_autoselect_data_ptr(item),
  341. item->autoselect_size);
  342. if (size) {
  343. memcpy(get_item_default_data(item), data, size);
  344. item_default_data_addref(item);
  345. }
  346. *p_item = item;
  347. }
  348. static inline void obs_data_item_set_autoselect_data(
  349. struct obs_data_item **p_item, const void *data, size_t size,
  350. enum obs_data_type type)
  351. {
  352. if (!p_item || !*p_item)
  353. return;
  354. struct obs_data_item *item = *p_item;
  355. item_autoselect_data_release(item);
  356. item->autoselect_size = size;
  357. item->type = type;
  358. item->data_len = item->data_size ?
  359. get_align_size(item->data_size) : 0;
  360. item->default_len = item->default_size ?
  361. get_align_size(item->default_size) : 0;
  362. item = obs_data_item_ensure_capacity(item);
  363. if (size) {
  364. memcpy(get_item_autoselect_data(item), data, size);
  365. item_autoselect_data_addref(item);
  366. }
  367. *p_item = item;
  368. }
  369. /* ------------------------------------------------------------------------- */
  370. static void obs_data_add_json_item(obs_data_t *data, const char *key,
  371. json_t *json);
  372. static inline void obs_data_add_json_object_data(obs_data_t *data, json_t *jobj)
  373. {
  374. const char *item_key;
  375. json_t *jitem;
  376. json_object_foreach (jobj, item_key, jitem) {
  377. obs_data_add_json_item(data, item_key, jitem);
  378. }
  379. }
  380. static inline void obs_data_add_json_object(obs_data_t *data, const char *key,
  381. json_t *jobj)
  382. {
  383. obs_data_t *sub_obj = obs_data_create();
  384. obs_data_add_json_object_data(sub_obj, jobj);
  385. obs_data_set_obj(data, key, sub_obj);
  386. obs_data_release(sub_obj);
  387. }
  388. static void obs_data_add_json_array(obs_data_t *data, const char *key,
  389. json_t *jarray)
  390. {
  391. obs_data_array_t *array = obs_data_array_create();
  392. size_t idx;
  393. json_t *jitem;
  394. json_array_foreach (jarray, idx, jitem) {
  395. obs_data_t *item;
  396. if (!json_is_object(jitem))
  397. continue;
  398. item = obs_data_create();
  399. obs_data_add_json_object_data(item, jitem);
  400. obs_data_array_push_back(array, item);
  401. obs_data_release(item);
  402. }
  403. obs_data_set_array(data, key, array);
  404. obs_data_array_release(array);
  405. }
  406. static void obs_data_add_json_item(obs_data_t *data, const char *key,
  407. json_t *json)
  408. {
  409. if (json_is_object(json))
  410. obs_data_add_json_object(data, key, json);
  411. else if (json_is_array(json))
  412. obs_data_add_json_array(data, key, json);
  413. else if (json_is_string(json))
  414. obs_data_set_string(data, key, json_string_value(json));
  415. else if (json_is_integer(json))
  416. obs_data_set_int(data, key, json_integer_value(json));
  417. else if (json_is_real(json))
  418. obs_data_set_double(data, key, json_real_value(json));
  419. else if (json_is_true(json))
  420. obs_data_set_bool(data, key, true);
  421. else if (json_is_false(json))
  422. obs_data_set_bool(data, key, false);
  423. }
  424. /* ------------------------------------------------------------------------- */
  425. static inline void set_json_string(json_t *json, const char *name,
  426. obs_data_item_t *item)
  427. {
  428. const char *val = obs_data_item_get_string(item);
  429. json_object_set_new(json, name, json_string(val));
  430. }
  431. static inline void set_json_number(json_t *json, const char *name,
  432. obs_data_item_t *item)
  433. {
  434. enum obs_data_number_type type = obs_data_item_numtype(item);
  435. if (type == OBS_DATA_NUM_INT) {
  436. long long val = obs_data_item_get_int(item);
  437. json_object_set_new(json, name, json_integer(val));
  438. } else {
  439. double val = obs_data_item_get_double(item);
  440. json_object_set_new(json, name, json_real(val));
  441. }
  442. }
  443. static inline void set_json_bool(json_t *json, const char *name,
  444. obs_data_item_t *item)
  445. {
  446. bool val = obs_data_item_get_bool(item);
  447. json_object_set_new(json, name, val ? json_true() : json_false());
  448. }
  449. static json_t *obs_data_to_json(obs_data_t *data);
  450. static inline void set_json_obj(json_t *json, const char *name,
  451. obs_data_item_t *item)
  452. {
  453. obs_data_t *obj = obs_data_item_get_obj(item);
  454. json_object_set_new(json, name, obs_data_to_json(obj));
  455. obs_data_release(obj);
  456. }
  457. static inline void set_json_array(json_t *json, const char *name,
  458. obs_data_item_t *item)
  459. {
  460. json_t *jarray = json_array();
  461. obs_data_array_t *array = obs_data_item_get_array(item);
  462. size_t count = obs_data_array_count(array);
  463. for (size_t idx = 0; idx < count; idx++) {
  464. obs_data_t *sub_item = obs_data_array_item(array, idx);
  465. json_t *jitem = obs_data_to_json(sub_item);
  466. json_array_append_new(jarray, jitem);
  467. obs_data_release(sub_item);
  468. }
  469. json_object_set_new(json, name, jarray);
  470. obs_data_array_release(array);
  471. }
  472. static json_t *obs_data_to_json(obs_data_t *data)
  473. {
  474. json_t *json = json_object();
  475. obs_data_item_t *item = NULL;
  476. for (item = obs_data_first(data); item; obs_data_item_next(&item)) {
  477. enum obs_data_type type = obs_data_item_gettype(item);
  478. const char *name = get_item_name(item);
  479. if (!obs_data_item_has_user_value(item))
  480. continue;
  481. if (type == OBS_DATA_STRING)
  482. set_json_string(json, name, item);
  483. else if (type == OBS_DATA_NUMBER)
  484. set_json_number(json, name, item);
  485. else if (type == OBS_DATA_BOOLEAN)
  486. set_json_bool(json, name, item);
  487. else if (type == OBS_DATA_OBJECT)
  488. set_json_obj(json, name, item);
  489. else if (type == OBS_DATA_ARRAY)
  490. set_json_array(json, name, item);
  491. }
  492. return json;
  493. }
  494. /* ------------------------------------------------------------------------- */
  495. obs_data_t *obs_data_create()
  496. {
  497. struct obs_data *data = bzalloc(sizeof(struct obs_data));
  498. data->ref = 1;
  499. return data;
  500. }
  501. obs_data_t *obs_data_create_from_json(const char *json_string)
  502. {
  503. obs_data_t *data = obs_data_create();
  504. json_error_t error;
  505. json_t *root = json_loads(json_string, JSON_REJECT_DUPLICATES, &error);
  506. if (root) {
  507. obs_data_add_json_object_data(data, root);
  508. json_decref(root);
  509. } else {
  510. blog(LOG_ERROR, "obs-data.c: [obs_data_create_from_json] "
  511. "Failed reading json string (%d): %s",
  512. error.line, error.text);
  513. }
  514. return data;
  515. }
  516. obs_data_t *obs_data_create_from_json_file(const char *json_file)
  517. {
  518. char *file_data = os_quick_read_utf8_file(json_file);
  519. obs_data_t *data = NULL;
  520. if (file_data) {
  521. data = obs_data_create_from_json(file_data);
  522. bfree(file_data);
  523. }
  524. return data;
  525. }
  526. void obs_data_addref(obs_data_t *data)
  527. {
  528. if (data)
  529. os_atomic_inc_long(&data->ref);
  530. }
  531. static inline void obs_data_destroy(struct obs_data *data)
  532. {
  533. struct obs_data_item *item = data->first_item;
  534. while (item) {
  535. struct obs_data_item *next = item->next;
  536. obs_data_item_release(&item);
  537. item = next;
  538. }
  539. /* NOTE: don't use bfree for json text, allocated by json */
  540. free(data->json);
  541. bfree(data);
  542. }
  543. void obs_data_release(obs_data_t *data)
  544. {
  545. if (!data) return;
  546. if (os_atomic_dec_long(&data->ref) == 0)
  547. obs_data_destroy(data);
  548. }
  549. const char *obs_data_get_json(obs_data_t *data)
  550. {
  551. if (!data) return NULL;
  552. /* NOTE: don't use libobs bfree for json text */
  553. free(data->json);
  554. data->json = NULL;
  555. json_t *root = obs_data_to_json(data);
  556. data->json = json_dumps(root, JSON_PRESERVE_ORDER | JSON_INDENT(4));
  557. json_decref(root);
  558. return data->json;
  559. }
  560. static struct obs_data_item *get_item(struct obs_data *data, const char *name)
  561. {
  562. if (!data) return NULL;
  563. struct obs_data_item *item = data->first_item;
  564. while (item) {
  565. if (strcmp(get_item_name(item), name) == 0)
  566. return item;
  567. item = item->next;
  568. }
  569. return NULL;
  570. }
  571. static void set_item_data(struct obs_data *data, struct obs_data_item **item,
  572. const char *name, const void *ptr, size_t size,
  573. enum obs_data_type type,
  574. bool default_data, bool autoselect_data)
  575. {
  576. obs_data_item_t *new_item = NULL;
  577. if ((!item || (item && !*item)) && data) {
  578. new_item = obs_data_item_create(name, ptr, size, type,
  579. default_data, autoselect_data);
  580. obs_data_item_t *prev = obs_data_first(data);
  581. obs_data_item_t *next = obs_data_first(data);
  582. obs_data_item_next(&next);
  583. for (; prev && next; obs_data_item_next(&prev),
  584. obs_data_item_next(&next)) {
  585. if (strcmp(get_item_name(next), name) > 0)
  586. break;
  587. }
  588. new_item->parent = data;
  589. if (prev && strcmp(get_item_name(prev), name) < 0) {
  590. prev->next = new_item;
  591. new_item->next = next;
  592. } else {
  593. data->first_item = new_item;
  594. new_item->next = prev;
  595. }
  596. if (!prev)
  597. data->first_item = new_item;
  598. obs_data_item_release(&prev);
  599. obs_data_item_release(&next);
  600. } else if (default_data) {
  601. obs_data_item_set_default_data(item, ptr, size, type);
  602. } else if (autoselect_data) {
  603. obs_data_item_set_autoselect_data(item, ptr, size, type);
  604. } else {
  605. obs_data_item_setdata(item, ptr, size, type);
  606. }
  607. }
  608. static inline void set_item(struct obs_data *data, obs_data_item_t **item,
  609. const char *name,
  610. const void *ptr, size_t size, enum obs_data_type type)
  611. {
  612. obs_data_item_t *actual_item = NULL;
  613. if (!data && !item)
  614. return;
  615. if (!item) {
  616. actual_item = get_item(data, name);
  617. item = &actual_item;
  618. }
  619. set_item_data(data, item, name, ptr, size, type, false, false);
  620. }
  621. static inline void set_item_def(struct obs_data *data, obs_data_item_t **item,
  622. const char *name,
  623. const void *ptr, size_t size, enum obs_data_type type)
  624. {
  625. obs_data_item_t *actual_item = NULL;
  626. if (!data && !item)
  627. return;
  628. if (!item) {
  629. actual_item = get_item(data, name);
  630. item = &actual_item;
  631. }
  632. if (item && *item && (*item)->type == type)
  633. return;
  634. set_item_data(data, item, name, ptr, size, type, true, false);
  635. }
  636. static inline void set_item_auto(struct obs_data *data, obs_data_item_t **item,
  637. const char *name,
  638. const void *ptr, size_t size, enum obs_data_type type)
  639. {
  640. obs_data_item_t *actual_item = NULL;
  641. if (!data && !item)
  642. return;
  643. if (!item) {
  644. actual_item = get_item(data, name);
  645. item = &actual_item;
  646. }
  647. set_item_data(data, item, name, ptr, size, type, false, true);
  648. }
  649. static void copy_obj(struct obs_data *data, const char *name,
  650. struct obs_data *obj,
  651. void (*callback)(obs_data_t *, const char *, obs_data_t *))
  652. {
  653. if (obj) {
  654. obs_data_t *new_obj = obs_data_create();
  655. obs_data_apply(new_obj, obj);
  656. callback(data, name, new_obj);
  657. obs_data_release(new_obj);
  658. }
  659. }
  660. static void copy_array(struct obs_data *data, const char *name,
  661. struct obs_data_array *array,
  662. void (*callback)(obs_data_t*, const char*, obs_data_array_t*))
  663. {
  664. if (array) {
  665. obs_data_array_t *new_array = obs_data_array_create();
  666. da_reserve(new_array->objects, array->objects.num);
  667. for (size_t i = 0; i < array->objects.num; i++) {
  668. obs_data_t *new_obj = obs_data_create();
  669. obs_data_t *obj = array->objects.array[i];
  670. obs_data_apply(new_obj, obj);
  671. obs_data_array_push_back(new_array, new_obj);
  672. obs_data_release(new_obj);
  673. }
  674. callback(data, name, new_array);
  675. obs_data_array_release(new_array);
  676. }
  677. }
  678. static inline void copy_item(struct obs_data *data, struct obs_data_item *item)
  679. {
  680. const char *name = get_item_name(item);
  681. void *ptr = get_item_data(item);
  682. if (item->type == OBS_DATA_OBJECT) {
  683. obs_data_t **obj = item->data_size ? ptr : NULL;
  684. if (obj)
  685. copy_obj(data, name, *obj, obs_data_set_obj);
  686. } else if (item->type == OBS_DATA_ARRAY) {
  687. obs_data_array_t **array = item->data_size ? ptr : NULL;
  688. if (array)
  689. copy_array(data, name, *array, obs_data_set_array);
  690. } else {
  691. if (item->data_size)
  692. set_item(data, NULL, name, ptr, item->data_size,
  693. item->type);
  694. }
  695. }
  696. void obs_data_apply(obs_data_t *target, obs_data_t *apply_data)
  697. {
  698. struct obs_data_item *item;
  699. if (!target || !apply_data || target == apply_data)
  700. return;
  701. item = apply_data->first_item;
  702. while (item) {
  703. copy_item(target, item);
  704. item = item->next;
  705. }
  706. }
  707. void obs_data_erase(obs_data_t *data, const char *name)
  708. {
  709. struct obs_data_item *item = get_item(data, name);
  710. if (item) {
  711. obs_data_item_detach(item);
  712. obs_data_item_release(&item);
  713. }
  714. }
  715. static inline void clear_item(struct obs_data_item *item)
  716. {
  717. void *ptr = get_item_data(item);
  718. size_t size;
  719. if (item->data_len) {
  720. if (item->type == OBS_DATA_OBJECT) {
  721. obs_data_t **obj = item->data_size ? ptr : NULL;
  722. if (obj && *obj)
  723. obs_data_release(*obj);
  724. } else if (item->type == OBS_DATA_ARRAY) {
  725. obs_data_array_t **array = item->data_size ? ptr : NULL;
  726. if (array && *array)
  727. obs_data_array_release(*array);
  728. }
  729. size = item->default_len + item->autoselect_size;
  730. if (size)
  731. memmove(ptr, (uint8_t*)ptr + item->data_len, size);
  732. item->data_size = 0;
  733. item->data_len = 0;
  734. }
  735. }
  736. void obs_data_clear(obs_data_t *target)
  737. {
  738. struct obs_data_item *item;
  739. if (!target)
  740. return;
  741. item = target->first_item;
  742. while (item) {
  743. clear_item(item);
  744. item = item->next;
  745. }
  746. }
  747. typedef void (*set_item_t)(obs_data_t*, obs_data_item_t**, const char*,
  748. const void*, size_t, enum obs_data_type);
  749. static inline void obs_set_string(obs_data_t *data, obs_data_item_t **item,
  750. const char *name,
  751. const char *val, set_item_t set_item_)
  752. {
  753. if (!val) val = "";
  754. set_item_(data, item, name, val, strlen(val)+1, OBS_DATA_STRING);
  755. }
  756. static inline void obs_set_int(obs_data_t *data, obs_data_item_t **item,
  757. const char *name,
  758. long long val, set_item_t set_item_)
  759. {
  760. struct obs_data_number num;
  761. num.type = OBS_DATA_NUM_INT;
  762. num.int_val = val;
  763. set_item_(data, item, name, &num, sizeof(struct obs_data_number),
  764. OBS_DATA_NUMBER);
  765. }
  766. static inline void obs_set_double(obs_data_t *data, obs_data_item_t **item,
  767. const char *name,
  768. double val, set_item_t set_item_)
  769. {
  770. struct obs_data_number num;
  771. num.type = OBS_DATA_NUM_DOUBLE;
  772. num.double_val = val;
  773. set_item_(data, item, name, &num, sizeof(struct obs_data_number),
  774. OBS_DATA_NUMBER);
  775. }
  776. static inline void obs_set_bool(obs_data_t *data, obs_data_item_t **item,
  777. const char *name,
  778. bool val, set_item_t set_item_)
  779. {
  780. set_item_(data, item, name, &val, sizeof(bool), OBS_DATA_BOOLEAN);
  781. }
  782. static inline void obs_set_obj(obs_data_t *data, obs_data_item_t **item,
  783. const char *name,
  784. obs_data_t *obj, set_item_t set_item_)
  785. {
  786. set_item_(data, item, name, &obj, sizeof(obs_data_t*), OBS_DATA_OBJECT);
  787. }
  788. static inline void obs_set_array(obs_data_t *data, obs_data_item_t **item,
  789. const char *name,
  790. obs_data_array_t *array, set_item_t set_item_)
  791. {
  792. set_item_(data, item, name, &array, sizeof(obs_data_t*), OBS_DATA_ARRAY);
  793. }
  794. void obs_data_set_string(obs_data_t *data, const char *name, const char *val)
  795. {
  796. obs_set_string(data, NULL, name, val, set_item);
  797. }
  798. void obs_data_set_int(obs_data_t *data, const char *name, long long val)
  799. {
  800. obs_set_int(data, NULL, name, val, set_item);
  801. }
  802. void obs_data_set_double(obs_data_t *data, const char *name, double val)
  803. {
  804. obs_set_double(data, NULL, name, val, set_item);
  805. }
  806. void obs_data_set_bool(obs_data_t *data, const char *name, bool val)
  807. {
  808. obs_set_bool(data, NULL, name, val, set_item);
  809. }
  810. void obs_data_set_obj(obs_data_t *data, const char *name, obs_data_t *obj)
  811. {
  812. obs_set_obj(data, NULL, name, obj, set_item);
  813. }
  814. void obs_data_set_array(obs_data_t *data, const char *name,
  815. obs_data_array_t *array)
  816. {
  817. obs_set_array(data, NULL, name, array, set_item);
  818. }
  819. void obs_data_set_default_string(obs_data_t *data, const char *name,
  820. const char *val)
  821. {
  822. obs_set_string(data, NULL, name, val, set_item_def);
  823. }
  824. void obs_data_set_default_int(obs_data_t *data, const char *name, long long val)
  825. {
  826. obs_set_int(data, NULL, name, val, set_item_def);
  827. }
  828. void obs_data_set_default_double(obs_data_t *data, const char *name, double val)
  829. {
  830. obs_set_double(data, NULL, name, val, set_item_def);
  831. }
  832. void obs_data_set_default_bool(obs_data_t *data, const char *name, bool val)
  833. {
  834. obs_set_bool(data, NULL, name, val, set_item_def);
  835. }
  836. void obs_data_set_default_obj(obs_data_t *data, const char *name, obs_data_t *obj)
  837. {
  838. obs_set_obj(data, NULL, name, obj, set_item_def);
  839. }
  840. void obs_data_set_autoselect_string(obs_data_t *data, const char *name,
  841. const char *val)
  842. {
  843. obs_set_string(data, NULL, name, val, set_item_auto);
  844. }
  845. void obs_data_set_autoselect_int(obs_data_t *data, const char *name,
  846. long long val)
  847. {
  848. obs_set_int(data, NULL, name, val, set_item_auto);
  849. }
  850. void obs_data_set_autoselect_double(obs_data_t *data, const char *name,
  851. double val)
  852. {
  853. obs_set_double(data, NULL, name, val, set_item_auto);
  854. }
  855. void obs_data_set_autoselect_bool(obs_data_t *data, const char *name, bool val)
  856. {
  857. obs_set_bool(data, NULL, name, val, set_item_auto);
  858. }
  859. void obs_data_set_autoselect_obj(obs_data_t *data, const char *name,
  860. obs_data_t *obj)
  861. {
  862. obs_set_obj(data, NULL, name, obj, set_item_auto);
  863. }
  864. void obs_data_set_autoselect_array(obs_data_t *data, const char *name,
  865. obs_data_array_t *arr)
  866. {
  867. obs_set_array(data, NULL, name, arr, set_item_auto);
  868. }
  869. const char *obs_data_get_string(obs_data_t *data, const char *name)
  870. {
  871. return obs_data_item_get_string(get_item(data, name));
  872. }
  873. long long obs_data_get_int(obs_data_t *data, const char *name)
  874. {
  875. return obs_data_item_get_int(get_item(data, name));
  876. }
  877. double obs_data_get_double(obs_data_t *data, const char *name)
  878. {
  879. return obs_data_item_get_double(get_item(data, name));
  880. }
  881. bool obs_data_get_bool(obs_data_t *data, const char *name)
  882. {
  883. return obs_data_item_get_bool(get_item(data, name));
  884. }
  885. obs_data_t *obs_data_get_obj(obs_data_t *data, const char *name)
  886. {
  887. return obs_data_item_get_obj(get_item(data, name));
  888. }
  889. obs_data_array_t *obs_data_get_array(obs_data_t *data, const char *name)
  890. {
  891. return obs_data_item_get_array(get_item(data, name));
  892. }
  893. const char *obs_data_get_default_string(obs_data_t *data, const char *name)
  894. {
  895. return obs_data_item_get_default_string(get_item(data, name));
  896. }
  897. long long obs_data_get_default_int(obs_data_t *data, const char *name)
  898. {
  899. return obs_data_item_get_default_int(get_item(data, name));
  900. }
  901. double obs_data_get_default_double(obs_data_t *data, const char *name)
  902. {
  903. return obs_data_item_get_default_double(get_item(data, name));
  904. }
  905. bool obs_data_get_default_bool(obs_data_t *data, const char *name)
  906. {
  907. return obs_data_item_get_default_bool(get_item(data, name));
  908. }
  909. obs_data_t *obs_data_get_default_obj(obs_data_t *data, const char *name)
  910. {
  911. return obs_data_item_get_default_obj(get_item(data, name));
  912. }
  913. obs_data_array_t *obs_data_get_default_array(obs_data_t *data, const char *name)
  914. {
  915. return obs_data_item_get_default_array(get_item(data, name));
  916. }
  917. const char *obs_data_get_autoselect_string(obs_data_t *data, const char *name)
  918. {
  919. return obs_data_item_get_autoselect_string(get_item(data, name));
  920. }
  921. long long obs_data_get_autoselect_int(obs_data_t *data, const char *name)
  922. {
  923. return obs_data_item_get_autoselect_int(get_item(data, name));
  924. }
  925. double obs_data_get_autoselect_double(obs_data_t *data, const char *name)
  926. {
  927. return obs_data_item_get_autoselect_double(get_item(data, name));
  928. }
  929. bool obs_data_get_autoselect_bool(obs_data_t *data, const char *name)
  930. {
  931. return obs_data_item_get_autoselect_bool(get_item(data, name));
  932. }
  933. obs_data_t *obs_data_get_autoselect_obj(obs_data_t *data, const char *name)
  934. {
  935. return obs_data_item_get_autoselect_obj(get_item(data, name));
  936. }
  937. obs_data_array_t *obs_data_get_autoselect_array(obs_data_t *data,
  938. const char *name)
  939. {
  940. return obs_data_item_get_autoselect_array(get_item(data, name));
  941. }
  942. obs_data_array_t *obs_data_array_create()
  943. {
  944. struct obs_data_array *array = bzalloc(sizeof(struct obs_data_array));
  945. array->ref = 1;
  946. return array;
  947. }
  948. void obs_data_array_addref(obs_data_array_t *array)
  949. {
  950. if (array)
  951. os_atomic_inc_long(&array->ref);
  952. }
  953. static inline void obs_data_array_destroy(obs_data_array_t *array)
  954. {
  955. if (array) {
  956. for (size_t i = 0; i < array->objects.num; i++)
  957. obs_data_release(array->objects.array[i]);
  958. da_free(array->objects);
  959. bfree(array);
  960. }
  961. }
  962. void obs_data_array_release(obs_data_array_t *array)
  963. {
  964. if (!array)
  965. return;
  966. if (os_atomic_dec_long(&array->ref) == 0)
  967. obs_data_array_destroy(array);
  968. }
  969. size_t obs_data_array_count(obs_data_array_t *array)
  970. {
  971. return array ? array->objects.num : 0;
  972. }
  973. obs_data_t *obs_data_array_item(obs_data_array_t *array, size_t idx)
  974. {
  975. obs_data_t *data;
  976. if (!array)
  977. return NULL;
  978. data = (idx < array->objects.num) ? array->objects.array[idx] : NULL;
  979. if (data)
  980. os_atomic_inc_long(&data->ref);
  981. return data;
  982. }
  983. size_t obs_data_array_push_back(obs_data_array_t *array, obs_data_t *obj)
  984. {
  985. if (!array || !obj)
  986. return 0;
  987. os_atomic_inc_long(&obj->ref);
  988. return da_push_back(array->objects, &obj);
  989. }
  990. void obs_data_array_insert(obs_data_array_t *array, size_t idx, obs_data_t *obj)
  991. {
  992. if (!array || !obj)
  993. return;
  994. os_atomic_inc_long(&obj->ref);
  995. da_insert(array->objects, idx, &obj);
  996. }
  997. void obs_data_array_erase(obs_data_array_t *array, size_t idx)
  998. {
  999. if (array) {
  1000. obs_data_release(array->objects.array[idx]);
  1001. da_erase(array->objects, idx);
  1002. }
  1003. }
  1004. /* ------------------------------------------------------------------------- */
  1005. /* Item status inspection */
  1006. bool obs_data_has_user_value(obs_data_t *data, const char *name)
  1007. {
  1008. return data && obs_data_item_has_user_value(get_item(data, name));
  1009. }
  1010. bool obs_data_has_default_value(obs_data_t *data, const char *name)
  1011. {
  1012. return data && obs_data_item_has_default_value(get_item(data, name));
  1013. }
  1014. bool obs_data_has_autoselect_value(obs_data_t *data, const char *name)
  1015. {
  1016. return data && obs_data_item_has_autoselect_value(get_item(data, name));
  1017. }
  1018. bool obs_data_item_has_user_value(obs_data_item_t *item)
  1019. {
  1020. return item && item->data_size;
  1021. }
  1022. bool obs_data_item_has_default_value(obs_data_item_t *item)
  1023. {
  1024. return item && item->default_size;
  1025. }
  1026. bool obs_data_item_has_autoselect_value(obs_data_item_t *item)
  1027. {
  1028. return item && item->autoselect_size;
  1029. }
  1030. /* ------------------------------------------------------------------------- */
  1031. /* Clearing data values */
  1032. void obs_data_unset_user_value(obs_data_t *data, const char *name)
  1033. {
  1034. obs_data_item_unset_user_value(get_item(data, name));
  1035. }
  1036. void obs_data_unset_default_value(obs_data_t *data, const char *name)
  1037. {
  1038. obs_data_item_unset_default_value(get_item(data, name));
  1039. }
  1040. void obs_data_unset_autoselect_value(obs_data_t *data, const char *name)
  1041. {
  1042. obs_data_item_unset_autoselect_value(get_item(data, name));
  1043. }
  1044. void obs_data_item_unset_user_value(obs_data_item_t *item)
  1045. {
  1046. if (!item || !item->data_size)
  1047. return;
  1048. void *old_non_user_data = get_default_data_ptr(item);
  1049. item_data_release(item);
  1050. item->data_size = 0;
  1051. item->data_len = 0;
  1052. if (item->default_size || item->autoselect_size)
  1053. move_data(item, old_non_user_data, item,
  1054. get_default_data_ptr(item),
  1055. item->default_len + item->autoselect_size);
  1056. }
  1057. void obs_data_item_unset_default_value(obs_data_item_t *item)
  1058. {
  1059. if (!item || !item->default_size)
  1060. return;
  1061. void *old_autoselect_data = get_autoselect_data_ptr(item);
  1062. item_default_data_release(item);
  1063. item->default_size = 0;
  1064. item->default_len = 0;
  1065. if (item->autoselect_size)
  1066. move_data(item, old_autoselect_data, item,
  1067. get_autoselect_data_ptr(item),
  1068. item->autoselect_size);
  1069. }
  1070. void obs_data_item_unset_autoselect_value(obs_data_item_t *item)
  1071. {
  1072. if (!item || !item->autoselect_size)
  1073. return;
  1074. item_autoselect_data_release(item);
  1075. item->autoselect_size = 0;
  1076. }
  1077. /* ------------------------------------------------------------------------- */
  1078. /* Item iteration */
  1079. obs_data_item_t *obs_data_first(obs_data_t *data)
  1080. {
  1081. if (!data)
  1082. return NULL;
  1083. if (data->first_item)
  1084. os_atomic_inc_long(&data->first_item->ref);
  1085. return data->first_item;
  1086. }
  1087. obs_data_item_t *obs_data_item_byname(obs_data_t *data, const char *name)
  1088. {
  1089. if (!data)
  1090. return NULL;
  1091. struct obs_data_item *item = get_item(data, name);
  1092. if (item)
  1093. os_atomic_inc_long(&item->ref);
  1094. return item;
  1095. }
  1096. bool obs_data_item_next(obs_data_item_t **item)
  1097. {
  1098. if (item && *item) {
  1099. obs_data_item_t *next = (*item)->next;
  1100. obs_data_item_release(item);
  1101. *item = next;
  1102. if (next) {
  1103. os_atomic_inc_long(&next->ref);
  1104. return true;
  1105. }
  1106. }
  1107. return false;
  1108. }
  1109. void obs_data_item_release(obs_data_item_t **item)
  1110. {
  1111. if (item && *item) {
  1112. long ref = os_atomic_dec_long(&(*item)->ref);
  1113. if (!ref) {
  1114. obs_data_item_destroy(*item);
  1115. *item = NULL;
  1116. }
  1117. }
  1118. }
  1119. void obs_data_item_remove(obs_data_item_t **item)
  1120. {
  1121. if (item && *item) {
  1122. obs_data_item_detach(*item);
  1123. obs_data_item_release(item);
  1124. }
  1125. }
  1126. enum obs_data_type obs_data_item_gettype(obs_data_item_t *item)
  1127. {
  1128. return item ? item->type : OBS_DATA_NULL;
  1129. }
  1130. enum obs_data_number_type obs_data_item_numtype(obs_data_item_t *item)
  1131. {
  1132. struct obs_data_number *num;
  1133. if (!item || item->type != OBS_DATA_NUMBER)
  1134. return OBS_DATA_NUM_INVALID;
  1135. num = get_item_data(item);
  1136. return num->type;
  1137. }
  1138. void obs_data_item_set_string(obs_data_item_t **item, const char *val)
  1139. {
  1140. obs_set_string(NULL, item, NULL, val, set_item);
  1141. }
  1142. void obs_data_item_set_int(obs_data_item_t **item, long long val)
  1143. {
  1144. obs_set_int(NULL, item, NULL, val, set_item);
  1145. }
  1146. void obs_data_item_set_double(obs_data_item_t **item, double val)
  1147. {
  1148. obs_set_double(NULL, item, NULL, val, set_item);
  1149. }
  1150. void obs_data_item_set_bool(obs_data_item_t **item, bool val)
  1151. {
  1152. obs_set_bool(NULL, item, NULL, val, set_item);
  1153. }
  1154. void obs_data_item_set_obj(obs_data_item_t **item, obs_data_t *val)
  1155. {
  1156. obs_set_obj(NULL, item, NULL, val, set_item);
  1157. }
  1158. void obs_data_item_set_array(obs_data_item_t **item, obs_data_array_t *val)
  1159. {
  1160. obs_set_array(NULL, item, NULL, val, set_item);
  1161. }
  1162. void obs_data_item_set_default_string(obs_data_item_t **item, const char *val)
  1163. {
  1164. obs_set_string(NULL, item, NULL, val, set_item_def);
  1165. }
  1166. void obs_data_item_set_default_int(obs_data_item_t **item, long long val)
  1167. {
  1168. obs_set_int(NULL, item, NULL, val, set_item_def);
  1169. }
  1170. void obs_data_item_set_default_double(obs_data_item_t **item, double val)
  1171. {
  1172. obs_set_double(NULL, item, NULL, val, set_item_def);
  1173. }
  1174. void obs_data_item_set_default_bool(obs_data_item_t **item, bool val)
  1175. {
  1176. obs_set_bool(NULL, item, NULL, val, set_item_def);
  1177. }
  1178. void obs_data_item_set_default_obj(obs_data_item_t **item, obs_data_t *val)
  1179. {
  1180. obs_set_obj(NULL, item, NULL, val, set_item_def);
  1181. }
  1182. void obs_data_item_set_default_array(obs_data_item_t **item,
  1183. obs_data_array_t *val)
  1184. {
  1185. obs_set_array(NULL, item, NULL, val, set_item_def);
  1186. }
  1187. void obs_data_item_set_autoselect_string(obs_data_item_t **item, const char *val)
  1188. {
  1189. obs_set_string(NULL, item, NULL, val, set_item_auto);
  1190. }
  1191. void obs_data_item_set_autoselect_int(obs_data_item_t **item, long long val)
  1192. {
  1193. obs_set_int(NULL, item, NULL, val, set_item_auto);
  1194. }
  1195. void obs_data_item_set_autoselect_double(obs_data_item_t **item, double val)
  1196. {
  1197. obs_set_double(NULL, item, NULL, val, set_item_auto);
  1198. }
  1199. void obs_data_item_set_autoselect_bool(obs_data_item_t **item, bool val)
  1200. {
  1201. obs_set_bool(NULL, item, NULL, val, set_item_auto);
  1202. }
  1203. void obs_data_item_set_autoselect_obj(obs_data_item_t **item, obs_data_t *val)
  1204. {
  1205. obs_set_obj(NULL, item, NULL, val, set_item_auto);
  1206. }
  1207. void obs_data_item_set_autoselect_array(obs_data_item_t **item,
  1208. obs_data_array_t *val)
  1209. {
  1210. obs_set_array(NULL, item, NULL, val, set_item_auto);
  1211. }
  1212. static inline bool item_valid(struct obs_data_item *item,
  1213. enum obs_data_type type)
  1214. {
  1215. return item && item->type == type;
  1216. }
  1217. typedef void *(*get_data_t)(obs_data_item_t*);
  1218. static inline const char *data_item_get_string(obs_data_item_t *item,
  1219. get_data_t get_data)
  1220. {
  1221. return item_valid(item, OBS_DATA_STRING) && get_data(item) ?
  1222. get_data(item) : "";
  1223. }
  1224. static inline long long item_int(struct obs_data_item *item,
  1225. get_data_t get_data)
  1226. {
  1227. if (item && get_data(item)) {
  1228. struct obs_data_number *num = get_data(item);
  1229. return (num->type == OBS_DATA_NUM_INT) ?
  1230. num->int_val : (long long)num->double_val;
  1231. }
  1232. return 0;
  1233. }
  1234. static inline long long data_item_get_int(obs_data_item_t *item,
  1235. get_data_t get_data)
  1236. {
  1237. return item_int(item_valid(item, OBS_DATA_NUMBER) ? item : NULL,
  1238. get_data);
  1239. }
  1240. static inline double item_double(struct obs_data_item *item,
  1241. get_data_t get_data)
  1242. {
  1243. if (item && get_data(item)) {
  1244. struct obs_data_number *num = get_data(item);
  1245. return (num->type == OBS_DATA_NUM_INT) ?
  1246. (double)num->int_val : num->double_val;
  1247. }
  1248. return 0.0;
  1249. }
  1250. static inline double data_item_get_double(obs_data_item_t *item,
  1251. get_data_t get_data)
  1252. {
  1253. return item_double(item_valid(item, OBS_DATA_NUMBER) ? item : NULL,
  1254. get_data);
  1255. }
  1256. static inline bool data_item_get_bool(obs_data_item_t *item, get_data_t get_data)
  1257. {
  1258. return item_valid(item, OBS_DATA_BOOLEAN) && get_data(item) ?
  1259. *(bool*)get_data(item) : false;
  1260. }
  1261. typedef obs_data_t *(*get_obj_t)(obs_data_item_t*);
  1262. static inline obs_data_t *data_item_get_obj(obs_data_item_t *item,
  1263. get_obj_t get_obj)
  1264. {
  1265. obs_data_t *obj = item_valid(item, OBS_DATA_OBJECT) ?
  1266. get_obj(item) : NULL;
  1267. if (obj)
  1268. os_atomic_inc_long(&obj->ref);
  1269. return obj;
  1270. }
  1271. typedef obs_data_array_t *(*get_array_t)(obs_data_item_t*);
  1272. static inline obs_data_array_t *data_item_get_array(obs_data_item_t *item,
  1273. get_array_t get_array)
  1274. {
  1275. obs_data_array_t *array = item_valid(item, OBS_DATA_ARRAY) ?
  1276. get_array(item) : NULL;
  1277. if (array)
  1278. os_atomic_inc_long(&array->ref);
  1279. return array;
  1280. }
  1281. const char *obs_data_item_get_string(obs_data_item_t *item)
  1282. {
  1283. return data_item_get_string(item, get_item_data);
  1284. }
  1285. long long obs_data_item_get_int(obs_data_item_t *item)
  1286. {
  1287. return data_item_get_int(item, get_item_data);
  1288. }
  1289. double obs_data_item_get_double(obs_data_item_t *item)
  1290. {
  1291. return data_item_get_double(item, get_item_data);
  1292. }
  1293. bool obs_data_item_get_bool(obs_data_item_t *item)
  1294. {
  1295. return data_item_get_bool(item, get_item_data);
  1296. }
  1297. obs_data_t *obs_data_item_get_obj(obs_data_item_t *item)
  1298. {
  1299. return data_item_get_obj(item, get_item_obj);
  1300. }
  1301. obs_data_array_t *obs_data_item_get_array(obs_data_item_t *item)
  1302. {
  1303. return data_item_get_array(item, get_item_array);
  1304. }
  1305. const char *obs_data_item_get_default_string(obs_data_item_t *item)
  1306. {
  1307. return data_item_get_string(item, get_item_default_data);
  1308. }
  1309. long long obs_data_item_get_default_int(obs_data_item_t *item)
  1310. {
  1311. return data_item_get_int(item, get_item_default_data);
  1312. }
  1313. double obs_data_item_get_default_double(obs_data_item_t *item)
  1314. {
  1315. return data_item_get_double(item, get_item_default_data);
  1316. }
  1317. bool obs_data_item_get_default_bool(obs_data_item_t *item)
  1318. {
  1319. return data_item_get_bool(item, get_item_default_data);
  1320. }
  1321. obs_data_t *obs_data_item_get_default_obj(obs_data_item_t *item)
  1322. {
  1323. return data_item_get_obj(item, get_item_obj);
  1324. }
  1325. obs_data_array_t *obs_data_item_get_default_array(obs_data_item_t *item)
  1326. {
  1327. return data_item_get_array(item, get_item_array);
  1328. }
  1329. const char *obs_data_item_get_autoselect_string(obs_data_item_t *item)
  1330. {
  1331. return data_item_get_string(item, get_item_autoselect_data);
  1332. }
  1333. long long obs_data_item_get_autoselect_int(obs_data_item_t *item)
  1334. {
  1335. return data_item_get_int(item, get_item_autoselect_data);
  1336. }
  1337. double obs_data_item_get_autoselect_double(obs_data_item_t *item)
  1338. {
  1339. return data_item_get_double(item, get_item_autoselect_data);
  1340. }
  1341. bool obs_data_item_get_autoselect_bool(obs_data_item_t *item)
  1342. {
  1343. return data_item_get_bool(item, get_item_autoselect_data);
  1344. }
  1345. obs_data_t *obs_data_item_get_autoselect_obj(obs_data_item_t *item)
  1346. {
  1347. return data_item_get_obj(item, get_item_autoselect_obj);
  1348. }
  1349. obs_data_array_t *obs_data_item_get_autoselect_array(obs_data_item_t *item)
  1350. {
  1351. return data_item_get_array(item, get_item_autoselect_array);
  1352. }
  1353. /* ------------------------------------------------------------------------- */
  1354. /* Helper functions for certain structures */
  1355. typedef void (*set_obj_t)(obs_data_t*, const char*, obs_data_t*);
  1356. static inline void set_vec2(obs_data_t *data, const char *name,
  1357. const struct vec2 *val, set_obj_t set_obj)
  1358. {
  1359. obs_data_t *obj = obs_data_create();
  1360. obs_data_set_double(obj, "x", val->x);
  1361. obs_data_set_double(obj, "y", val->y);
  1362. set_obj(data, name, obj);
  1363. obs_data_release(obj);
  1364. }
  1365. static inline void set_vec3(obs_data_t *data, const char *name,
  1366. const struct vec3 *val, set_obj_t set_obj)
  1367. {
  1368. obs_data_t *obj = obs_data_create();
  1369. obs_data_set_double(obj, "x", val->x);
  1370. obs_data_set_double(obj, "y", val->y);
  1371. obs_data_set_double(obj, "z", val->z);
  1372. set_obj(data, name, obj);
  1373. obs_data_release(obj);
  1374. }
  1375. static inline void set_vec4(obs_data_t *data, const char *name,
  1376. const struct vec4 *val, set_obj_t set_obj)
  1377. {
  1378. obs_data_t *obj = obs_data_create();
  1379. obs_data_set_double(obj, "x", val->x);
  1380. obs_data_set_double(obj, "y", val->y);
  1381. obs_data_set_double(obj, "z", val->z);
  1382. obs_data_set_double(obj, "w", val->w);
  1383. set_obj(data, name, obj);
  1384. obs_data_release(obj);
  1385. }
  1386. static inline void set_quat(obs_data_t *data, const char *name,
  1387. const struct quat *val, set_obj_t set_obj)
  1388. {
  1389. obs_data_t *obj = obs_data_create();
  1390. obs_data_set_double(obj, "x", val->x);
  1391. obs_data_set_double(obj, "y", val->y);
  1392. obs_data_set_double(obj, "z", val->z);
  1393. obs_data_set_double(obj, "w", val->w);
  1394. set_obj(data, name, obj);
  1395. obs_data_release(obj);
  1396. }
  1397. void obs_data_set_vec2(obs_data_t *data, const char *name,
  1398. const struct vec2 *val)
  1399. {
  1400. set_vec2(data, name, val, obs_data_set_obj);
  1401. }
  1402. void obs_data_set_vec3(obs_data_t *data, const char *name,
  1403. const struct vec3 *val)
  1404. {
  1405. set_vec3(data, name, val, obs_data_set_obj);
  1406. }
  1407. void obs_data_set_vec4(obs_data_t *data, const char *name,
  1408. const struct vec4 *val)
  1409. {
  1410. set_vec4(data, name, val, obs_data_set_obj);
  1411. }
  1412. void obs_data_set_quat(obs_data_t *data, const char *name,
  1413. const struct quat *val)
  1414. {
  1415. set_quat(data, name, val, obs_data_set_obj);
  1416. }
  1417. void obs_data_set_default_vec2(obs_data_t *data, const char *name,
  1418. const struct vec2 *val)
  1419. {
  1420. set_vec2(data, name, val, obs_data_set_default_obj);
  1421. }
  1422. void obs_data_set_default_vec3(obs_data_t *data, const char *name,
  1423. const struct vec3 *val)
  1424. {
  1425. set_vec3(data, name, val, obs_data_set_default_obj);
  1426. }
  1427. void obs_data_set_default_vec4(obs_data_t *data, const char *name,
  1428. const struct vec4 *val)
  1429. {
  1430. set_vec4(data, name, val, obs_data_set_default_obj);
  1431. }
  1432. void obs_data_set_default_quat(obs_data_t *data, const char *name,
  1433. const struct quat *val)
  1434. {
  1435. set_quat(data, name, val, obs_data_set_default_obj);
  1436. }
  1437. void obs_data_set_autoselect_vec2(obs_data_t *data, const char *name,
  1438. const struct vec2 *val)
  1439. {
  1440. set_vec2(data, name, val, obs_data_set_autoselect_obj);
  1441. }
  1442. void obs_data_set_autoselect_vec3(obs_data_t *data, const char *name,
  1443. const struct vec3 *val)
  1444. {
  1445. set_vec3(data, name, val, obs_data_set_autoselect_obj);
  1446. }
  1447. void obs_data_set_autoselect_vec4(obs_data_t *data, const char *name,
  1448. const struct vec4 *val)
  1449. {
  1450. set_vec4(data, name, val, obs_data_set_autoselect_obj);
  1451. }
  1452. void obs_data_set_autoselect_quat(obs_data_t *data, const char *name,
  1453. const struct quat *val)
  1454. {
  1455. set_quat(data, name, val, obs_data_set_autoselect_obj);
  1456. }
  1457. static inline void get_vec2(obs_data_t *obj, struct vec2 *val)
  1458. {
  1459. if (!obj) return;
  1460. val->x = (float)obs_data_get_double(obj, "x");
  1461. val->y = (float)obs_data_get_double(obj, "y");
  1462. obs_data_release(obj);
  1463. }
  1464. static inline void get_vec3(obs_data_t *obj, struct vec3 *val)
  1465. {
  1466. if (!obj) return;
  1467. val->x = (float)obs_data_get_double(obj, "x");
  1468. val->y = (float)obs_data_get_double(obj, "y");
  1469. val->z = (float)obs_data_get_double(obj, "z");
  1470. obs_data_release(obj);
  1471. }
  1472. static inline void get_vec4(obs_data_t *obj, struct vec4 *val)
  1473. {
  1474. if (!obj) return;
  1475. val->x = (float)obs_data_get_double(obj, "x");
  1476. val->y = (float)obs_data_get_double(obj, "y");
  1477. val->z = (float)obs_data_get_double(obj, "z");
  1478. val->w = (float)obs_data_get_double(obj, "w");
  1479. obs_data_release(obj);
  1480. }
  1481. static inline void get_quat(obs_data_t *obj, struct quat *val)
  1482. {
  1483. if (!obj) return;
  1484. val->x = (float)obs_data_get_double(obj, "x");
  1485. val->y = (float)obs_data_get_double(obj, "y");
  1486. val->z = (float)obs_data_get_double(obj, "z");
  1487. val->w = (float)obs_data_get_double(obj, "w");
  1488. obs_data_release(obj);
  1489. }
  1490. void obs_data_get_vec2(obs_data_t *data, const char *name, struct vec2 *val)
  1491. {
  1492. get_vec2(obs_data_get_obj(data, name), val);
  1493. }
  1494. void obs_data_get_vec3(obs_data_t *data, const char *name, struct vec3 *val)
  1495. {
  1496. get_vec3(obs_data_get_obj(data, name), val);
  1497. }
  1498. void obs_data_get_vec4(obs_data_t *data, const char *name, struct vec4 *val)
  1499. {
  1500. get_vec4(obs_data_get_obj(data, name), val);
  1501. }
  1502. void obs_data_get_quat(obs_data_t *data, const char *name, struct quat *val)
  1503. {
  1504. get_quat(obs_data_get_obj(data, name), val);
  1505. }
  1506. void obs_data_get_default_vec2(obs_data_t *data, const char *name,
  1507. struct vec2 *val)
  1508. {
  1509. get_vec2(obs_data_get_default_obj(data, name), val);
  1510. }
  1511. void obs_data_get_default_vec3(obs_data_t *data, const char *name,
  1512. struct vec3 *val)
  1513. {
  1514. get_vec3(obs_data_get_default_obj(data, name), val);
  1515. }
  1516. void obs_data_get_default_vec4(obs_data_t *data, const char *name,
  1517. struct vec4 *val)
  1518. {
  1519. get_vec4(obs_data_get_default_obj(data, name), val);
  1520. }
  1521. void obs_data_get_default_quat(obs_data_t *data, const char *name,
  1522. struct quat *val)
  1523. {
  1524. get_quat(obs_data_get_default_obj(data, name), val);
  1525. }
  1526. void obs_data_get_autoselect_vec2(obs_data_t *data, const char *name,
  1527. struct vec2 *val)
  1528. {
  1529. get_vec2(obs_data_get_autoselect_obj(data, name), val);
  1530. }
  1531. void obs_data_get_autoselect_vec3(obs_data_t *data, const char *name,
  1532. struct vec3 *val)
  1533. {
  1534. get_vec3(obs_data_get_autoselect_obj(data, name), val);
  1535. }
  1536. void obs_data_get_autoselect_vec4(obs_data_t *data, const char *name,
  1537. struct vec4 *val)
  1538. {
  1539. get_vec4(obs_data_get_autoselect_obj(data, name), val);
  1540. }
  1541. void obs_data_get_autoselect_quat(obs_data_t *data, const char *name,
  1542. struct quat *val)
  1543. {
  1544. get_quat(obs_data_get_autoselect_obj(data, name), val);
  1545. }