📄 yc_string.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.
*/
/******************************************************************************/
/******************************************************************************/
#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
#include <ctype.h>
#include <float.h>
#include <stdarg.h>
#include <string.h>
#include "yc_memory.h"
#include "yc_memalgo.h"
#include "yc_string.h"
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
#include <wchar.h>
#include <wctype.h>
#endif
#ifdef __cplusplus
namespace youngc { extern "C" {
#endif
/******************************************************************************/
/******************************************************************************/
static ylib_fp_alloc_t stralloc = pool_alloc;
static ylib_fp_dealloc_t strdealloc = pool_dealloc;
void set_dystr_alloc( ylib_fp_alloc_t alloc )
{
stralloc = alloc;
}
void set_dystr_dealloc( ylib_fp_dealloc_t dealloc )
{
strdealloc = dealloc;
}
size_t hash_ncstring( const ncstring* dycstr )
{
size_t h = 0, len = ncstr_size( (ncstring*)dycstr );
char* s = ncstr_begin( (ncstring*)dycstr );
for( ; len > 0; --len,++s )
h = (h << 5) - h + *s;
return h;
}
int cmp_ncstring( const ncstring* left, const ncstring* right )
{
size_t lslen = ncstr_size( (ncstring*)left );
size_t rslen = ncstr_size( (ncstring*)right );
int result = memcmp( ncstr_begin( (ncstring*)left ),
ncstr_begin( (ncstring*)right ),
lslen < rslen ? lslen : rslen );
if( 0 == result )
{
if( lslen < rslen )
result = -1;
else if( lslen > rslen )
result = 1;
}
return result;
}
int eq_ncstring( const ncstring* left, const ncstring* right )
{
size_t lslen = ncstr_size( (ncstring*)left );
size_t rslen = ncstr_size( (ncstring*)right );
if( lslen != rslen )
return lslen < rslen ? -1 : 1;
return memcmp( ncstr_begin( (ncstring*)left ),
ncstr_begin( (ncstring*)right ),
lslen );
}
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
size_t hash_wcstring( const wcstring* dywcstr )
{
size_t h = 0, len = wcstr_size( (wcstring*)dywcstr );
wchar_t* ws = wcstr_begin( (wcstring*)dywcstr );
for( ; len > 0; --len,++ws )
h = (h << 5) - h + *ws;
return h;
}
int cmp_wcstring( const wcstring* left, const wcstring* right )
{
int result = 0;
const wchar_t* ls = wcstr_begin( (wcstring*)left );
const wchar_t* rs = wcstr_begin( (wcstring*)right );
size_t lslen = wcstr_size( (wcstring*)left );
size_t rslen = wcstr_size( (wcstring*)right );
size_t cmp_len = lslen < rslen ? lslen : rslen;
for( ; cmp_len > 0; --cmp_len,++ls,++rs )
{
if( *ls != *rs )
{
result = ( *ls < *rs ? -1 : 1 );
break;
}
}
if( 0 == result )
{
if( lslen < rslen )
result = -1;
else if( lslen > rslen )
result = 1;
}
return result;
}
int eq_wcstring( const wcstring* left, const wcstring* right )
{
const wchar_t* ls;
const wchar_t* rs;
size_t lslen = wcstr_size( (wcstring*)left );
size_t rslen = wcstr_size( (wcstring*)right );
if( lslen != rslen )
return lslen < rslen ? -1 : 1;
ls = wcstr_begin( (wcstring*)left );
rs = wcstr_begin( (wcstring*)right );
for( ; lslen > 0; --lslen,++ls,++rs )
{
if( *ls != *rs )
return *ls < *rs ? -1 : 1;
}
return 0;
}
#endif /* SUPPORT_C95_WIDE_CHARACTER */
/******************************************************************************/
/******************************************************************************/
static void dystr_init( dystring* uninit_self )
{
uninit_self->m_dynamic = false;
ylib_memset( &(uninit_self->strobj.m_dystr), 0, sizeof(dymemarray) );
}
/******************************************************************************/
static void dystr_destroy( dystring* self )
{
if( true == self->m_dynamic )
dymemarr_destroy( &(self->strobj.m_dystr) );
self->m_dynamic = false;
self->strobj.m_ncstr.len = 0;
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
self->strobj.m_wcstr.len = 0;
#endif
}
/******************************************************************************/
static int dystr_init_copy( dystring* uninit_self, const dystring* src )
{
uninit_self->m_dynamic = src->m_dynamic;
if( false == src->m_dynamic )
ylib_memcopy( &(uninit_self->strobj.m_ncstr), &(src->strobj.m_ncstr),
sizeof(dymemarray) );
else
return dymemarr_init_copy( &(uninit_self->strobj.m_dystr),
&(src->strobj.m_dystr) );
return 1;
}
/******************************************************************************/
static void dystr_init_move( dystring* uninit_self, dystring* src )
{
*uninit_self = *src;
src->m_dynamic = false;
src->strobj.m_ncstr.len = 0;
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
src->strobj.m_wcstr.len = 0;
#endif
}
/******************************************************************************/
static void dystr_assign_move( dystring* self, dystring* src )
{
dystring temp = *self;
*self = *src;
*src = temp;
}
/******************************************************************************/
static bool static_to_dynamic( ncstring* self, size_t new_capa, bool wchar )
{
dymemarray arr;
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
dymemarr_init( &arr, true == wchar ? sizeof(wchar_t) : sizeof(char),
stralloc, strdealloc );
#else
dymemarr_init( &arr, sizeof(char), stralloc, strdealloc );
#endif
if( false == wchar )
{
if( false == dymemarr_reserve(&arr, new_capa) )
return false;
}
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
else
{
if( false == dymemarr_reserve(&arr, new_capa) )
return false;
}
#endif
#ifdef __MACRO_C_YOUNG_LIBRARY_COMPILER_SUPPORT_C95_WIDE_CHARACTER__
if( false == dymemarr_insert_array( &arr, 0,
true == wchar ? (void*)(self->strobj.m_wcstr.data)
: (void*)(self->strobj.m_ncstr.data),
true == wchar ? self->strobj.m_wcstr.len
: self->strobj.m_ncstr.len ) )
#else
if( false == dymemarr_insert_array( &arr, 0,
self->strobj.m_ncstr.data,
self->strobj.m_ncstr.len ) )
#endif
{
dymemarr_destroy( &arr );
return false;
}
self->strobj.m_dystr = arr;
self->m_dynamic = true;
return true;
}
/******************************************************************************/
/******************************************************************************/
/* ncstring */
/******************************************************************************/
/******************************************************************************/
void ncstr_init( ncstring* uninit_self )
{
dystr_init( uninit_self );
}
/******************************************************************************/
void ncstr_destroy( ncstring* self )
{
dystr_destroy( self );
}
/******************************************************************************/
int ncstr_init_copy( ncstring* uninit_self, const ncstring* src )
{
return uninit_self == src ? -1 : dystr_init_copy( uninit_self, src );
}
/******************************************************************************/
int ncstr_assign_copy( ncstring* self, const ncstring* src )
{
if( self != src )
{
if( false == self->m_dynamic )
return dystr_init_copy( self, src );
else
{
if( false == src->m_dynamic )
return dymemarr_replace_array( &(self->strobj.m_dystr), 0,
ncstr_size( self ),
src->strobj.m_ncstr.data,
src->strobj.m_ncstr.len );
else
return dymemarr_assign_copy( &(self->strobj.m_dystr),
&(src->strobj.m_dystr) );
}
}
return -1;
}
/******************************************************************************/
void ncstr_init_move( ncstring* uninit_self, ncstring* src )
{
if( uninit_self != src )
dystr_init_move( uninit_self, src );
}
/******************************************************************************/
void ncstr_assign_move( ncstring* self, ncstring* src )
{
if( self != src )
dystr_assign_move( self, src );
}
/******************************************************************************/
bool ncstr_push_back( ncstring* self, const char value )
{
bool result = true;
if( false == self->m_dynamic )
{
if( self->strobj.m_ncstr.len < STATIC_NCSTR_LEN )
{
self->strobj.m_ncstr.data[self->strobj.m_ncstr.len] = value;
++( self->strobj.m_ncstr.len );
return true;
}
else
{
if( false == static_to_dynamic(self, STATIC_NCSTR_LEN + 1, false) )
return false;
}
}
DYMEMARR_PUSH_BACK( self->strobj.m_dystr, value, char, result );
return result;
}
/******************************************************************************/
bool ncstr_reserve( ncstring* self, size_t new_capacity )
{
if( true == self->m_dynamic )
return dymemarr_reserve( &(self->strobj.m_dystr), new_capacity );
else if( STATIC_NCSTR_LEN < new_capacity )
return static_to_dynamic( self, new_capacity, false );
return true;
}
/******************************************************************************/
void ncstr_erase_pos( ncstring* self, size_t index )
{
if( true == self->m_dynamic )
dymemarr_erase_pos( &(self->strobj.m_dystr), index );
else if( index < (size_t)(self->strobj.m_ncstr.len) )
{
if( index + 1 < (size_t)(self->strobj.m_ncstr.len) )
ylib_memcopy( self->strobj.m_ncstr.data + index,
self->strobj.m_ncstr.data + index + 1,
(self->strobj.m_ncstr.len - index) * sizeof(char) );
--( self->strobj.m_ncstr.len );
}
}
/******************************************************************************/
void ncstr_erase_range( ncstring* self, size_t first_index, size_t last_index )
{
if( true == self->m_dynamic )
dymemarr_erase_range( &(self->strobj.m_dystr), first_index, last_index );
else if( first_index < (size_t)(self->strobj.m_ncstr.len)
&& first_index < last_index )
{
if( last_index > (size_t)(self->strobj.m_ncstr.len) )
last_index = self->strobj.m_ncstr.len;
if( last_index < (size_t)(self->strobj.m_ncstr.len) )
ylib_memcopy( self->strobj.m_ncstr.data + first_index,
self->strobj.m_ncstr.data + last_index,
(self->strobj.m_ncstr.len - last_index)
* sizeof(char) );
self->strobj.m_ncstr.len -= (unsigned char)( last_index - first_index );
}
}
/******************************************************************************/
bool ncstr_insert_value( ncstring* self, size_t index, const char value,
size_t count )
{
if( true == self->m_dynamic )
return dymemarr_insert_value( &(self->strobj.m_dystr), index,
&value, count );
else
{
if( self->strobj.m_ncstr.len + count <= STATIC_NCSTR_LEN )
{
ylib_memcopy( self->strobj.m_ncstr.data + index + count,
self->strobj.m_ncstr.data + index,
(self->strobj.m_ncstr.len - index) * sizeof(char) );
ylib_memset( self->strobj.m_ncstr.data + index, value, count );
self->strobj.m_ncstr.len += (unsigned char)count;
}
else
{
if( false == static_to_dynamic(self, self->strobj.m_ncstr.len
+ count, false) )
return false;
return dymemarr_insert_value( &(self->strobj.m_dystr), index,
&value, count );
}
}
return true;
}
/******************************************************************************/
bool ncstr_insert_array( ncstring* self, size_t index, const char* src,
size_t count )
{
if( true == self->m_dynamic )
return dymemarr_insert_array( &(self->strobj.m_dystr), index,
src, count );
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -