Esempio n. 1
0
tb_void_t tb_vector_nremove(tb_vector_ref_t vector, tb_size_t itor, tb_size_t size)
{
    // check
    tb_vector_impl_t* impl = (tb_vector_impl_t*)vector;
    tb_assert_and_check_return(impl && size && itor < impl->size);

    // clear it
    if (!itor && size >= impl->size) 
    {
        tb_vector_clear(vector);
        return ;
    }
    
    // strip size
    if (itor + size > impl->size) size = impl->size - itor;

    // compute the left size
    tb_size_t left = impl->size - itor - size;

    // free data
    if (impl->func.nfree)
        impl->func.nfree(&impl->func, impl->data + itor * impl->func.size, size);

    // move the left data
    if (left)
    {
        tb_byte_t* pd = impl->data + itor * impl->func.size;
        tb_byte_t* ps = impl->data + (itor + size) * impl->func.size;
        tb_memmov(pd, ps, left * impl->func.size);
    }

    // update size
    impl->size -= size;
}
Esempio n. 2
0
tb_byte_t* tb_queue_buffer_push_init(tb_queue_buffer_ref_t buffer, tb_size_t* size)
{
    // check
    tb_assert_and_check_return_val(buffer && buffer->maxn, tb_null);

    // no data?
    if (!buffer->data)
    {
        // make data
        buffer->data = tb_malloc_bytes(buffer->maxn);
        tb_assert_and_check_return_val(buffer->data, tb_null);

        // init 
        buffer->head = buffer->data;
        buffer->size = 0;
    }
    tb_assert_and_check_return_val(buffer->data && buffer->head, tb_null);

    // full?
    tb_size_t left = buffer->maxn - buffer->size;
    tb_check_return_val(left, tb_null);

    // move data to head first, make sure there is enough write space 
    if (buffer->head != buffer->data)
    {
        if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
        buffer->head = buffer->data;
    }

    // save size
    if (size) *size = left;

    // ok
    return buffer->head + buffer->size;
}
Esempio n. 3
0
static tb_void_t tb_hash_map_itor_remove(tb_iterator_ref_t iterator, tb_size_t itor)
{
    // check
    tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator;
    tb_assert_return(impl && impl->hash_list && impl->hash_size);
    
    // buck & item
    tb_size_t buck = tb_hash_map_index_buck(itor);
    tb_size_t item = tb_hash_map_index_item(itor);
    tb_assert_return(buck && item); buck--; item--;
    tb_assert_return(buck < impl->hash_size);

    // the step
    tb_size_t step = impl->element_name.size + impl->element_data.size;
    tb_assert_return(step);

    // get list
    tb_hash_map_item_list_t* list = impl->hash_list[buck];
    tb_assert_return(list && list->size && item < list->size);

    // free item
    if (impl->element_name.free) impl->element_name.free(&impl->element_name, ((tb_byte_t*)&list[1]) + item * step);
    if (impl->element_data.free) impl->element_data.free(&impl->element_data, ((tb_byte_t*)&list[1]) + item * step + impl->element_name.size);

    // remove item from the list
    if (list->size > 1)
    {
        // move items
        if (item < list->size - 1) tb_memmov(((tb_byte_t*)&list[1]) + item * step, ((tb_byte_t*)&list[1]) + (item + 1) * step, (list->size - item - 1) * step);

        // update size
        list->size--;
    }
    // remove list
    else 
    {
        // free it
        tb_free(list);

        // reset
        impl->hash_list[buck] = tb_null;
    }

    // update the impl item size
    impl->item_size--;
}
Esempio n. 4
0
tb_long_t tb_queue_buffer_writ(tb_queue_buffer_ref_t buffer, tb_byte_t const* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && data && buffer->maxn, -1);

    // no data?
    if (!buffer->data)
    {
        // make data
        buffer->data = tb_malloc_bytes(buffer->maxn);
        tb_assert_and_check_return_val(buffer->data, -1);

        // init it
        buffer->head = buffer->data;
        buffer->size = 0;
    }
    tb_assert_and_check_return_val(buffer->data && buffer->head, -1);

    // full?
    tb_size_t left = buffer->maxn - buffer->size;
    tb_check_return_val(left, 0);

    // attempt to write data in tail directly if the tail space is enough
    tb_byte_t* tail = buffer->head + buffer->size;
    if (buffer->data + buffer->maxn >= tail + size)
    {
        tb_memcpy(tail, data, size);
        buffer->size += size;
        return (tb_long_t)size;
    }

    // move data to head
    if (buffer->head != buffer->data)
    {
        if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
        buffer->head = buffer->data;
    }

    // write data
    tb_size_t writ = left > size? size : left;
    tb_memcpy(buffer->data + buffer->size, data, writ);
    buffer->size += writ;

    // ok
    return writ;
}
Esempio n. 5
0
tb_void_t tb_vector_remove(tb_vector_ref_t vector, tb_size_t itor)
{   
    // check
    tb_vector_impl_t* impl = (tb_vector_impl_t*)vector;
    tb_assert_and_check_return(impl && itor < impl->size);

    if (impl->size)
    {
        // do free
        if (impl->func.free) impl->func.free(&impl->func, impl->data + itor * impl->func.size);

        // move data if itor is not last
        if (itor < impl->size - 1) tb_memmov(impl->data + itor * impl->func.size, impl->data + (itor + 1) * impl->func.size, (impl->size - itor - 1) * impl->func.size);

        // resize
        impl->size--;
    }
}
Esempio n. 6
0
tb_void_t tb_vector_ninsert_prev(tb_vector_ref_t vector, tb_size_t itor, tb_cpointer_t data, tb_size_t size)
{
    // check
    tb_vector_impl_t* impl = (tb_vector_impl_t*)vector;
    tb_assert_and_check_return(impl && impl->data && size && itor <= impl->size);

    // save size
    tb_size_t osize = impl->size;

    // grow size
    if (!tb_vector_resize(vector, osize + size)) 
    {
        tb_trace_d("impl resize: %u => %u failed", osize, osize + 1);
        return ;
    }

    // move items if not at tail
    if (osize != itor) tb_memmov(impl->data + (itor + size) * impl->func.size, impl->data + itor * impl->func.size, (osize - itor) * impl->func.size);

    // duplicate data
    impl->func.ndupl(&impl->func, impl->data + itor * impl->func.size, data, size);
}
Esempio n. 7
0
tb_byte_t* tb_buffer_memnmovp(tb_buffer_t* buffer, tb_size_t p, tb_size_t b, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(buffer && (b + n) <= tb_buffer_size(buffer), tb_null);

    // clear?
    if (b == tb_buffer_size(buffer)) 
    {
        tb_buffer_clear(buffer);
        return tb_buffer_data(buffer);
    }

    // check
    tb_check_return_val(p != b && n, tb_buffer_data(buffer));

    // resize
    tb_byte_t* d = tb_buffer_resize(buffer, p + n);
    tb_assert_and_check_return_val(d, tb_null);

    // memmov
    tb_memmov(d + p, d + b, n);
    return d;
}
Esempio n. 8
0
tb_long_t tb_queue_buffer_writ(tb_queue_buffer_t* buffer, tb_byte_t const* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && data && buffer->maxn, -1);

    // no data?
    if (!buffer->data)
    {
        // make data
        buffer->data = tb_malloc_bytes(buffer->maxn);
        tb_assert_and_check_return_val(buffer->data, -1);

        // init it
        buffer->head = buffer->data;
        buffer->size = 0;
    }
    tb_assert_and_check_return_val(buffer->data && buffer->head, -1);

    // no left?
    tb_size_t left = buffer->maxn - buffer->size;
    tb_check_return_val(left, 0);

    // move data to head
    if (buffer->head != buffer->data)
    {
        if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
        buffer->head = buffer->data;
    }

    // writ data
    tb_size_t writ = left > size? size : left;
    tb_memcpy(buffer->data + buffer->size, data, writ);
    buffer->size += writ;

    // ok
    return writ;
}
Esempio n. 9
0
tb_byte_t* tb_queue_buffer_resize(tb_queue_buffer_ref_t buffer, tb_size_t maxn)
{
    // check
    tb_assert_and_check_return_val(buffer && maxn && maxn >= buffer->size, tb_null);

    // has data?
    if (buffer->data)
    {
        // move data to head
        if (buffer->head != buffer->data)
        {
            if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
            buffer->head = buffer->data;
        }

        // realloc
        if (maxn > buffer->maxn)
        {
            // init head
            buffer->head = tb_null;

            // make data
            buffer->data = (tb_byte_t*)tb_ralloc(buffer->data, maxn);
            tb_assert_and_check_return_val(buffer->data, tb_null);

            // save head
            buffer->head = buffer->data;
        }
    }

    // update maxn
    buffer->maxn = maxn;

    // ok
    return buffer->data;
}
Esempio n. 10
0
File: path.c Progetto: richwu/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_size_t tb_path_translate(tb_char_t* path, tb_size_t size, tb_size_t maxn)
{
    // check
    tb_assert_and_check_return_val(path, 0);

    // file://?
    tb_char_t* p = path;
    if (!tb_strnicmp(p, "file:", 5)) p += 5;
    // is user directory?
    else if (path[0] == '~')
    {
        // get the home directory
        tb_char_t home[TB_PATH_MAXN];
        tb_size_t home_size = tb_directory_home(home, sizeof(home) - 1);
        tb_assert_and_check_return_val(home_size, 0);

        // check the path space
        tb_size_t path_size = size? size : tb_strlen(path);
        tb_assert_and_check_return_val(home_size + path_size - 1 < maxn, 0);

        // move the path and ensure the enough space for the home directory
        tb_memmov(path + home_size, path + 1, path_size - 1);

        // copy the home directory 
        tb_memcpy(path, home, home_size);
        path[home_size + path_size - 1] = '\0';
    }

    // remove repeat separator
    tb_char_t*  q = path;
    tb_size_t   repeat = 0;
    for (; *p; p++)
    {
        if (tb_path_is_separator(*p))
        {
            // save the separator if not exists
            if (!repeat) *q++ = TB_PATH_SEPARATOR;

            // repeat it
            repeat++;
        }
        else 
        {
            // save character
            *q++ = *p;

            // clear repeat
            repeat = 0;
        }
    }

    // remove the tail separator and not root: '/'
    if (q > path + 1 && *(q - 1) == TB_PATH_SEPARATOR) q--;

    // end
    *q = '\0';

    // is windows path? 
    if (q > path + 1 && tb_isalpha(path[0]) && path[1] == ':')
    {
        // get the upper drive prefix
        path[0] = tb_toupper(path[0]);

        // append the drive separator if not exists
        if (q - path == 2)
        {
            *q++ = TB_PATH_SEPARATOR;
            *q = '\0';
        }
    }

    // trace
    tb_trace_d("translate: %s", path);

    // ok
    return q - path;
}
Esempio n. 11
0
tb_size_t tb_hash_map_insert(tb_hash_map_ref_t hash_map, tb_cpointer_t name, tb_cpointer_t data)
{
    // check
    tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)hash_map;
    tb_assert_and_check_return_val(impl, 0);

    // the step
    tb_size_t step = impl->element_name.size + impl->element_data.size;
    tb_assert_and_check_return_val(step, 0);

    // find it
    tb_size_t buck = 0;
    tb_size_t item = 0;
    if (tb_hash_map_item_find(impl, name, &buck, &item))
    {
        // check
        tb_assert_and_check_return_val(buck < impl->hash_size, 0);

        // get list
        tb_hash_map_item_list_t* list = impl->hash_list[buck];
        tb_assert_and_check_return_val(list && list->size && item < list->size, 0);

        // replace data
        impl->element_data.repl(&impl->element_data, ((tb_byte_t*)&list[1]) + item * step + impl->element_name.size, data);
    }
    else
    {
        // check
        tb_assert_and_check_return_val(buck < impl->hash_size, 0);

        // get list
        tb_hash_map_item_list_t* list = impl->hash_list[buck];
        
        // insert item
        if (list)
        {
            // grow?
            if (list->size >= list->maxn)
            {
                // check
                tb_assert_and_check_return_val(impl->item_grow, 0);

                // resize maxn
                tb_size_t maxn = tb_align_pow2(list->maxn + impl->item_grow);
                tb_assert_and_check_return_val(maxn > list->maxn, 0);

                // realloc it
                list = (tb_hash_map_item_list_t*)tb_ralloc(list, sizeof(tb_hash_map_item_list_t) + maxn * step);  
                tb_assert_and_check_return_val(list, 0);

                // update the impl item maxn
                impl->item_maxn += maxn - list->maxn;

                // update maxn
                list->maxn = maxn;

                // reattach list
                impl->hash_list[buck] = list;
            }
            tb_assert_and_check_return_val(item <= list->size && list->size < list->maxn, 0);

            // move items
            if (item != list->size) tb_memmov(((tb_byte_t*)&list[1]) + (item + 1) * step, ((tb_byte_t*)&list[1]) + item * step, (list->size - item) * step);

            // dupl item
            list->size++;
            impl->element_name.dupl(&impl->element_name, ((tb_byte_t*)&list[1]) + item * step, name);
            impl->element_data.dupl(&impl->element_data, ((tb_byte_t*)&list[1]) + item * step + impl->element_name.size, data);

        }
        // create list for adding item
        else
        {
            // check
            tb_assert_and_check_return_val(impl->item_grow, 0);

            // make list
            list = (tb_hash_map_item_list_t*)tb_malloc0(sizeof(tb_hash_map_item_list_t) + impl->item_grow * step);
            tb_assert_and_check_return_val(list, 0);

            // init list
            list->size = 1;
            list->maxn = impl->item_grow;
            impl->element_name.dupl(&impl->element_name, ((tb_byte_t*)&list[1]), name);
            impl->element_data.dupl(&impl->element_data, ((tb_byte_t*)&list[1]) + impl->element_name.size, data);

            // attach list
            impl->hash_list[buck] = list;

            // update the impl item maxn
            impl->item_maxn += list->maxn;
        }

        // update the impl item size
        impl->item_size++;
    }

    // ok?
    return tb_hash_map_index_make(buck + 1, item + 1);
}
Esempio n. 12
0
static tb_void_t tb_hash_map_itor_remove_range(tb_iterator_ref_t iterator, tb_size_t prev, tb_size_t next, tb_size_t size)
{
    // check
    tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator;
    tb_assert_return(impl && impl->hash_list && impl->hash_size);

    // no size
    tb_check_return(size);

    // the step
    tb_size_t step = impl->element_name.size + impl->element_data.size;
    tb_assert_return(step);

    // the first itor
    tb_size_t itor = prev? tb_hash_map_itor_next(iterator, prev) : tb_hash_map_itor_head(iterator);

    // the head buck and item
    tb_size_t buck_head = tb_hash_map_index_buck(itor);
    tb_size_t item_head = tb_hash_map_index_item(itor);
    tb_assert_return(buck_head && item_head);

    // compute index
    buck_head--;
    item_head--;
    tb_assert_return(buck_head < impl->hash_size && item_head < TB_HASH_MAP_BUCKET_ITEM_MAXN);

    // the last buck and the tail item
    tb_size_t buck_last;
    tb_size_t item_tail;
    if (next)
    {
        // next => buck and item
        buck_last = tb_hash_map_index_buck(next);
        item_tail = tb_hash_map_index_item(next);
        tb_assert_return(buck_last && item_tail);

        // compute index
        buck_last--;
        item_tail--;
        tb_assert_return(buck_last < impl->hash_size && item_tail < TB_HASH_MAP_BUCKET_ITEM_MAXN);
    }
    else 
    {
        buck_last = impl->hash_size - 1;
        item_tail = -1;
    }

    // remove items: [itor, next)
    tb_size_t buck;
    tb_size_t item;
    tb_element_free_func_t name_free = impl->element_name.free;
    tb_element_free_func_t data_free = impl->element_data.free;
    for (buck = buck_head, item = item_head; buck <= buck_last; buck++, item = 0)
    {
        // the list
        tb_hash_map_item_list_t* list = impl->hash_list[buck];
        tb_check_continue(list && list->size);

        // the tail
        tb_size_t tail = (buck == buck_last && next)? item_tail : list->size;
        tb_assert_abort(tail != -1);
        tb_check_continue(item < tail);

        // the data
        tb_byte_t* data = (tb_byte_t*)&list[1];

        // free items
        tb_size_t i = 0;
        for (i = item; i < tail; i++)
        {
            if (name_free) name_free(&impl->element_name, data + i * step);
            if (data_free) data_free(&impl->element_data, data + i * step + impl->element_name.size);
        }

        // move items
        if (buck == buck_last && tail < list->size) tb_memmov(data + item * step, data + tail * step, (list->size - tail) * step);

        // update the list size
        list->size -= tail - item;

        // update the item size
        impl->item_size -= tail - item;
    }
}