Пример #1
0
/**
 * qhasharr->remove_by_idx(): Remove an object from this table by index number.
 *
 * @param tbl       qhasharr_t container pointer.
 * @param idx       slot index number
 *
 * @return true if successful, otherwise(not found) returns false
 * @retval errno will be set in error condition.
 *  - ENOENT    : Index is not pointing a valid object.
 *  - EINVAL    : Invald argument.
 *  - EFAULT    : Unexpected error. Data structure is not constant.
 *
 * @code
 *  int idx = 0;
 *  qhasharr_obj_t obj;
 *  while(tbl->getnext(tbl, &obj, &idx) == true) {
 *    if (condition_to_remove) {
 *      idx--;  // adjust index by -1
 *      remove_by_idx(idx);
 *    }
 *    free(obj.name);
 *    free(obj.data);
 *  }
 * @endcode
 *
 * @note
 * This function is to remove an object in getnext() traversal loop without
 * knowing the object name but index value. When key names are longer than
 * defined size, the keys are stored with truncation with their fingerprint,
 * so this method provides a way to remove those keys.
 * getnext() returns actual index + 1(pointing next slot of current finding),
 * so you need to adjust it by -1 for the valid index number. And once you
 * remove object by this method, rewind idx by -1 before calling getnext()
 * because collision objects can be moved back to removed index again, so
 * by adjusting index by -1, getnext() can continue search from the removed
 * slot index again. Please refer an example code.
 */
bool qhasharr_remove_by_idx(qhasharr_t *tbl, int idx) {
    if (idx < 0) {
        errno = EINVAL;
        return false;
    }

    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    if (tblslots[idx].count == 1) {
        // just remove
        remove_data(tbl, idx);
    } else if (tblslots[idx].count > 1) {  // leading slot and has collision
        // find the collision key
        int idx2;
        for (idx2 = idx + 1;; idx2++) {
            if (idx2 >= tbldata->maxslots)
                idx2 = 0;
            if (idx2 == idx) {
                errno = EFAULT;
                return false;
            }
            if (tblslots[idx2].count == COLLISION_MARK
                    && tblslots[idx2].hash == tblslots[idx].hash) {
                break;
            }
        }

        // move to leading slot
        int backupcount = tblslots[idx].count;
        remove_data(tbl, idx);  // remove leading data
        copy_slot(tbl, idx, idx2);  // copy slot
        remove_slot(tbl, idx2);  // remove moved slot

        tblslots[idx].count = backupcount - 1;  // adjust collision counter
        if (tblslots[idx].link != -1) {
            tblslots[tblslots[idx].link].hash = idx;
        }

    } else if (tblslots[idx].count == COLLISION_MARK) {  // collision key
        // decrease counter from leading slot
        if (tblslots[tblslots[idx].hash].count <= 1) {
            errno = EFAULT;
            return false;
        }
        tblslots[tblslots[idx].hash].count--;

        // remove data
        remove_data(tbl, idx);
    } else {
        errno = ENOENT;
        return false;
    }

    return true;
}
Пример #2
0
int
main(void)
{
	struct linked_list l = { .head = NULL };
	append(&l, 4.5);
	append(&l, 2.5);
	append(&l, 6);
	remove_data(&l, 2.5);
	append(&l, 4.5);
	append(&l, 9);
	remove_data(&l, 4.5);
	print(&l);
	free_list(&l);
	return 0;
}
Пример #3
0
/*
 * The last few bytes of the image look like the following:
 *
 *  \0version\0vendore_name\0product_namechksum
 *	the chksum is 16bits wide, and the version is no more than 20bytes.
 *
 * version is w.x.y[nz], where n is ubpi, and w, x, y and z are 1 or 2 digit
 * numbers.
 *
 */
