RZ_API RZ_OWN RzBinStrDb *rz_bin_string_database_new(RZ_NULLABLE RZ_OWN RzList /*<RzBinString *>*/ *list) {
	RzBinStrDb *db = RZ_NEW0(RzBinStrDb);
	if (!db) {
		RZ_LOG_ERROR("rz_bin: Cannot allocate RzBinStrDb\n");
		rz_list_free(list);
		return NULL;
	}

	db->list = list ? list : rz_list_newf((RzListFree)rz_bin_string_free);
	db->phys = ht_up_new0();
	db->virt = ht_up_new0();
	if (!db->list || !db->phys || !db->virt) {
		RZ_LOG_ERROR("rz_bin: Cannot allocate RzBinStrDb internal data structure.\n");
		goto fail;
	}

	RzListIter *it;
	RzBinString *bstr;
	rz_list_foreach (list, it, bstr) {
		if (!ht_up_update(db->phys, bstr->paddr, bstr)) {
			RZ_LOG_ERROR("rz_bin: Cannot insert/update RzBinString in RzBinStrDb (phys)\n");
			goto fail;
		}
		if (!ht_up_update(db->virt, bstr->vaddr, bstr)) {
			RZ_LOG_ERROR("rz_bin: Cannot insert/update RzBinString in RzBinStrDb (virt)\n");
			goto fail;
		}
	}
	return db;

fail:
	rz_bin_string_database_free(db);
	return NULL;
}
RZ_API RZ_OWN RzBinStrDb *rz_bin_string_database_new(RZ_NULLABLE RZ_OWN RzList   *list) {
	RzBinStrDb *db = RZ_NEW0(RzBinStrDb);
	if (!db) {
		RZ_LOG_ERROR("rz_bin: Cannot allocate RzBinStrDb\n");
		rz_list_free(list);
		return NULL;
	}

	db->list = list ? list : rz_list_newf((RzListFree)rz_bin_string_free);
	db->phys = ht_up_new0();
	db->virt = ht_up_new0();
	if (!db->list || !db->phys || !db->virt) {
		RZ_LOG_ERROR("rz_bin: Cannot allocate RzBinStrDb internal data structure.\n");
		goto fail;
	}

	RzListIter *it;
	RzBinString *bstr;
	rz_list_foreach (list, it, bstr) {
		if (!ht_up_update(db->phys, bstr->paddr, bstr)) {
			RZ_LOG_ERROR("rz_bin: Cannot insert/update RzBinString in RzBinStrDb (phys)\n");
			goto fail;
		}
		if (!ht_up_update(db->virt, bstr->vaddr, bstr)) {
			RZ_LOG_ERROR("rz_bin: Cannot insert/update RzBinString in RzBinStrDb (virt)\n");
			goto fail;
		}
	}
	return db;

fail:
	rz_bin_string_database_free(db);
	return NULL;
}