/** @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 #include #include #include #include #include #ifdef EMBEDDED_LINUX #include #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 ); }