int check_vendor(char *vendorName, char *productName, char *version)
{
	struct fileblock_t *currBlock;
	int versionInfo;
	char *cp;
	char imageVendorName[MAX_VENDOR_SIZE];
	char imageProductName[MAX_PRODUCT_SIZE];
	char imageVersion[MAX_VERSION_SIZE];

	/*
	 * Point to what should be the last byte in the product name string.
	 */
	if (fileblocks == NULL)
		return 5;
	for (currBlock = fileblocks; currBlock->next; currBlock = currBlock->next);
	cp = currBlock->data + currBlock->length - 1;

	/*
	 * Now try to get the vendor/product/version strings, from the end
	 * of the image
	 */
	cp = get_string(&currBlock, cp, imageProductName, MAX_PRODUCT_SIZE);
	if (cp == NULL)
		return 5;

	cp = get_string(&currBlock, cp, imageVendorName, MAX_VENDOR_SIZE);
	if (cp == NULL)
		return 5;

	cp = get_string(&currBlock, cp, imageVersion, MAX_VERSION_SIZE);
	if (cp == NULL)
		return 5;
#ifdef CONFIG_PROP_LOGD_LOGD
	memcpy(new_image_version, imageVersion, MAX_VERSION_SIZE);
	new_image_version[MAX_VERSION_SIZE] = '\0';
#endif

	/* Looks like there was versioning information there, strip it off
	 * now so that we don't write it to flash, or try to decompress it, etc */
	remove_data(strlen(imageProductName) + strlen(imageVendorName) + strlen(imageVersion) + 3);

	/*
	 * Check the product name.
	 */
	if (strcmp(productName, imageProductName) != 0)
		return 1;

	/*
	 * Check the vendor name.
	 */
	if (strcmp(vendorName, imageVendorName) != 0)
		return 2;

	/*
	 * Check the version number.
	 */
	versionInfo = check_version_info(version, imageVersion);

	return versionInfo;
}
Пример #4
0
int main(int argc, char const *argv[])
{
	list_t *list = (list_t*)malloc(sizeof (list_t));
	init(list);

	//make a node
	add_at(list, (void*)2, 0);
	assert(list->head && list->tail);
	assert((int) get(list, 0) == 2);
	//do more adding
	int i = 3;
	for(; i < 15; ++i){
		add_front(list, (void*)i);
		assert(list->head && list->tail);
		assert((int) get(list, 0) == i);
	}
	assert((int) get(list, list->size - 1) == 2);
	assert((int) fold_left(list, add_list, (void*)0) == 104);
	assert((int) fold_left(list, add_list, (void*)0) == (int)fold_right(list, add_list, (void*)0));
	add_back(list, (void*)0);
	assert(list->tail->data == (void*)0);
	assert((int) get(list, list->size - 1) == 0);
	add_front(list, (void*)2);
	add_front(list, (void*)2);
	assert((int) fold_left(list, count_2, (void*)0) == 3);
	remove_data(list, (void*)2, is_2);
	return 0;
}
Пример #5
0
void
test_crud(void)
{
    cut_assert_create();

    add_data(1, 1, "API.JA");
    add_data(2, 1, "CHECKINSTALL.JA");
    add_data(3, 1, "FUTUREWORKS.JA");
    add_data(4, 1, "INSTALL.JA");
    gcut_assert_equal_list_string(gcut_take_new_list_string("1", "2", "3", NULL),
                                  retrieve_record_ids("検索"));

    remove_data(1, 1, "API.JA");
    gcut_assert_equal_list_string(gcut_take_new_list_string("2", "3", NULL),
                                  retrieve_record_ids("検索"));

    update_data(3, 1, "FUTUREWORKS.JA", "Makefile.am");
    gcut_assert_equal_list_string(gcut_take_new_list_string("2", NULL),
                                  retrieve_record_ids("検索"));

    remove_data(2, 1, "CHECKINSTALL.JA");
    add_data(3, 2, "FUTUREWORKS.JA");
    gcut_assert_equal_list_string(gcut_take_new_list_string("3", NULL),
                                  retrieve_record_ids("検索"));

    update_data(4, 1, "INSTALL.JA", "README.JA");
    gcut_assert_equal_list_string(gcut_take_new_list_string("3", "4", NULL),
                                  retrieve_record_ids("検索"));

    remove_data(4, 1, "README.JA");
    gcut_assert_equal_list_string(gcut_take_new_list_string("3", NULL),
                                  retrieve_record_ids("検索"));

    remove_data(3, 2, "FUTUREWORKS.JA");
    cut_set_message("this assertion is wrong?");
    gcut_assert_equal_list_string(NULL, retrieve_record_ids("検索"));
}
/**
 * Function timer_expired() is called after the timer is elapsed.
 * @param id and data are set by caller of abs_eap_am_tools::set_timer() function.
 * @param id could be used to separate different timer events.
 * @param data could be pointer to any data that is needed in timer processing.
 */
