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
357 lines
9.0 KiB
C++
Executable File
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;
|
|
}
|
|
|