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

📄 yc_string.c

📁 一个类STL的多平台可移植的算法容器库,主要用于嵌入式系统编程时的内存管理等方面
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * 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 + -