EAP_FUNC_EXPORT eap_status_e eap_am_memory_store_c::timer_expired(
	const u32_t id, void *data)
{
	EAP_TRACE_DEBUG(
		m_am_tools,
		TRACE_FLAGS_DEFAULT,
		(EAPL("eap_am_memory_store_c::timer_expired(): id %d, data 0x%08x\n"),
		 id,
		 data));

	if (data != 0)
	{
		eap_variable_data_c * const key = reinterpret_cast<eap_variable_data_c *>(data);

		EAP_TRACE_DATA_DEBUG(
			m_am_tools,
			TRACE_FLAGS_DEFAULT,
			(EAPL("eap_am_memory_store_c::timer_expired(): key"),
			 key->get_data(),
			 key->get_data_length()));

		eap_am_memory_store_tlv_data_c * const tlv_data = m_store_new.get_handler(key);
		if (tlv_data != 0)
		{
			if (id == tlv_data->get_timer_id())
			{
				eap_status_e status = remove_data(key);

				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
				return EAP_STATUS_RETURN(m_am_tools, status);
			}
			else
			{
				EAP_TRACE_DEBUG(
					m_am_tools,
					TRACE_FLAGS_ERROR,
					(EAPL("eap_am_memory_store_c::timer_expired(): id %d != tlv_data->id %d, tlv_data 0x%08x\n"),
					 id,
					 tlv_data->get_timer_id(),
					 tlv_data));
				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
				return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
			}
		}
	}

	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
}
Пример #7
0
/**
 * Read a message from a queue.
 *
 *     Read and dequeue a message.
 *     This service may panic if err parameter is NULL and:
 *      -# queue parameter is invalid, or
 *      -# message parameter is NULL, or
 *      -# when called from an ISR.
 *
 *     Authorized execution levels:  task, fiber.
 *
 * @param queue : handler on the queue (value returned by queue_create).
 *
 * @param message (out): pointer to read message.
 *
 * @param timeout: maximum number of milliseconds to wait for the message. Special
 *                values OS_NO_WAIT and OS_WAIT_FOREVER may be used.
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : a message was read
 *          -# E_OS_ERR_TIMEOUT: no message was received
 *          -# E_OS_ERR_EMPTY: the queue is empty
 *          -# E_OS_ERR: invalid parameter
 *          -# E_OS_ERR_NOT_ALLOWED: service cannot be executed from ISR context.
 */
