コード例 #1
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Cancellation a buffer
BSP_DECLARE(void) bsp_del_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        if (!B_ISCONST(b))
        {
            if (_BSP_BUFFER_HIGHWATER < B_SIZE(b))
            {
                // Buffer too big, just clean
                bsp_free(B_DATA(b));
                B_DATA(b) = NULL;
                B_SIZE(b) = 0;
                B_LEN(b) = 0;
                B_NOW(b) = 0;
            }

            if (_BSP_BUFFER_UNSATURATION < (B_SIZE(b) - B_LEN(b)))
            {
                _shrink_buffer(b);
            }
        }
        else
        {
            B_DATA(b) = NULL;
            B_SIZE(b) = 0;
        }

        bsp_mempool_free(mp_buffer, (void *) b);
    }

    return;
}
コード例 #2
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
BSP_PRIVATE(int) _shrink_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        size_t new_size = 2 << (int) log2(B_LEN(b));
        if (new_size < B_SIZE(b))
        {
            char *new_data = bsp_realloc(B_DATA(b), new_size);
            if (new_data)
            {
                B_DATA(b) = new_data;
                B_SIZE(b) = new_size;

                return BSP_RTN_SUCCESS;
            }

            return BSP_RTN_ERR_MEMORY;
        }
        else
        {
            // May not shrink
            return BSP_RTN_SUCCESS;
        }
    }

    return BSP_RTN_ERR_GENERAL;
}
コード例 #3
0
ファイル: free.c プロジェクト: Adpa18/malloc
void    _free(void *ptr)
{
    t_block *block;

    RETURN(!ptr || ptr > LAST_PTR() || ptr < FIRST_PTR());
    block = GET_BLOCK(ptr);
    RETURN(block->isFree);
    block->isFree = true;
    if (block->parent == last && last->startBlock == last->lastBlock)
    {
        if (!(last = last->prev))
            blocks = NULL;
        else
            last->next = NULL;
        brk(block->parent);
    }
    else if (block == block->parent->lastBlock)
    {
        if (!(block->parent->lastBlock = block->prev))
            block->parent->startBlock = NULL;
        block->parent->freeSize += B_SIZE(block->size);
    }
    else if (block->parent->maxFreeSize < block->size)
        block->parent->maxFreeSize = block->size;
}
コード例 #4
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Read file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read(BSP_BUFFER *b, int fd, size_t len)
{
    if (!b || !fd || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    // Try read
    ssize_t ret = read(fd, B_DATA(b) + B_LEN(b), len);
    if (ret > 0)
    {
        bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) ret, fd);
        B_LEN(b) += ret;
    }

    return ret;
}
コード例 #5
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Append data to buffer
BSP_DECLARE(size_t) bsp_buffer_append(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        // Space not enough, realloc buffer
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memcpy(B_DATA(b) + B_LEN(b), data, len);
    B_LEN(b) = need;

    return len;
}
コード例 #6
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Set const data to en empty buffer
BSP_DECLARE(size_t) bsp_buffer_set_const(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    if (B_DATA(b))
    {
        bsp_free(B_DATA(b));
    }

    B_DATA(b) = (char *) data;
    B_SIZE(b) = 0;
    B_LEN(b) = len;

    // Set to const
    b->is_const = BSP_TRUE;

    return len;
}
コード例 #7
0
ファイル: free.c プロジェクト: Adpa18/malloc
void    _free(void *ptr)
{
    t_block *block;

    RETURN(!ptr || ptr > (void *)moreSpace(0, true));
    block = GET_BLOCK(ptr);
    RETURN(block->isFree);
    mergeBlocks(&block);
    block->isFree = true;
    if (block == block->parent->lastBlock)
    {
        block->parent->lastBlock = block->prev;
        block->parent->freeSize += B_SIZE(block->size);
        if (!block->parent->next && block->parent->freeSize > PAGE_SIZE)
        {
            if (blocks != block->parent)
            {
                if (block->parent->prev)
                    block->parent->prev->next = block->parent->next;
                brk(block->parent);
            }
        }
    }
    else
    if (block->parent->maxFreeSize < block->size)
        block->parent->maxFreeSize = block->size;
}
コード例 #8
0
ファイル: free.c プロジェクト: Adpa18/malloc
void    mergeBlocks(t_block **block)
{
    if ((*block)->next && (*block)->next->isFree)
    {
        (*block)->size += B_SIZE((*block)->next->size);
        (*block)->next = (*block)->next->next;
        if ((*block)->next)
            (*block)->next->prev = (*block);
    }
    if ((*block)->prev && (*block)->prev->isFree)
    {
        (*block)->prev->size += B_SIZE((*block)->size);
        (*block)->prev->next = (*block)->next;
        if ((*block)->next)
            (*block)->next->prev = (*block)->prev;
        *block = (*block)->prev;
    }
}
コード例 #9
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Read all data from file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read_all(BSP_BUFFER *b, int fd)
{
    if (!b || !fd)
    {
        return 0;
    }

    ssize_t len = 0, tlen = 0;
    while (BSP_TRUE)
    {
        size_t need = B_LEN(b) + _BSP_FD_READ_ONCE;
        if (need > B_SIZE(b))
        {
            if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
            {
                // Enlarge error
                break;
            }
        }

        len = read(fd, B_DATA(b) + B_LEN(b), _BSP_FD_READ_ONCE);
        if (len < 0)
        {
            if (EINTR == errno || EWOULDBLOCK == errno || EAGAIN == errno)
            {
                 // Break
                break;
            }
        }
        else if (0 == len)
        {
            // TCP FIN
            tlen = 0;
            break;
        }
        else
        {
            // Data already in buffer -_-
            tlen += len;
            B_LEN(b) += len;
            bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) len, fd);
            if (len < _BSP_FD_READ_ONCE)
            {
                // All gone
                break;
            }
        }
    }

    return tlen;
}
コード例 #10
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
BSP_PRIVATE(int) _enlarge_buffer(BSP_BUFFER *b, size_t size)
{
    if (b && size > B_SIZE(b))
    {
        size_t new_size = 2 << bsp_log2(size);
        char *new_data = bsp_realloc(B_DATA(b), new_size);
        if (new_data)
        {
            B_DATA(b) = new_data;
            B_SIZE(b) = new_size;

            return BSP_RTN_SUCCESS;
        }
        else
        {
            bsp_trace_message(BSP_TRACE_CRITICAL, _tag_, "Enlarge buffer to %llu bytes failed", (unsigned long long int) new_size);
        }

        return BSP_RTN_ERR_MEMORY;
    }

    return BSP_RTN_ERR_GENERAL;
}
コード例 #11
0
ファイル: bsp_buffer.c プロジェクト: zscwind/libbsp
// Fill seriate character to buffer
BSP_DECLARE(size_t) bsp_buffer_fill(BSP_BUFFER *b, int code, size_t len)
{
    if (!b || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memset(B_DATA(b) + B_LEN(b), code, len);
    B_LEN(b) = need;

    return len;
}