diff options
-rw-r--r-- | Changelog-Trunk.txt | 1 | ||||
-rw-r--r-- | src/common/db.h | 286 |
2 files changed, 287 insertions, 0 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 8288e11df..c120c17e4 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,7 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/12/23 + * Added a generic vector implementation (dynamic array) based on defines. [FlavioJS] * Fixed horrible handling of skill_abra_db which leads to memory corruption (depending on the contents of yor abra_db.txt file) [Skotlex] 2007/12/22 diff --git a/src/common/db.h b/src/common/db.h index ecaed67af..30948b0cb 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -848,4 +848,290 @@ void linkdb_final ( struct linkdb_node** head ); +///////////////////////////////////////////////////////////////////// +// Vector library based on defines. (dynamic array) +// uses aMalloc, aRealloc, aFree + + + +/// Declares a named vector struct. +/// +/// @param __name Structure name +/// @param __type Type of data +#define VECTOR_STRUCT(__name,__type) \ + struct __name { \ + size_t _max_; \ + size_t _len_; \ + __type* _data_; \ + } + + + +/// Declares a named vector struct variable. +/// +/// @param __name Structure name +/// @param __var Variable name +#define VECTOR_STRUCT_VAR(__name,__var) \ + struct __name __var = {0,0,NULL} + + + +/// Declares a vector variable with an anonymous struct. +/// +/// @param __type Type of data +/// @param __var Variable name +#define VECTOR_VAR(__type,__var) \ + struct { \ + size_t _max_; \ + size_t _len_; \ + __type* _data_; \ + } __var = {0,0,NULL} + + + +/// Returns the internal array of values. +/// +/// @param __vec Vector +/// @return Array of values +#define VECTOR_DATA(__vec) \ + ( (__vec)._data_ ) + + + +/// Returns the length of the vector. +/// +/// @param __vec Vector +/// @return Length +#define VECTOR_LENGTH(__vec) \ + ( (__vec)._len_ ) + + + +/// Returns the capacity of the vector. +/// +/// @param __vec Vector +/// @return Capacity +#define VECTOR_CAPACITY(__vec) \ + ( (__vec)._max_ ) + + + +/// Returns the value at the target index. +/// Assumes the index exists. +/// +/// @param __vec Vector +/// @param __idx Index +/// @return Value +#define VECTOR_INDEX(__vec,__idx) \ + ( VECTOR_DATA(__vec)[__idx] ) + + + +/// Returns the first value of the vector. +/// Assumes the array is not empty. +/// +/// @param __vec Vector +/// @return First value +#define VECTOR_FIRST(__vec) \ + ( VECTOR_INDEX(__vec,0) ) + + + +/// Returns the last value of the vector. +/// Assumes the array is not empty. +/// +/// @param __vec Vector +/// @return Last value +#define VECTOR_LAST(__vec) \ + ( VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)-1) ) + + + +/// Resizes the vector. +/// Excess values are discarded, new positions are zeroed. +/// +/// @param __vec Vector +/// @param __n Size +#define VECTOR_RESIZE(__vec,__n) \ + do{ \ + if( (__n) > VECTOR_CAPACITY(__vec) ) \ + { /* increase size */ \ + if( VECTOR_CAPACITY(__vec) == 0 ) VECTOR_DATA(__vec) = aMalloc((__n)*sizeof(VECTOR_FIRST(__vec))); /* allocate new */ \ + else VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \ + memset(VECTOR_DATA(__vec)+VECTOR_LENGTH(__vec), 0, (VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec))*sizeof(VECTOR_FIRST(__vec))); /* clear new data */ \ + VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \ + } \ + else if( (__n) == 0 && VECTOR_CAPACITY(__vec) ) \ + { /* clear vector */ \ + aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* free data */ \ + VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \ + VECTOR_LENGTH(__vec) = 0; /* clear length */ \ + } \ + else if( (__n) < VECTOR_CAPACITY(__vec) ) \ + { /* reduce size */ \ + VECTOR_DATA(__vec) = aRealloc(VECTOR_DATA(__vec),(__n)*sizeof(VECTOR_FIRST(__vec))); /* reallocate */ \ + VECTOR_CAPACITY(__vec) = (__n); /* update capacity */ \ + if( VECTOR_LENGTH(__vec) > (__n) ) VECTOR_LENGTH(__vec) = (__n); /* update length */ \ + } \ + }while(0) + + + +/// Ensures that the array has the target number of empty positions. +/// Increases the capacity in multiples of __step. +/// +/// @param __vec Vector +/// @param __n Empty positions +/// @param __step Increase +#define VECTOR_ENSURE(__vec,__n,__step) \ + do{ \ + size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \ + while( (__n) > _empty_ ) _empty_ += (__step); \ + if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \ + }while(0) + + + +/// Inserts a value in the target index. (using the '=' operator) +/// Assumes the index is valid and there is enough capacity. +/// +/// @param __vec Vector +/// @param __idx Index +/// @param __val Value +#define VECTOR_INSERT(__vec,__idx,__val) \ + do{ \ + if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \ + memmove(&VECTOR_INDEX(__vec,(__idx)+1),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \ + VECTOR_INDEX(__vec,__idx) = (__val); /* set value */ \ + ++VECTOR_LENGTH(__vec); /* increase length */ \ + }while(0) + + + +/// Inserts a value in the target index. (using memcpy) +/// Assumes the index is valid and there is enough capacity. +/// +/// @param __vec Vector +/// @param __idx Index +/// @param __val Value +#define VECTOR_INSERTCOPY(__vec,__idx,__val) \ + VECTOR_INSERTARRAY(__vec,__idx,&(__val),1) + + + +/// Inserts the values of the array in the target index. (using memcpy) +/// Assumes the index is valid and there is enough capacity. +/// +/// @param __vec Vector +/// @param __idx Index +/// @param __pval Array of values +/// @param __n Number of values +#define VECTOR_INSERTARRAY(__vec,__idx,__pval,__n) \ + do{ \ + if( (__idx) < VECTOR_LENGTH(__vec) ) /* move data */ \ + memmove(&VECTOR_INDEX(__vec,(__idx)+(__n)),&VECTOR_INDEX(__vec,__idx),(VECTOR_LENGTH(__vec)-(__idx))*sizeof(VECTOR_FIRST(__vec))); \ + memcpy(&VECTOR_INDEX(__vec,__idx), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \ + VECTOR_LENGTH(__vec) += (__n); /* increase length */ \ + }while(0) + + + +/// Inserts a value in the end of the vector. (using the '=' operator) +/// Assumes there is enough capacity. +/// +/// @param __vec Vector +/// @param __val Value +#define VECTOR_PUSH(__vec,__val) \ + do{ \ + VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)) = (__val); /* set value */ \ + ++VECTOR_LENGTH(__vec); /* increase length */ \ + }while(0) + + + +/// Inserts a value in the end of the vector. (using memcpy) +/// Assumes there is enough capacity. +/// +/// @param __vec Vector +/// @param __val Value +#define VECTOR_PUSHCOPY(__vec,__val) \ + VECTOR_PUSHARRAY(__vec,&(__val),1) + + + +/// Inserts the values of the array in the end of the vector. (using memcpy) +/// Assumes there is enough capacity. +/// +/// @param __vec Vector +/// @param __pval Array of values +/// @param __n Number of values +#define VECTOR_PUSHARRAY(__vec,__pval,__n) \ + do{ \ + memcpy(&VECTOR_INDEX(__vec,VECTOR_LENGTH(__vec)), (__pval), (__n)*sizeof(VECTOR_FIRST(__vec))); /* set values */ \ + VECTOR_LENGTH(__vec) += (__n); /* increase length */ \ + }while(0) + + + +/// Removes and returns the last value of the vector. +/// Assumes the array is not empty. +/// +/// @param __vec Vector +/// @return Removed value +#define VECTOR_POP(__vec) \ + ( VECTOR_INDEX(__vec,--VECTOR_LENGTH(__vec)) ) + + + +/// Removes the last N values of the vector and returns the value of the last pop. +/// Assumes there are enough values. +/// +/// @param __vec Vector +/// @param __n Number of pops +/// @return Last removed value +#define VECTOR_POPN(__vec,__n) \ + ( VECTOR_INDEX(__vec,(VECTOR_LENGTH(__vec)-=(__n))) ) + + + +/// Removes the target index from the vector. +/// Assumes the index is valid and there are enough values. +/// +/// @param __vec Vector +/// @param __idx Index +#define VECTOR_ERASE(__vec,__idx) \ + VECTOR_ERASEN(__vec,__idx,1) + + + +/// Removes N values from the target index of the vector. +/// Assumes the index is valid and there are enough values. +/// +/// @param __vec Vector +/// @param __idx Index +/// @param __n Number of values +#define VECTOR_ERASEN(__vec,__idx,__n) \ + do{ \ + if( (__idx) < VECTOR_LENGTH(__vec)-(__n) ) /* move data */ \ + memmove(&VECTOR_INDEX(__vec,__idx),&VECTOR_INDEX(__vec,(__idx)+(__n)),(VECTOR_LENGTH(__vec)-((__idx)+(__n)))*sizeof(VECTOR_FIRST(__vec))); \ + VECTOR_LENGTH(__vec) -= (__n); /* decrease length */ \ + }while(0) + + + +/// Clears the vector, freeing allocated data. +/// +/// @param __vec Vector +#define VECTOR_CLEAR(__vec) \ + do{ \ + if( VECTOR_CAPACITY(__vec) ) \ + { \ + aFree(VECTOR_DATA(__vec)); VECTOR_DATA(__vec) = NULL; /* clear allocated array */ \ + VECTOR_CAPACITY(__vec) = 0; /* clear capacity */ \ + VECTOR_LENGTH(__vec) = 0; /* clear length */ \ + } \ + }while(0) + + + #endif /* _DB_H_ */ |