int hash_insert(struct hash *hash, const char *key, void *mem, free_func *freer) { unsigned i, h; struct hash_bucket *bucket = malloc(sizeof *bucket), *iter; if (!bucket) return -1; bucket->key = string_dup(key); if (!bucket->key) { free(bucket); return -1; } bucket->mem = mem; h = hashstr(key, hash->max_size); for (i = 0; i < hash->buckets[h].length; ++i) { darray_at(&hash->buckets[h], i, (void **)&iter); if (!strcmp(iter->key, bucket->key)) { if (freer) freer(hash->buckets[h].mem[i]); hash->buckets[h].mem[i] = bucket; return 0; } } darray_push_back(&hash->buckets[h], bucket); return 0; }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array; CHECK_REQUIRED_VAL(info, getname, obs_register_source); CHECK_REQUIRED_VAL(info, create, obs_register_source); CHECK_REQUIRED_VAL(info, destroy, obs_register_source); if (info->type == OBS_SOURCE_TYPE_INPUT && info->output_flags & OBS_SOURCE_VIDEO) { CHECK_REQUIRED_VAL(info, getwidth, obs_register_source); CHECK_REQUIRED_VAL(info, getheight, obs_register_source); } memcpy(&data, info, size); if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else { blog(LOG_ERROR, "Tried to register unknown source type: %u", info->type); return; } darray_push_back(sizeof(struct obs_source_info), array, &data); }
static void module_load_exports(struct obs_module *mod, struct darray *output_array, const char *type, const size_t data_size, void *callback_ptr) { bool (*enum_func)(size_t idx, const char **name); bool (*callback)(void*, const char*, const char*, void*); struct dstr enum_name; const char *name; size_t i = 0; callback = callback_ptr; dstr_init_copy(&enum_name, "enum_"); dstr_cat(&enum_name, type); enum_func = os_dlsym(mod->module, enum_name.array); if (!enum_func) goto complete; while (enum_func(i++, &name)) { void *info = bmalloc(data_size); if (!callback(mod->module, mod->name, name, info)) blog(LOG_ERROR, "Couldn't load '%s' because it " "was missing required functions", name); else darray_push_back(data_size, output_array, info); bfree(info); } complete: dstr_free(&enum_name); }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array; if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else { blog(LOG_ERROR, "Tried to register unknown source type: %u", info->type); goto error; } if (find_source(array, info->id)) { blog(LOG_WARNING, "Source d '%s' already exists! " "Duplicate library?", info->id); goto error; } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_source); CHECK_REQUIRED_VAL_(info, create, obs_register_source); CHECK_REQUIRED_VAL_(info, destroy, obs_register_source); if (info->type == OBS_SOURCE_TYPE_INPUT && (info->output_flags & OBS_SOURCE_VIDEO) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); CHECK_REQUIRED_VAL_(info, get_height, obs_register_source); } #undef CHECK_REQUIRED_VAL_ if (size > sizeof(data)) { blog(LOG_ERROR, "Tried to register obs_source_info with size " "%llu which is more than libobs currently " "supports (%llu)", (long long unsigned)size, (long long unsigned)sizeof(data)); goto error; } memcpy(&data, info, size); /* mark audio-only filters as an async filter categorically */ if (data.type == OBS_SOURCE_TYPE_FILTER) { if ((data.output_flags & OBS_SOURCE_VIDEO) == 0) data.output_flags |= OBS_SOURCE_ASYNC; } darray_push_back(sizeof(struct obs_source_info), array, &data); return; error: HANDLE_ERROR(size, obs_source_info, info); }
static void config_add_item(struct darray *items, struct strref *name, struct strref *value) { struct config_item item; item.name = bstrdup_n(name->array, name->len); item.value = bstrdup_n(value->array, value->len); darray_push_back(sizeof(struct config_item), items, &item); }
static int ep_parse_annotations(struct effect_parser *ep, struct darray *annotations) { if (!cf_token_is(&ep->cfp, "<")) { cf_adderror_expecting(&ep->cfp, "<"); goto error; } /* get annotation variables */ while (true) { bool do_break = false; struct ep_param var; ep_param_init(&var, bstrdup(""), bstrdup(""), false, false, false); switch (ep_parse_param_annotation_var(ep, &var)) { case PARSE_UNEXPECTED_CONTINUE: cf_adderror_syntax_error(&ep->cfp); /* Falls through. */ case PARSE_CONTINUE: ep_param_free(&var); continue; case PARSE_UNEXPECTED_BREAK: cf_adderror_syntax_error(&ep->cfp); /* Falls through. */ case PARSE_BREAK: ep_param_free(&var); do_break = true; break; case PARSE_EOF: ep_param_free(&var); goto error; } if (do_break) break; darray_push_back(sizeof(struct ep_param), annotations, &var); } if (!cf_token_is(&ep->cfp, ">")) { cf_adderror_expecting(&ep->cfp, ">"); goto error; } if (!cf_next_valid_token(&ep->cfp)) goto error; return true; error: return false; }
static inline int ep_parse_pass_command_call(struct effect_parser *ep, struct darray *call) { struct cf_token end_token; cf_token_clear(&end_token); while (!cf_token_is(&ep->cfp, ";")) { if (cf_token_is(&ep->cfp, "}")) { cf_adderror_expecting(&ep->cfp, ";"); return PARSE_CONTINUE; } darray_push_back(sizeof(struct cf_token), call, ep->cfp.cur_token); if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; } darray_push_back(sizeof(struct cf_token), call, ep->cfp.cur_token); darray_push_back(sizeof(struct cf_token), call, &end_token); return PARSE_SUCCESS; }
void hash_values(struct hash *hash, struct darray *arr) { unsigned i, j; struct hash_bucket *iter; for (i = 0; i < hash->max_size; ++i) { for (j = 0; j < hash->buckets[i].length; ++j) { darray_at(&hash->buckets[i], j, (void **)&iter); darray_push_back(arr, iter->mem); } } }
static void config_add_item(struct darray *items, struct strref *name, struct strref *value) { struct config_item item; struct dstr item_value; dstr_init_copy_strref(&item_value, value); dstr_replace(&item_value, "\\n", "\n"); dstr_replace(&item_value, "\\r", "\r"); dstr_replace(&item_value, "\\\\", "\\"); item.name = bstrdup_n(name->array, name->len); item.value = item_value.array; darray_push_back(sizeof(struct config_item), items, &item); }
static inline void append_space(struct cf_preprocessor *pp, struct darray *tokens, const struct cf_token *base) { struct cf_token token; strref_set(&token.str, space_filler, 1); token.type = CFTOKEN_SPACETAB; if (base) { token.lex = base->lex; strref_copy(&token.unmerged_str, &base->unmerged_str); } else { token.lex = pp->lex; strref_copy(&token.unmerged_str, &token.str); } darray_push_back(sizeof(struct cf_token), tokens, &token); }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array; if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else { blog(LOG_ERROR, "Tried to register unknown source type: %u", info->type); return; } if (find_source(array, info->id)) { blog(LOG_WARNING, "Source d '%s' already exists! " "Duplicate library?", info->id); return; } CHECK_REQUIRED_VAL(info, get_name, obs_register_source); CHECK_REQUIRED_VAL(info, create, obs_register_source); CHECK_REQUIRED_VAL(info, destroy, obs_register_source); if (info->type == OBS_SOURCE_TYPE_INPUT && (info->output_flags & OBS_SOURCE_VIDEO) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { CHECK_REQUIRED_VAL(info, get_width, obs_register_source); CHECK_REQUIRED_VAL(info, get_height, obs_register_source); } memcpy(&data, info, size); /* mark audio-only filters as an async filter categorically */ if (data.type == OBS_SOURCE_TYPE_FILTER) { if ((data.output_flags & OBS_SOURCE_VIDEO) == 0) data.output_flags |= OBS_SOURCE_ASYNC; } darray_push_back(sizeof(struct obs_source_info), array, &data); }
static void cf_preprocess_addtoken(struct cf_preprocessor *pp, struct darray *dst, /* struct cf_token */ struct cf_token **p_cur_token, const struct cf_token *base, const struct macro_params *params) { struct cf_token *cur_token = *p_cur_token; if (pp->ignore_state) goto ignore; if (!base) base = cur_token; if (cur_token->type == CFTOKEN_NAME) { struct cf_def *def; struct macro_param *param; param = get_macro_param(params, &cur_token->str); if (param) { cf_preprocess_unwrap_param(pp, dst, &cur_token, base, param); goto exit; } def = cf_preprocess_get_def(pp, &cur_token->str); if (def) { cf_preprocess_unwrap_define(pp, dst, &cur_token, base, def, params); goto exit; } } darray_push_back(sizeof(struct cf_token), dst, cur_token); ignore: cur_token++; exit: *p_cur_token = cur_token; }
static inline void append_end_token(struct darray *tokens) { struct cf_token end; cf_token_clear(&end); darray_push_back(sizeof(struct cf_token), tokens, &end); }
void obs_register_source_s(const struct obs_source_info *info, size_t size) { struct obs_source_info data = {0}; struct darray *array = NULL; if (info->type == OBS_SOURCE_TYPE_INPUT) { array = &obs->input_types.da; } else if (info->type == OBS_SOURCE_TYPE_FILTER) { array = &obs->filter_types.da; } else if (info->type == OBS_SOURCE_TYPE_TRANSITION) { array = &obs->transition_types.da; } else if (info->type != OBS_SOURCE_TYPE_SCENE) { source_warn("Tried to register unknown source type: %u", info->type); goto error; } if (get_source_info(info->id)) { source_warn("Source '%s' already exists! " "Duplicate library?", info->id); goto error; } memcpy(&data, info, size); /* mark audio-only filters as an async filter categorically */ if (data.type == OBS_SOURCE_TYPE_FILTER) { if ((data.output_flags & OBS_SOURCE_VIDEO) == 0) data.output_flags |= OBS_SOURCE_ASYNC; } if (data.type == OBS_SOURCE_TYPE_TRANSITION) { if (data.get_width) source_warn("get_width ignored registering " "transition '%s'", data.id); if (data.get_height) source_warn("get_height ignored registering " "transition '%s'", data.id); data.output_flags |= OBS_SOURCE_COMPOSITE | OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW; } if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) { if ((data.output_flags & OBS_SOURCE_AUDIO) != 0) { source_warn("Source '%s': Composite sources " "cannot be audio sources", info->id); goto error; } if ((data.output_flags & OBS_SOURCE_ASYNC) != 0) { source_warn("Source '%s': Composite sources " "cannot be async sources", info->id); goto error; } } #define CHECK_REQUIRED_VAL_(info, val, func) \ CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func) CHECK_REQUIRED_VAL_(info, get_name, obs_register_source); CHECK_REQUIRED_VAL_(info, create, obs_register_source); CHECK_REQUIRED_VAL_(info, destroy, obs_register_source); if (info->type != OBS_SOURCE_TYPE_FILTER && info->type != OBS_SOURCE_TYPE_TRANSITION && (info->output_flags & OBS_SOURCE_VIDEO) != 0 && (info->output_flags & OBS_SOURCE_ASYNC) == 0) { CHECK_REQUIRED_VAL_(info, get_width, obs_register_source); CHECK_REQUIRED_VAL_(info, get_height, obs_register_source); } if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) { CHECK_REQUIRED_VAL_(info, audio_render, obs_register_source); } #undef CHECK_REQUIRED_VAL_ if (size > sizeof(data)) { source_warn("Tried to register obs_source_info with size " "%llu which is more than libobs currently " "supports (%llu)", (long long unsigned)size, (long long unsigned)sizeof(data)); goto error; } if (array) darray_push_back(sizeof(struct obs_source_info), array, &data); da_push_back(obs->source_types, &data); return; error: HANDLE_ERROR(size, obs_source_info, info); }
static inline void add_attrib(struct darray *list, int attrib, int val) { darray_push_back(sizeof(int), list, &attrib); darray_push_back(sizeof(int), list, &val); }