⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yc_dymemarr.c

📁 一个类STL的多平台可移植的算法容器库,主要用于嵌入式系统编程时的内存管理等方面
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * The young Library
 * Copyright (c) 2005 by Yang Huan(杨桓)

 * Permission to use, copy, modify, distribute and sell this software for any
 * purpose is hereby granted without fee, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and this
 * permission notice appear in supporting documentation.
 * The author make no representations about the suitability of this software
 * for any purpose. It is provided "as is" without express or implied warranty.
 */

/******************************************************************************/
/******************************************************************************/
#include "yc_memalgo.h"
#include "yc_dymemarr.h"

#ifdef __cplusplus
    namespace youngc {  extern "C" {
#endif
/******************************************************************************/
/******************************************************************************/

enum DYMEMARR_CONSTANT
{
    DYMEMARR_ALIGN_SIZE = sizeof(long) * 16
};

#define POS( PARR, index ) \
        ( (ylib_byte_t*)((PARR)->m_start) + (index) * (PARR)->m_element_size )

#define LENGTH( PARR )                       \
        ( ( (ylib_byte_t*)((PARR)->m_finish) \
            - (ylib_byte_t*)((PARR)->m_start) ) / (PARR)->m_element_size )

#define CAPACITY( PARR )                     \
        ( ( (ylib_byte_t*)((PARR)->m_utmost) \
            - (ylib_byte_t*)((PARR)->m_start) ) / (PARR)->m_element_size )

#define LEN_SIZE( PARR ) \
        ( (ylib_byte_t*)((PARR)->m_finish) - (ylib_byte_t*)((PARR)->m_start) )

#define CAPA_SIZE( PARR ) \
        ( (ylib_byte_t*)((PARR)->m_utmost) - (ylib_byte_t*)((PARR)->m_start) )

/******************************************************************************/

static size_t dymemarr_alloc_size( const dymemarray* self, size_t len )
{
    size_t alloc_size = DYMEMARR_ALIGN_SIZE;
    size_t request_size = len * self->m_element_size;

    /* 如果 m_element_size <= CHARACTER_SIZE_MAX 则有可能是字符串
     * 将长度加1以容纳结束符 */
    if( self->m_element_size <= CHARACTER_SIZE_MAX )
        request_size += self->m_element_size;

    while( alloc_size < request_size )
        alloc_size *= 2;

    return alloc_size;
}

/******************************************************************************/

static bool dymemarr_memory_reserve( dymemarray* self,
                                     size_t index,
                                     size_t old_count,
                                     size_t new_count )
{
    size_t old_len = LENGTH( self );
    size_t new_len = old_len - old_count + new_count;

    if( new_len <= CAPACITY(self) )
    {
        if( old_count != new_count )
            ylib_memmove( POS(self, index + new_count),
                          POS(self, index + old_count),
                          (old_len - index - old_count) * self->m_element_size );
    }
    else
    {
        size_t new_size = dymemarr_alloc_size( self, new_len );
        ylib_byte_t* new_data = (ylib_byte_t*)( self->m_alloc( new_size ) );

        if( !new_data )
            return false;

        ylib_memcopy( new_data, self->m_start, self->m_element_size * index );

        ylib_memcopy( new_data + (index + new_count) * self->m_element_size,
                      POS(self, index + old_count),
                      (old_len - index - old_count) * self->m_element_size );

        dymemarr_destroy( self );

        self->m_start = new_data;
        self->m_utmost = new_data + new_size;

        if( self->m_element_size <= CHARACTER_SIZE_MAX )
            self->m_utmost = (ylib_byte_t*)(self->m_utmost)
                             - self->m_element_size;
    }

    self->m_finish = POS( self, new_len );
    return true;
}

/******************************************************************************/

void dymemarr_init( dymemarray* uninit_self,
                    size_t element_size,
                    ylib_fp_alloc_t alloc,
                    ylib_fp_dealloc_t dealloc )
{
    uninit_self->m_start = NULL;
    uninit_self->m_finish = NULL;
    uninit_self->m_utmost = NULL;
    uninit_self->m_element_size = element_size;
    uninit_self->m_alloc = alloc;
    uninit_self->m_dealloc = dealloc;
}

/******************************************************************************/

void dymemarr_reinit( dymemarray* self, size_t element_size )
{
    if( self->m_element_size <= CHARACTER_SIZE_MAX )
        self->m_utmost = (ylib_byte_t*)(self->m_utmost) + self->m_element_size;

    self->m_finish = self->m_start;
    self->m_element_size = element_size;

    if( self->m_element_size <= CHARACTER_SIZE_MAX )
        self->m_utmost = (ylib_byte_t*)(self->m_utmost) - self->m_element_size;
}

/******************************************************************************/

void dymemarr_destroy( dymemarray* self )
{
    if( self->m_start )
    {
        if( self->m_element_size <= CHARACTER_SIZE_MAX )
            self->m_utmost = (ylib_byte_t*)(self->m_utmost)
                             + self->m_element_size;
        self->m_dealloc( self->m_start, CAPA_SIZE(self) );
    }

    self->m_start = NULL;
    self->m_finish = NULL;
    self->m_utmost = NULL;
}

/******************************************************************************/

int dymemarr_init_copy( dymemarray* uninit_self, const dymemarray* src )
{
    if( uninit_self == src )
        return -1;
    else
    {
        if( src->m_start == src->m_finish )
        {
            *uninit_self = *src;
            uninit_self->m_start = NULL;
            uninit_self->m_finish = NULL;
            uninit_self->m_utmost = NULL;
        }
        else
        {
            size_t src_len = LENGTH( src );
            size_t alloc_size = dymemarr_alloc_size( src, src_len );

            *uninit_self = *src;
            uninit_self->m_start = src->m_alloc( alloc_size );

            if( !(uninit_self->m_start) )
            {
                uninit_self->m_finish = NULL;
                uninit_self->m_utmost = NULL;
                return 0;
            }
            else
            {
                size_t len_size = LEN_SIZE( src );

                ylib_memcopy( uninit_self->m_start, src->m_start, len_size );

                uninit_self->m_finish = (ylib_byte_t*)(uninit_self->m_start)
                                        + len_size;

                uninit_self->m_utmost = (ylib_byte_t*)(uninit_self->m_start)
                                        + alloc_size;

                if( uninit_self->m_element_size <= CHARACTER_SIZE_MAX )
                    uninit_self->m_utmost = (ylib_byte_t*)(uninit_self->m_utmost)
                                            - uninit_self->m_element_size;
            }
        }
    }

    return 1;
}

/******************************************************************************/

int dymemarr_assign_copy( dymemarray* self, const dymemarray* src )
{
    if( self == src || self->m_element_size != src->m_element_size )
        return -1;

    return true == dymemarr_replace_array( self, 0, LENGTH(self),
                                           src->m_start, LENGTH(src) ) ? 1 : 0;
}

/******************************************************************************/

void dymemarr_init_move( dymemarray* uninit_self, dymemarray* src )
{
    if( uninit_self != src )
    {
        *uninit_self = *src;
        src->m_start = NULL;
        src->m_finish = NULL;
        src->m_utmost = NULL;
    }
}

/******************************************************************************/

void dymemarr_assign_move( dymemarray* self, dymemarray* src )
{
    if( self != src )
    {
        dymemarray temp = *self;
        *self = *src;
        *src = temp;
    }
}

/******************************************************************************/

void* dymemarr_to_string( dymemarray* self, const void* end_of_str )
{
    if( self->m_start && self->m_element_size <= CHARACTER_SIZE_MAX )
    {
        if( !end_of_str )
            ylib_memset( self->m_finish, 0, self->m_element_size );
        else
            ylib_memcopy( self->m_finish, end_of_str, self->m_element_size );
    }

    return self->m_start;
}

/******************************************************************************/

bool dymemarr_reserve( dymemarray* self, size_t new_capacity )
{
    if( CAPACITY(self) < new_capacity )
    {
        size_t new_size = dymemarr_alloc_size( self, new_capacity );
        ylib_byte_t* new_data = (ylib_byte_t*)( self->m_alloc( new_size ) );

        if( !new_data )
            return false;
        else
        {
            size_t len_size = LEN_SIZE( self );

            if( self->m_start )
            {
                ylib_memcopy( new_data, self->m_start, len_size );
                dymemarr_destroy( self );
            }

            if( self->m_element_size <= CHARACTER_SIZE_MAX )
                new_size -= self->m_element_size;

            self->m_start = new_data;
            self->m_finish = new_data + len_size;
            self->m_utmost = new_data + new_size;
        }
    }

    return true;
}

/******************************************************************************/

void dymemarr_erase_pos( dymemarray* self, size_t index )
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -