tlist.c 14.5 KB
/**    
    @file     tlist.c
    @date     1997/10/7
    @author   유영창 frog@falinux.com  FALinux.Co.,Ltd.
    @brief    Ver 1.0.1
              Delphi 형식의 리스트 객체이다.
              
    @modify   
    		  오재경 (2012/2/7, Ver 1.0.2)
                - tlist_clear() 해제 에러 수정 (아주 중요함)
    
    		  오재경 (2009/1/14, Ver 1.0.1)
                - 인덱스 에러함수 추가
                - 에러일 경우 return 코드 추가
   
    @todo    
    @bug     
    @remark  
    @warning 
*/
//
//  저작권    에프에이리눅스(주)
//            외부공개 금지
//
//----------------------------------------------------------------------------
#define EMBEDDED_LINUX                                          // 이렇게 처리하지 않으면 EClipse에서 C 영역이 회색 바탕이 됨

#ifdef MS_WIN32
    #undef EMBEDDED_LINUX
#endif


#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include <unistd.h>
#include <string.h>

#include <tlist.h>

#ifdef EMBEDDED_LINUX

	#include <sys/resource.h>

#endif


char desc_tlist[] = "falinux tlist ver 1.0.1";

//------------------------------------------------------------------------------
/** @brief   에러함수
    @param   that   관리 객체의 포인터
*///----------------------------------------------------------------------------
void   tlist_error      ( tlist *that )
{
	printf( "tlist error %p\n", that );
//  exit( 1 ); 
}
//------------------------------------------------------------------------------
/** @brief   인덱스 범위에러
    @param   that   관리 객체의 포인터
    @param   index  에러인덱스
*///----------------------------------------------------------------------------
void   tlist_error_index  ( tlist *that, int index )
{
	printf( "tlist error : outof bound  obj=%p count=%d err-index=%d \n", that, that->fcount, index );
//    exit( 1 ); 
}
//------------------------------------------------------------------------------
/** @brief   tlist 객체를 생성한다.
    @return  객체의 포인터
*///----------------------------------------------------------------------------
tlist* tlist_create     ( void )
{
   tlist *that;
   that = ( tlist *) malloc( sizeof( tlist ) );
   if( that )
   {
      that->flist     = NULL;
      that->fcount    = 0;
      that->fcapacity = 0;
   }
   return that;
}

//------------------------------------------------------------------------------
/** @brief   tlist 객체를 소멸시킨다.
    @param   *that 관리 객체의 포인터
*///----------------------------------------------------------------------------
void   tlist_free       ( tlist *that )
{
    tlist_clear( that );
    free( that );
}

