Exemple #1
0
static bool TinyHashInsertElement(AssocHashTable *hashtable, const char *element, Rval rval, enum cfdatatype dtype)
{
    int i;

    if (hashtable->array.size == TINY_LIMIT)
    {
        HashConvertToHuge(hashtable);
        return HugeHashInsertElement(hashtable, element, rval, dtype);
    }

    for (i = 0; i < hashtable->array.size; ++i)
    {
        if (strcmp(hashtable->array.values[i]->lval, element) == 0)
        {
            return false;
        }
    }

    /* Do not inline NewAssoc into a assignment -- NewAssoc calls CopyRvalItem,
       which can call GetVariable (OMG), which calls HashLookupElement, so we
       need to be sure hash table is in consistent state while calling
       NewAssoc. If NewAssoc is in the right-hand side of the assignment, then
       compiler is free to choose the order of increment and NewAssoc call, so
       HashLookupElement might end up reading values by NULL pointer. Long-term
       solution is to fix CopyRvalItem. */

    CfAssoc *a = NewAssoc(element, rval, dtype);

    hashtable->array.values[hashtable->array.size++] = a;
    return true;
}
void Dictionary::SetAt(const ieResRef key, unsigned int type, unsigned int value)
{
	int i;
	unsigned int nHash;
	MyAssoc* pAssoc=GetAssocAt( key, type, nHash );

	if (pAssoc == NULL) {
		if (m_pHashTable == NULL)
			InitHashTable( m_nHashTableSize );

		// it doesn't exist, add a new Association
		pAssoc = NewAssoc();
		// put into hash table
		pAssoc->pNext = m_pHashTable[nHash];
		m_pHashTable[nHash] = pAssoc;
	}
	for(i=0;i<KEYSIZE && key[i];i++) {
		pAssoc->key[i]=tolower(key[i]);
	}
	for(;i<KEYSIZE;i++) {
		pAssoc->key[i]=0;
	}
	pAssoc->type = type;
	pAssoc->value = value;
}
Exemple #3
0
static bool HugeHashInsertElement(AssocHashTable *hashtable, const char *element, Rval rval, enum cfdatatype dtype)
{
    int bucket = GetHash(element);
    int i = bucket;

    do
    {
        /* Free bucket is found */
        if (hashtable->buckets[i] == NULL || hashtable->buckets[i] == HASH_ENTRY_DELETED)
        {
            hashtable->buckets[i] = NewAssoc(element, rval, dtype);
            return true;
        }

        /* Collision -- this element already exists */
        if (strcmp(element, hashtable->buckets[i]->lval) == 0)
        {
            return false;
        }

        i = (i + 1) % CF_HASHTABLESIZE;
    }
    while (i != bucket);

/* Hash table is full */
    return false;
}
Exemple #4
0
CfAssoc *CopyAssoc(CfAssoc *old)
{
    if (old == NULL)
    {
        return NULL;
    }

    return NewAssoc(old->lval, old->rval, old->dtype);
}
Exemple #5
0
PromiseIterator *PromiseIteratorNew(EvalContext *ctx, const Promise *pp, const Rlist *lists, const Rlist *containers)
{
    PromiseIterator *iter = xmalloc(sizeof(PromiseIterator));

    iter->vars = SeqNew(RlistLen(lists), DeleteAssoc);
    iter->var_states = SeqNew(RlistLen(lists), NULL);
    iter->has_null_list = false;

    for (const Rlist *rp = lists; rp != NULL; rp = rp->next)
    {
        VarRef *ref = VarRefParseFromBundle(RlistScalarValue(rp), PromiseGetBundle(pp));

        DataType dtype = CF_DATA_TYPE_NONE;
        const void *value = EvalContextVariableGet(ctx, ref, &dtype);
        if (!value)
        {
            Log(LOG_LEVEL_ERR, "Couldn't locate variable '%s' apparently in '%s'", RlistScalarValue(rp), PromiseGetBundle(pp)->name);
            VarRefDestroy(ref);
            continue;
        }

        VarRefDestroy(ref);

        CfAssoc *new_var = NewAssoc(RlistScalarValue(rp), (Rval) { (void *)value, DataTypeToRvalType(dtype) }, dtype);
        iter->has_null_list |= !AppendIterationVariable(iter, new_var);
    }

    for (const Rlist *rp = containers; rp; rp = rp->next)
    {
        VarRef *ref = VarRefParseFromBundle(RlistScalarValue(rp), PromiseGetBundle(pp));

        DataType dtype = CF_DATA_TYPE_NONE;
        const JsonElement *value = EvalContextVariableGet(ctx, ref, &dtype);
        if (!value)
        {
            Log(LOG_LEVEL_ERR, "Couldn't locate variable '%s' apparently in '%s'", RlistScalarValue(rp), PromiseGetBundle(pp)->name);
            VarRefDestroy(ref);
            continue;
        }

        VarRefDestroy(ref);

        assert(dtype == CF_DATA_TYPE_CONTAINER);

        /* Mimics NewAssoc() but bypassing extra copying of ->rval: */
        CfAssoc *new_var = xmalloc(sizeof(CfAssoc));
        new_var->lval = xstrdup(RlistScalarValue(rp));
        new_var->rval = (Rval) { ContainerToRlist(value), RVAL_TYPE_LIST };
        new_var->dtype = CF_DATA_TYPE_STRING_LIST;

        iter->has_null_list |= !AppendIterationVariable(iter, new_var);
    }

    // We now have a control list of list-variables, with internal state in state_ptr
    return iter;
}
Exemple #6
0
static void test_copy(void **state)
{
    CfAssoc *ap = NewAssoc("hello", (Rval) { "world", CF_SCALAR }, cf_str);
    CfAssoc *ap2 = CopyAssoc(ap);

    assert_string_equal(ap->lval, ap2->lval);
    assert_string_equal(ap->rval.item, ap2->rval.item);
    assert_int_equal(ap->rval.rtype, ap2->rval.rtype);
    assert_int_equal(ap->dtype, ap2->dtype);

    DeleteAssoc(ap);
    DeleteAssoc(ap2);
}
Exemple #7
0
char& CMapDWORDToChar::operator[](DWORD key)
{
	ASSERT_VALID(this);

	UINT nHash;
	CAssoc* pAssoc;
	if ((pAssoc = GetAssocAt(key, nHash)) == NULL)
	{
		if (m_pHashTable == NULL)
			InitHashTable(m_nHashTableSize);

		// it doesn't exist, add a new Association
		pAssoc = NewAssoc();
		pAssoc->nHashValue = nHash;
		pAssoc->key = key;
		// 'pAssoc->value' is a constructed object, nothing more

		// put into hash table
		pAssoc->pNext = m_pHashTable[nHash];
		m_pHashTable[nHash] = pAssoc;
	}
	return pAssoc->value;  // return new reference
}
Exemple #8
0
static void test_create_destroy(void)
{
    CfAssoc *ap = NewAssoc("hello", (Rval) { "world", RVAL_TYPE_SCALAR }, DATA_TYPE_STRING);
    DeleteAssoc(ap);
}
Exemple #9
0
static void test_create_destroy(void **state)
{
    CfAssoc *ap = NewAssoc("hello", (Rval) { "world", CF_SCALAR }, cf_str);
    DeleteAssoc(ap);
}