void queue_get_message (T_QUEUE queue, T_QUEUE_MESSAGE* message, int timeout, OS_ERR_TYPE* err)
{
    OS_ERR_TYPE _err;
    T_EXEC_LEVEL execLvl = _getExecLevel();
    queue_impl_t * q = (queue_impl_t*) queue;

    /* check input parameters */
    if( (message == NULL) || (!queue_used(q)) || (q->sema==NULL) || (timeout<OS_WAIT_FOREVER) )
    {
        error_management (err, E_OS_ERR);
        return;
    }

    /* check execution level */
    if ((E_EXEC_LVL_FIBER == execLvl) || (E_EXEC_LVL_TASK == execLvl))
    {
        _err = semaphore_take(q->sema, timeout);
        switch(_err){

        case E_OS_OK:
        {
            uint32_t it_mask = interrupt_lock();
            _err = remove_data(q, message);
            interrupt_unlock(it_mask);
            error_management (err, E_OS_OK);
        }
            break;
        case E_OS_ERR_TIMEOUT:
            error_management (err, E_OS_ERR_TIMEOUT);
            break;
        case E_OS_ERR_BUSY:
            if(err){
                //QUEUE EMPTY, is a common use case, do not panic even if err == NULL
                *err = E_OS_ERR_EMPTY;
            }
            break;
        default:
            //unknown error
            panic(E_OS_ERR_UNKNOWN);
        }
    }
    else
    {
        error_management (err, E_OS_ERR_NOT_ALLOWED);
    }

    return;
}
Пример #8
0
static bool put_data(qhasharr_t *tbl, int idx, uint32_t hash, const void *name,
                     size_t namesize, const void *data, size_t datasize,
                     int count) {
    qhasharr_data_t *tbldata = tbl->data;
    qhasharr_slot_t *tblslots = get_slots(tbl);

    assert(tblslots[idx].count == 0);

    unsigned char namemd5[16];
    qhashmd5(name, namesize, namemd5);

    // store name
    tblslots[idx].count = count;
    tblslots[idx].hash = hash;
    memcpy(tblslots[idx].data.pair.name, name,
           (namesize < Q_HASHARR_NAMESIZE) ? namesize : Q_HASHARR_NAMESIZE);
    memcpy((char *) tblslots[idx].data.pair.namemd5, (char *) namemd5, 16);
    tblslots[idx].data.pair.namesize = namesize;
    tblslots[idx].link = -1;

    // store data
    int newidx;
    size_t savesize;
    for (newidx = idx, savesize = 0; savesize < datasize;) {
        if (savesize > 0) {  // find next empty slot
            int tmpidx = find_avail(tbl, newidx + 1);
            if (tmpidx < 0) {
                remove_data(tbl, idx);
                errno = ENOBUFS;
                return false;
            }

            // clear & set
            memset((void *) (&tblslots[tmpidx]), '\0', sizeof(qhasharr_slot_t));

            tblslots[tmpidx].count = EXTBLOCK_MARK; // extended data block
            tblslots[tmpidx].hash = newidx;   // previous link
            tblslots[tmpidx].link = -1;       // end block mark
            tblslots[tmpidx].datasize = 0;
            tblslots[newidx].link = tmpidx;   // link chain

            newidx = tmpidx;
        }

        // copy data
        size_t copysize = datasize - savesize;
        if (tblslots[newidx].count == EXTBLOCK_MARK) {
            // extended value
            if (copysize > sizeof(struct Q_HASHARR_SLOT_EXT)) {
                copysize = sizeof(struct Q_HASHARR_SLOT_EXT);
            }
            memcpy(tblslots[newidx].data.ext.data, data + savesize, copysize);
        } else {
            // first slot
            if (copysize > Q_HASHARR_DATASIZE) {
                copysize = Q_HASHARR_DATASIZE;
            }
            memcpy(tblslots[newidx].data.pair.data, data + savesize, copysize);

            // increase stored key counter
            tbldata->num++;
        }
        tblslots[newidx].datasize = copysize;
        savesize += copysize;

        // increase used slot counter
        tbldata->usedslots++;
    }

#ifdef QHASHARR_TIMESTAMP
    time(&tblslots[idx].timestamp);
#endif

    return true;
}
Пример #9
0
int main() {
	unsigned int key_space = 1024;
	HashMap * hm = create_hashmap(key_space);

	char * string_1 = "TI2725-C";
	char * string_2 = "Embedded";
	char * string_3 = "Software";
	const char * key_1    = "ab";
	const char * key_2    = "cd";
	const char * key_3    = "ad";
	const char * key_4    = "xy";

	// Insert ("ab" -> "TI2725-C").
	insert_data(hm, key_1, string_1, resolve_collision);
	assert(memcmp(get_data(hm, key_1), string_1, mystrlen(string_1)) == 0);

	// Insert ("cd" -> "Embedded").
	insert_data(hm, key_2, string_2, resolve_collision);
	assert(memcmp(get_data(hm, key_2), string_2, mystrlen(string_2)) == 0);

	// Insert ("ad" -> "Software").
	insert_data(hm, key_3, string_3, resolve_collision);
	assert(memcmp(get_data(hm, key_3), string_3, mystrlen(string_3)) == 0);

	// Insert ("ab" -> "Embedded").
	insert_data(hm, key_1, string_2, resolve_collision);
	assert(memcmp(get_data(hm, key_1), string_2, mystrlen(string_2)) == 0);

	// Get data for a not inserted key.
	assert(get_data(hm, key_4) == NULL);

	// Iterate the hash map
	iterate(hm, print_element);

#ifdef NEW_HASH
	set_hash_function(hm, your_own_hash);

	printf("\nHERE WE GO AGAIN!\n\n");

	// Iterate the hash map 
	iterate(hm, print_element);
#endif

	// Delete key "cd".
	remove_data(hm, key_2, NULL);
	assert(get_data(hm, key_2) == NULL);

	// Delete key "ab".
	remove_data(hm, key_1, NULL);
	assert(get_data(hm, key_1) == NULL);

	// Delete key "ad".
	remove_data(hm, key_3, NULL);
	assert(get_data(hm, key_3) == NULL);

	// Delete the hash map.
	delete_hashmap(hm, NULL);

#ifdef COUNTING_WORDS
	// Create a temporary file
	FILE *stream = tmpfile();

	// Write to the stream
	fprintf(stream, "foo bar_, baz!\n");
	fprintf(stream, "foo\t\"bar\".\n");
	fprintf(stream, "foo?\n");

	// Set the position to the start of the stream
	fseek(stream, 0, SEEK_SET);

	// Count the words
	count_words(stream);

	// Close the file
	fclose(stream);
#endif

	return 0;
}