//------------------------------------------------------------------------------
/** @brief   아이템을 추가한다.
    @param   that 관리 객체의 포인터
    @param   item 새로이 추가되는 아이템 포인터
    @return  추가된 아이템의 인덱스
*///----------------------------------------------------------------------------
int    tlist_add        ( tlist *that, void *item )
{
     int result;
     result = that->fcount; 
     if( result == that->fcapacity )
     {
       tlist_grow( that );
     }
     that->flist[ result ] = item;
     that->fcount++; 
     return result;
}
//------------------------------------------------------------------------------
/** @brief   모든 아이템을 제거한다.
    @param   that 관리 객체의 포인터
*///----------------------------------------------------------------------------
void   tlist_clear      ( tlist *that )
{
	if ( that->flist )
	{
		free(that->flist);
		that->flist = NULL;
	}
	that->fcount    = 0;
	that->fcapacity = 0;
}
//------------------------------------------------------------------------------
/** @brief   하나의 아이템을 제거한다.
    @param   that 관리 객체의 포인터
    @param   index 제거될 아이템의 인덱스
*///----------------------------------------------------------------------------
void   tlist_delete     ( tlist *that, int index )
{
    if( ( index < 0 ) || ( index >= that->fcount ) ) 
    {
    	tlist_error_index( that, index );
    	return;
    }
    
    that->fcount--;
    if( index < that->fcount ) memmove( &that->flist[ index ], 
                                        &that->flist[ index + 1], 
                                        ( that->fcount - index ) * sizeof( void * ) );
}
//------------------------------------------------------------------------------
/** @brief   2개의 아이템 위치를 교환한다.
    @param   that 관리 객체의 포인터
    @param   index1 교환할 인덱스1
    @param   index2 교환할 인덱스2
*///----------------------------------------------------------------------------
void   tlist_exchange   ( tlist *that, int index1, int index2 )
{
    void *item;

    if(    ( index1 < 0 ) || ( index1 >= that->fcount ) 
        || ( index2 < 0 ) || ( index2 >= that->fcount ) ) 
    {
   		tlist_error( that );
   		return;
   	}
   	
    item = that->flist[ index1 ];
    that->flist[ index1 ] = that->flist[ index2 ];
    that->flist[ index2 ] = item;  
}
//------------------------------------------------------------------------------
/** @brief   아이템 풀의 용량을 확장한다.
    @param   that 관리 객체의 포인터
    @return  객체의 포인터
*///----------------------------------------------------------------------------
tlist *tlist_expand     ( tlist *that )
{
    if( that->fcount == that->fcapacity ) tlist_grow( that );
    return that;
}
//------------------------------------------------------------------------------
/** @brief   첫번째 아이템 포인터를 돌려준다.
    @param   that 관리 객체의 포인터
    @return  첫번째 아이템 포인터
*///----------------------------------------------------------------------------
void  *tlist_first      ( tlist *that )
{
    return tlist_get( that, 0 );
}
//------------------------------------------------------------------------------
/** @brief   인덱스에 해당하는 아이템 포인터를 돌려준다.
    @param   that 관리 객체의 포인터
    @param   index 아이템 인덱스
    @return  인덱스에 해당하는 아이템 포인터
*///----------------------------------------------------------------------------
void*  tlist_get        ( tlist *that, int index )
{
    if( (index<0) || ( index >= that->fcount ) )
    {
    	tlist_error_index( that, index );
    	return NULL;
    }
    return( that->flist[ index ] );
}
//------------------------------------------------------------------------------
/** @brief   아이템이 들어갈 메모리를 증가시킨다.
    @param   that 관리 객체의 포인터
*///----------------------------------------------------------------------------
void   tlist_grow     ( tlist *that )
{
    int delta;
 
    if      ( that->fcapacity > 8 ) delta = 16;
    else if ( that->fcapacity > 4 ) delta =  8;
    else                            delta =  4;
    
    tlist_setcapacity( that, that->fcapacity + delta ); 
}
//------------------------------------------------------------------------------
/** @brief   아이템 포인터가 동일한 포인터의 인덱스를 구한다.
    @param   that 관리 객체의 포인터
    @param   index  아이템 포인터
    @return  아이템 포인터가 해당되는 인덱스
*///----------------------------------------------------------------------------
int    tlist_indexof    ( tlist *that, void *item )
{
    int result;
    result = 0;
    while( ( result < that->fcount ) && ( that->flist[ result ] != item ) ) result++;
    if( result == that->fcount ) result = -1;
    return result;
}
//------------------------------------------------------------------------------
/** @brief   아이템을 특정 위치에 추가한다.
    @param   that 관리 객체의 포인터
    @param   index 추가할 아이템가 들어갈 인덱스
    @param   item  추가할 아이템 포인터
*///----------------------------------------------------------------------------
void   tlist_insert     ( tlist *that, int index, void *item )
{
    if( ( index < 0 ) || ( index > that->fcount ) ) 
    {
    	tlist_error_index( that, index );
    	return;
    }
    	
    if( that->fcount == that->fcapacity ) tlist_grow( that );
    if( index < that->fcount ) memmove( &that->flist[ index + 1], 
                                        &that->flist[ index ], 
                                        ( that->fcount - index ) * sizeof( void * ) );
    that->flist[ index ] = item;
    that->fcount++;
}
//------------------------------------------------------------------------------
/** @brief   마지막 아이템 포인터를 구한다.
    @param   that 관리 객체의 포인터
    @return  마지막 아이템 포인터
*///----------------------------------------------------------------------------
void  *tlist_last       ( tlist *that )
{
    return( tlist_get( that, that->fcount -1 ) );
}
//------------------------------------------------------------------------------
/** @brief   특정 아이템의 위치(인덱스)를 변경한다.
    @param   that 관리 객체의 포인터
    @param   curindex 변경할 아이템의 인덱스
    @param   newindex 변경될 아이템의 인덱스
*///----------------------------------------------------------------------------
void   tlist_move       ( tlist *that, int curindex, int newindex )
{
	void *item; 
	if( curindex != newindex ) 
	{
		if( ( newindex < 0 ) || ( newindex >= that->fcount ) )
		{
			tlist_error_index( that, newindex );
			return;
		}
			 
		item = tlist_get( that, curindex );
		tlist_delete( that, curindex );
		tlist_insert( that, newindex, item );
	} 
}
//------------------------------------------------------------------------------
/** @brief   특정아이템의 포인터를 변경한다.
    @param   that  관리 객체의 포인터
    @param   index 아이템가 변경될 인덱스
    @param   item  새로 변경될 아이템 포인터
*///----------------------------------------------------------------------------
void   tlist_put        ( tlist *that, int index, void *item )
{
	if( (index< 0) || (index>=that->fcount) ) 
	{
		tlist_error_index( that, index );
		return;
	}
	
	that->flist[ index ] = item;
}
//------------------------------------------------------------------------------
/** @brief   인자로 전해준 동일한 아이템 포인터를 찾아 삭제한다.
    @param   that 관리 객체의 포인터
    @param   item 삭제할 아이템의 포인터
    @return  삭제된 아이템의 과거 인덱스
*///----------------------------------------------------------------------------
int    tlist_remove     ( tlist *that, void *item )
{
    int result;
    result = tlist_indexof( that, item );
    if( result != -1 ) tlist_delete( that, result );
    return result;
}
//------------------------------------------------------------------------------
/** @brief   메모리 관리를 위해 사용하지 않는 메모리를 반환한다.
    @param   that 관리 객체의 포인터
    @remark  실제 메모리를 반환하지 않는다.
    @todo    메모리를 반환하도록 재작성되어야 한다.
*///----------------------------------------------------------------------------
void   tlist_pack       ( tlist *that )
{
   int loop;
   for( loop = that->fcount -1; loop >= 0 ; loop-- )
      if( tlist_get( that, loop ) == NULL ) tlist_delete( that, loop );
}
//------------------------------------------------------------------------------
/** @brief   관리할 수 있는 아이템 풀의 용량을 설정하고 메모리를 재 할당한다.
    @param   that 관리 객체의 포인터
    @param   newcapacity 할당해야할 아이템 풀의 용량
*///----------------------------------------------------------------------------
void   tlist_setcapacity( tlist *that, int newcapacity )
{
   	if( ( newcapacity < that->fcount ) || ( newcapacity > MAXLISTSIZE ) ) 
    {
       tlist_error( that );
       return;
    }
    
    if( newcapacity > that->fcapacity )
    {
        that->flist = ( void ** )realloc( that->flist,newcapacity * sizeof( void * ) );
        if( that->flist != NULL ) that->fcapacity = newcapacity;  
    }
}
//------------------------------------------------------------------------------
/** @brief   관리할 수 있는 아이템의 개수를 설정하며 아이템의 개수를 설정된 값으로 변경한다.
    @param   that 관리 객체의 포인터
    @param   newcount 변경되는 아이템의 개수
*///----------------------------------------------------------------------------
void   tlist_setcount   ( tlist *that, int newcount )
{
    if( (newcount < 0) || (newcount > MAXLISTSIZE ) )
    {
    	tlist_error( that ); 
    	return;
    }
    if( newcount > that->fcapacity ) tlist_setcapacity( that, newcount );
    if( newcount > that->fcount ) 
        memset( that->flist[ that->fcount], 0, ( newcount - that->fcount ) * sizeof( void * ));
    that->fcount = newcount; 
}
//------------------------------------------------------------------------------
/** @brief   아이템풀의 크기를 얻는다.
    @param   that 관리 객체의 포인터
    @return  아이템풀의 크기
*///----------------------------------------------------------------------------
int    tlist_getcapacity ( tlist *that )
{
    return that->fcapacity;
}
//------------------------------------------------------------------------------
/** @brief   아이템의 개수를 얻는다.
    @param   that 관리 객체의 포인터
    @return  아이템의 개수
*///----------------------------------------------------------------------------
int    tlist_getcount   ( tlist *that )
{
    return that->fcount;
}
//------------------------------------------------------------------------------
/** @brief   아이템을 사용자 비교함수를 통해 정렬한다.
    @param   that 관리 객체의 포인터
    @param   tlistsortcomparefunc 사용자비교 콜백함수이며, int (*func)(const void *, const void *) 형태이다.
*///----------------------------------------------------------------------------
void   tlist_sort       ( tlist *that,int (*tlistsortcomparefunc)(const void *, const void *) )
{
    if( ( that->flist != NULL ) && ( that->fcount > 0 ) )
        qsort( that->flist, that->fcount,sizeof( void *), tlistsortcomparefunc );
}