campo-sirio/include/assoc.cpp
guy 3e793a4cab applicat.cpp Gestione semplificata dei bar_item
array.cpp      Corretti TPointer_array
assoc.cpp      Aggiuntta add()
cfiles.c       Corretto salvataggio pathpref.ini
controls.cpp   Aggiunto attributo di read_only
default.url    Aggiunto menu di edit ed help
mask.cpp       Gestione menu edit
maskfld.cpp    Gestione menu edit
msksheet.cpp   Gestione menu edit
progind.cpp    Aggiunto nuova scavatura 3D
sheet.cpp
viswin.cpp     Aggiornati ID del menu edit
window.cpp     Corretta gestione voci di menu standard
xvtility.cpp   Aggiunto metodo per skippare gli errori di XVT


git-svn-id: svn://10.65.10.50/trunk@5791 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-12-24 14:26:25 +00:00

357 lines
9.0 KiB
C++
Executable File

#include <assoc.h>
// @ccost:(INTERNAL) HASH_SIZE | 10883 | Dimensione della tabella hash
const int HASH_SIZE = 10883;
TArray& TAssoc_array::bucket(int index)
{
TArray* arr = (TArray*)_bucket.objptr(index);
if (arr == NULL)
{
arr = new TArray;
_bucket.add(arr, index);
}
return *arr;
}
// @doc EXTERNAL
// @mfunc Cerca l'oggetto con chiave <p k>
//
// @rdesc Ritorna l'oggetto corrispondente alla chiave passate come parametro.
// <nl>Il parametro <p isnew> assume il valore TRUE se si tratta di un
// nuovo oggetto.
THash_object* TAssoc_array::_lookup(
const char* k, // @parm Chiave da cercare
bool& isnew, // @parm Viene assegnato TRUE se si tratta di una nuova chiave
bool insert) // @parm Permette di inserire la chiave
// @comm Ricerca all'interno della tabella hash l'oggetto con la chiave <p k>,
// nel caso non venga trovato <p isnew> ritorna TRUE (si tratta di un
// oggetto nuovo) e viene inserito nella tabella se il parametro <p insert>
// e' settato a TRUE.
{
const TFixed_string key(k);
const word hv = key.hash() % HASH_SIZE;
TArray& arr = bucket(hv);
THash_object* o = NULL;
isnew = FALSE;
for (int i = 0; i < arr.items(); i++)
{
THash_object* ob = (THash_object*)arr.objptr(i);
if (ob->_key == key)
{ o = ob; break; }
if (ob->_key > key)
break;
}
if (o == NULL)
{
if (insert)
{
o = new THash_object(key);
arr.insert(o,i);
_cnt++;
}
isnew = TRUE;
}
return o;
}
void TAssoc_array::destroy()
{
_bucket.destroy();
_cnt = _row = _col = 0;
_rowitem = _colitem = 0;
}
TObject* TAssoc_array::first_item()
{
_rowitem = _colitem = 0;
return succ_item();
}
TObject* TAssoc_array::last_item()
{
_rowitem = _bucket.last();
if( _rowitem < 0 )
return NULL;
_colitem = bucket(_rowitem).items() - 1;
return pred_item( );
}
TObject* TAssoc_array::succ_item()
{
const TArray* arr = (const TArray*)_bucket.objptr(_rowitem);
while (_rowitem < HASH_SIZE)
{
if (arr && (int)_colitem < arr->items())
break;
_rowitem = _bucket.succ(_rowitem);
if (_rowitem < HASH_SIZE)
{
arr = (TArray*)_bucket.objptr(_rowitem);
_colitem = 0;
}
}
if (_rowitem >= HASH_SIZE)
return NULL;
THash_object* o = (THash_object*)arr->objptr(_colitem++);
return (o == NULL || o->_obj == NULL) ? NULL : o->_obj;
}
TObject* TAssoc_array::pred_item()
{
const TArray* arr = (const TArray*)_bucket.objptr(_rowitem);
while (_rowitem >= 0)
{
if (arr && (int)_colitem >= 0)
break;
_rowitem = _bucket.pred(_rowitem);
if (_rowitem >= 0)
{
arr = (TArray*)_bucket.objptr(_rowitem);
_colitem = arr->items()-1;
}
}
if (_rowitem < 0 )
return NULL;
THash_object* o = (THash_object*)arr->objptr(_colitem--);
return (o == NULL || o->_obj == NULL) ? NULL : o->_obj;
}
// @doc EXTERNAL
// @mfunc Aggiunge un oggetto all'array.
// @rdesc Ritorna TRUE se esisteva gia' un elemento con la stessa chiave
bool TAssoc_array::add(
const char* key, // @parm Chiave d'ordinamento
TObject* obj, // @parm Ogetto da inserire (default=NULL)
bool force) // @parm Permette di forzare l'inserimento se esiste gia'
// un oggetto con la stessa chiave
// @parm const TObject | &obj | Indirizzo dell'oggetto da aggiungere
//
// @syntax add(const char* key, TObject* obj, bool force)
// @syntax add(const char* key, const TObject& obj, bool force)
//
// @comm Se l'oggetto da aggiungere esite gia' la chiave guarda il parametro <p force>:
// <nl>se <p force> = TRUE lo sostituisce e ritorna TRUE,
// <nl>se <p force> = FALSE non sostituisce e ritorna TRUE,
// <nl>altrimenti ritorna FALSE.
// <nl><nl>Nel caso l'oggetto da aggiungere venga passato per indirizzo
// la funzione aggiunge una copia dell'oggetto e quindi deve essere
// definita <mf TObject::dup>
{
bool isnew = FALSE;
THash_object* o = _lookup(key,isnew,TRUE);
if (!isnew)
{
if (force)
{
if (o->_obj != NULL)
delete o->_obj;
o->_obj = obj;
}
return TRUE;
}
o->_obj = obj;
return FALSE;
}
bool TAssoc_array::add(const char* key, const TObject& obj, bool force)
{
// Non inserire l'Hash_object se non lo trovi (ci pensa la add sotto)
bool isnew = FALSE;
THash_object* o = _lookup(key,isnew,FALSE);
if (!isnew && !force)
return TRUE;
return add(key,obj.dup(),force);
}
// @doc EXTERNAL
// @mfunc Elimina un oggetto.
// @rdesc Ritorna il risultato dell'operazione
//
// @flag TRUE | Eliminazione avvenuta
// @flag FALSE | L'oggetto non e' stato trovato
bool TAssoc_array::remove(
const char* k) // @parm Chiave dell'oggetto da eliminare
// @comm Cerca nella tabella hash l'oggetto con chiave <p k> e lo elimina.
{
const TFixed_string key(k);
const word hv = key.hash() % HASH_SIZE;
TArray& arr = bucket(hv);
THash_object* o = NULL;
for (int i = 0; i < arr.items(); i++)
{
THash_object* ob = (THash_object*)&arr[i];
if (ob->_key == key)
{ o = ob; break; }
if (ob->_key > key)
break;
}
if (o != NULL)
{
arr.destroy(i,TRUE);
_cnt--;
return TRUE;
}
return FALSE;
}
// @doc EXTERNAL
// @mfunc Trova l'oggetto indicizzato
//
// @rdesc Ritorna l'oggetto cercato. Se l'oggetto non viene trovato
// ritorna un errore
TObject& TAssoc_array::find(
const char* key) const // @parm Chiave dell'oggetto da trovare
// @comm Cerca l'oggetto indicizzato con chiave <p key>. Viene controllato se
// non c'e' (normalmente si usa operator[key])
{
/* Guy ruined this
bool isnew = FALSE;
THash_object* o = _lookup(key, isnew);
if (o == NULL) error_box("INTERNAL (HASH): Unref key");
if (o->_obj == NULL) return error;
else return *(o->_obj);
*/
TObject* o = objptr(key);
CHECKS(o, "Can't find hash object with key ", key);
return *o;
}
// @doc EXTERNAL
// @mfunc Ritorna l'oggetto con chiave <p key>
// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna NULL
TObject* TAssoc_array::objptr(
const char* key) const // @parm Chiave dell'oggetto da ritornare
{
bool isnew = FALSE;
THash_object* o = ((TAssoc_array*)this)->_lookup(key,isnew);
return o ? o->_obj : NULL;
}
// @doc EXTERNAL
// @mfunc Controlla l'esistenza di una chiave
//
// @rdesc Ritorna il risultato della ricerca
//
// @flag TRUE | Se la chiave esiste
// @flag FALSE | Se la chiave non esiste
bool TAssoc_array::is_key(
const char* key) const // @parm Chiave da cercarne l'esistenza
{
bool isnew = FALSE;
THash_object* o = ((TAssoc_array *)this)->_lookup(key,isnew);
return o != NULL;
}
// @doc EXTERNAL
// @mfunc Ritorna solo l'oggetto
//
// @rdesc Ritorna il puntatore all'oggetto (se diverso da NULL), altrimenti
// ritorna error object
TObject* TAssoc_array::get()
// @xref <mf TAssoc_array::get_hashobj>
{
const TArray* arr = (const TArray*)_bucket.objptr(_row);
while(_row < HASH_SIZE)
{
if (arr && (int)_col < arr->items())
break;
_row = _bucket.succ(_row);
arr = (const TArray*)_bucket.objptr(_row);
_col = 0;
}
if (_row >= HASH_SIZE)
{
_row = 0;
return NULL;
}
THash_object* o = (THash_object*)arr->objptr(_col++);
return (o == NULL || o->_obj == NULL) ? &error : o->_obj;
}
// @doc EXTERNAL
// @mfunc Ritorna l'oggetto e la relativa chiave
//
// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna NULL
THash_object* TAssoc_array::get_hashobj()
// @comm Se l'oggetto viene trovato viene richiamata la funzione
// <mf TAssoc_array::objptr>
//
// @xref <mf TAssoc_array::get>
{
const TArray* arr = (const TArray*)_bucket.objptr(_row);
while(_row < HASH_SIZE)
{
if (arr && (int)_col < arr->items())
break;
_row = _bucket.succ(_row);
arr = (const TArray*)_bucket.objptr(_row);
_col = 0;
}
if (_row >= HASH_SIZE)
{
_row = 0;
return NULL;
}
return (THash_object*)arr->objptr(_col++);
}
// mette chiavi e opzionalmente valori (come stringa) nel
// TString_array passato
int TAssoc_array::get_keys(TString_array& kl, bool add_values)
{
kl.destroy();
restart();
THash_object* o = NULL;
TString tmp(80);
while (o = get_hashobj())
{
TToken_string* tt = new TToken_string(o->key());
if (add_values)
{
tmp = "";
tmp << o->obj();
tt->add(tmp);
}
kl.add(tt);
}
restart();
return kl.items();
}
// @doc INTERNAL
// @mfunc Copia tutto l'array e ne duplica gli elementi
//
TAssoc_array & TAssoc_array::copy(
const TAssoc_array & a) // @parm Array associativo sorgente
{
destroy();
TAssoc_array& from = (TAssoc_array&)a;
from.restart();
for (THash_object* obj = from.get_hashobj(); obj; obj = from.get_hashobj())
add(obj->key(), obj->obj(), TRUE);
return * this;
}