assoc.cpp Stessa roba object.h Aggiunti distruttori virtuali printapp.cpp Sostituito == -1 con < 0 nei metodi set/get_cursor relation.cpp Riportate modifiche suggerite da Angelo string.* Aggiunti distruttori virtuali git-svn-id: svn://10.65.10.50/trunk@3740 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			341 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <assoc.h>
 | |
| 
 | |
| // @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 = _data[hv];
 | |
|   THash_object* o = NULL;
 | |
|   isnew = FALSE;
 | |
| 
 | |
|   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 && insert) 
 | |
|   { 
 | |
|     o = new THash_object(key);
 | |
|     arr.insert(o,i); 
 | |
|     isnew = TRUE;
 | |
|     _cnt++;
 | |
|   }
 | |
|   
 | |
|   return o;
 | |
| }
 | |
| 
 | |
| void TAssoc_array::destroy()
 | |
| {
 | |
|   for (int i = 0; i < HASH_SIZE; i++)
 | |
|     _data[i].destroy();
 | |
|   _cnt = _row = _col = 0;
 | |
| }
 | |
| 
 | |
| TObject* TAssoc_array::first_item( )
 | |
| {
 | |
|   _rowitem = 0;
 | |
|   _colitem = 0;
 | |
|   return succ_item( );
 | |
| }
 | |
| 
 | |
| TObject* TAssoc_array::last_item( )
 | |
| {
 | |
|   _rowitem = HASH_SIZE - 1;
 | |
|   while( _rowitem >= 0 && _data[ _rowitem ].items() == 0 )
 | |
|     _rowitem --;
 | |
|   if( _rowitem < 0 )           
 | |
|     return NULL;
 | |
|   const TArray* arr = &_data[_rowitem];  
 | |
|   _colitem = arr->items( ) - 1;
 | |
|   return pred_item( );
 | |
| }
 | |
| 
 | |
| 
 | |
| TObject* TAssoc_array::succ_item( )
 | |
| {
 | |
|   const TArray* arr = &_data[_rowitem];
 | |
|   
 | |
|   for(;_rowitem < HASH_SIZE;)
 | |
|   {
 | |
|     if ((int)_colitem < arr->items()) 
 | |
|       break;
 | |
|     arr = &_data[++_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 = &_data[_rowitem];
 | |
|   
 | |
|   for(;_rowitem >= 0;)
 | |
|   {
 | |
|     if ((int)_colitem >= 0 ) 
 | |
|       break;
 | |
|     _rowitem --;
 | |
|     while( _rowitem >= 0 && _data[ _rowitem ].items( ) == 0 )
 | |
|       _rowitem --;
 | |
|     if (_rowitem < 0 )
 | |
|       return NULL;      
 | |
|     arr = &_data[ _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)
 | |
| {
 | |
|   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 = _data[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) // @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);
 | |
|   if (o != NULL)
 | |
|     return o->_obj;
 | |
|   return 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 = &_data[_row];
 | |
|   
 | |
|   for(;_row < HASH_SIZE;)
 | |
|   {
 | |
|     if ((int)_col < arr->items()) 
 | |
|       break;
 | |
|     arr = &_data[++_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 = &_data[_row];
 | |
|   
 | |
|   for(;_row < HASH_SIZE;)
 | |
|   {
 | |
|     if ((int)_col < arr->items()) 
 | |
|       break;
 | |
|     arr = &_data[++_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;
 | |
| }
 | |
| 
 |