📄 kr_object.h
字号:
}
}; // StringBufferNode.
class KREBDLIBS_API StringBuffer {
protected:
SmallArrayList* /* StringBufferNode* */ fList;
public:
DEFINE_NEW(StringBuffer);
DEFINE_DELETE(StringBuffer);
void init(int len) {
SAFE_DELETE(fList);
fList = XNEW(SmallArrayList)(len);
}
int nbOfParts() {
return fList->size();
}
// calling code does not get ownership of the returned string (be it could have it already)
// returned string may be null if null ptr was added.
char* getPart(int i) {
StringBufferNode* node = (StringBufferNode*)fList->get(i);
return node->fString;
}
StringBuffer(int len) {
fList=NULL;
init(len);
}
~StringBuffer();
// s may be null.
StringBuffer* append(char* s, boolean takeOwnership=false){
StringBufferNode* n = XNEW(StringBufferNode)(s, takeOwnership);
fList->add(n);
return this;
}
StringBuffer* append(const char* s, boolean takeOwnership=false){
return append((char*) s, takeOwnership);
}
StringBuffer* append(long v){
char s[50] ;
i2a(v, &s[0]);
return append(xstrdup(s), true);
}
StringBuffer* append(boolean v){
if(v)
return append("true");
else
return append("false");
}
/**
returns ownerhip
*/
char* toString();
}; //StringBuffer.
/*
HashTable
*/
typedef void (*CommandCleaner) (void*) ;
/* CommandCleaner */ KREBDLIBS_API void freeCleaner(void* s);
class HashTableChunk;
class HashTableValue;
class KREBDLIBS_API HashTable {
protected:
int fSize;
HashTableChunk* *fTable;
HashTableChunk* fChunkPool; // pool of removed chunks
unsigned int fWantPoolRemoved: 1; // true if removed chunks should be pooled.
#ifdef DEV_DEBUG
boolean fHashTo3;
#endif
HashTableChunk* getChunk(char* key, int h=0);
HashTableChunk* getAndExtractChunk(char* key, int h=0);
void deleteChunk(HashTableChunk* chunk);
HashTableChunk* makeChunk(char* key, boolean hasKeyOwnership);
virtual int Hash(char* p);
char* toString();
public:
DEFINE_NEW(HashTable);
DEFINE_DELETE(HashTable);
HashTable(int taille);
virtual ~HashTable();
void setWantPool(unsigned int b){
fWantPoolRemoved=b;
}
#ifdef DEV_DEBUG
char* dump();// ATT: SUPPOSE values are char*
void setHashTo3(boolean b){
fHashTo3=b;
}
#endif
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<p></p>
</page>
</kaleidoc>
*/
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<api>
<class>HashTable</class>
<method>put</method>
<cpp> void put(char* key, boolean hasKeyOwnership, void* value, CommandCleaner cleaner, boolean replace=true);)</cpp>
<descr>
<p>Maps the specified key to the specified value in this HashTable.
The value can be retrieved by calling the get method with a key that is strcmp() to the original key.
More than one value can be associated to a particular key using the 'replace' parameter. Ownership of parameters are freely managed with the 'hasKeyOwnership 'and cleaner' parameters. </p>
<itemlist>
<item><p>key: the HashTable key.</p></item>
<item><p>hasKeyOwnership: if true, HashTable will free() the key when needed. If false, it will only be referenced. Another code shuold be in charge of free() if needed.</p></item>
<item><p>value: the value to associate to the key. </p></item>
<item><p>cleaner: a function to call to destroy the value. NULL should be used if the value should not be destroyed. For char* a generic freeCleaner() is available.</p></item>
<item><p>replace: if true, the previous values are replaced with the new one. If false, value is added to the value list of the corresponding key.</p></item>
</itemlist>
<note>The java VM returns the previous value in this case. This is difficult to do it here as the caller may not known the ownership of the returned value. This would make difficult to deal with the value.
More: in a put, getting the previous value is not important most of the time...</note>
</descr>
<examples>
<p>The freeCleaner can be used this way:</p>
<code>HashTable* ht = new HashTable(50);
ht->put("key5", false, xstrdup("key5value"), freeCleaner);
</code>
<p>If the value comes from static memory, owneship cannot be transfered:</p>
<code>ht->put("key5", false,"key5value", NULL);</code>
<p>For class instances, a more complex cleaner should be defined:</p>
<code>class MyClass {
public:
~MyClass() {
Verbose( VERB_LEV_DEBUG, "MyClass Destructor\n");
}
};
void MyClassCleaner(void* o){
MyClass* c = (MyClass*)o;
SAFE_DELETE(c);
}
</code>
<p>More than one value can be added for a particular key:</p>
<code>ht->put("key3", false, "key3valueBis", NULL, false);</code>
<p>Values can be retrived this way:</p>
<code>HashTableValue* v = ht->getValues("key3");
for(HashTableValue* n=v; n; n = n->getLink()) {
char* val = (char*)n->getValue();
Verbose( VERB_LEV_DEBUG, "key3 value: %s\n", val);
}
</code>
</examples>
</api>
</page>
</kaleidoc>
*/
void put(char* key, boolean hasKeyOwnership, void* value, CommandCleaner cleaner, boolean replace=true);
void put(char* key, void* value) {// unpublished shortcut
put(key, false, value, NULL, true);
}
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<api>
<class>HashTable</class>
<method>getValues</method>
<cpp>HashTableValue* getValues(char* key)</cpp>
<descr>
<p>Returns the values to which the specified key is mapped in this HashTable.
The result is a linked list of chunks containing the value itself (as void*) and a link to the next value.
It returns NULL if the key is not mapped to any value in this HashTable.</p>
<p>HashTable does not return the ownership of the HashTableValue.
The ownership of the value included in HashTableValue depends of the result of HashTableValue.getCommandCleaner().</p>
</descr>
<examples>
<p>More than one value can be added for a particular key:</p>
<code>ht->put("key3", false, "key3valueBis", NULL, false);</code>
<p>Values can be retrived this way:</p>
<code>HashTableValue* v = ht->getValues("key3");
for(HashTableValue* n=v; n; n = n->getLink()) {
char* val = (char*)n->getValue();
Verbose( VERB_LEV_DEBUG, "key3 value: %s\n", val);
}
</code>
</examples>
</api>
</page>
</kaleidoc>
!!! can NULL be used as a legal value?
!!! tell about ownership of returned material
*/
HashTableValue* getValues(char* key);
void* get(char* key);
/*
remove(Object key)
Removes the key (and its corresponding value) from this HashTable.
This method does nothing if the key is not in the HashTable.
*/
void remove(char* key);
HashTableValue* take(char* key);
}; //. HashTable
class HashTableValue {
friend class HashTableChunk;
friend class HashTable;
private:
HashTableValue* fLink; // ptr to the next chunk containing the next value for the same key.
void* fVal;
CommandCleaner fCommandCleaner;// cleaner for fVal
public:
DEFINE_NEW(HashTableValue);
DEFINE_DELETE(HashTableValue);
void init() {
fLink=NULL;
fVal=NULL;
fCommandCleaner=NULL;
}
HashTableValue(void* val, CommandCleaner cleaner){
init();
fVal=val;
fCommandCleaner=cleaner;
}
void valDestruction(){
if(fVal && fCommandCleaner)
fCommandCleaner(fVal);
}
~HashTableValue(){
valDestruction();
}
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<api>
<class>HashTableValue</class>
<method>getValue</method>
<cpp>void* getValue()</cpp>
<descr>
<p>Returns the value. The ownership depends of the HashTableValue.getCommandCleaner() result.
If non-NULL this means that the ownership of the value belongs to the HashTableValue object.</p>
</descr>
</api>
</page>
</kaleidoc>
*/
void* getValue() {
return fVal;
}
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<api>
<class>HashTableValue</class>
<method>getLink</method>
<cpp>HashTableValue* getLink()</cpp>
<descr>
<p>Returns the next HashTableValue associated to the same key.
This allows to browse all the values associated to a particular key.</p>
</descr>
</api>
</page>
</kaleidoc>
*/
HashTableValue* getLink() {
return fLink;
}
/*
<kaleidoc>
<filename>HashTable</filename>
<page>
<api>
<class>HashTableValue</class>
<method>getCommandCleaner</method>
<cpp>CommandCleaner getCommandCleaner()</cpp>
<descr>
<p>returns the function used to destroy the value (which is kept as a void*) or NULL if the ownership of value does not belong to the HashTableValue object.</p>
</descr>
</api>
</page>
</kaleidoc>
*/
CommandCleaner getCommandCleaner() {
return fCommandCleaner;
}
#ifdef DEV_DEBUG
char* toString();
#endif
};//.HashTableValue
class HashTableChunk {
public:
HashTableChunk* fCollisionLink; // ptr to the next chunk containing a key which is different but has the same hashcode.
char* fKey;
unsigned int fHasKeyOwnership: 1;
HashTableValue* fValueLink; // ptr to the next chunk containing a key which is different but has the same hashcode.
DEFINE_NEW(HashTableChunk);
DEFINE_DELETE(HashTableChunk);
//void * operator new[](size_t n) { BREAKPOINT; return (void*) 12345; }
void init() {
fCollisionLink=NULL;
fValueLink=NULL;
fKey=NULL;
}
HashTableChunk(char* key, boolean hasKeyOwnership){
init();
fKey=key;
fHasKeyOwnership=hasKeyOwnership;
}
void valDestruction();
void keyDestruction(){
if(fHasKeyOwnership) SAFE_FREE(fKey);
}
void reset() { // called before reusing an object (coming from pool of deleted objected for example)
keyDestruction();
valDestruction();
init();
}
~HashTableChunk(){
reset();
}
HashTableValue* getValues() {
return fValueLink;
}
void putValue(void* value, CommandCleaner cleaner, boolean replace);
#ifdef DEV_DEBUG
char* toString();
#endif
};//.HashTableChunk
#endif // __KR_Object__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -