📄 yc_dymemarr.c
字号:
/*
* 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 + -