Patch level : 2.0
Files correlati : Omnia0.exe Ricompilazione Demo : [ ] Commento : Prima versione del traduttore universale git-svn-id: svn://10.65.10.50/trunk@11690 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
f577cf2f07
commit
c95157e55e
240
omnia/Omnia0.cpp
Executable file
240
omnia/Omnia0.cpp
Executable file
@ -0,0 +1,240 @@
|
||||
#include <windows.h>
|
||||
#include <fstream.h>
|
||||
|
||||
#include "utility.h"
|
||||
#include "xml.h"
|
||||
|
||||
class TLettore : public TObject
|
||||
{
|
||||
TXmlItem _trc;
|
||||
|
||||
int _lines, _chars;
|
||||
TString _rseparator, _fseparator;
|
||||
TString_array _curr;
|
||||
|
||||
protected:
|
||||
bool load_trc(const char* trc);
|
||||
|
||||
char* get_line_buffer(int i, int size);
|
||||
bool read_record(istream& input);
|
||||
const TString& get_field(const TXmlItem& field) const;
|
||||
const TXmlItem* find_field(const TXmlItem& record, const TString& name) const;
|
||||
void evaluate(const TString& expr, const TXmlItem& recin, TString& val) const;
|
||||
void smart_trim(TString& val, int mode) const;
|
||||
|
||||
public:
|
||||
int convert(const TFilename& src, const TFilename& trc, const TFilename& dst);
|
||||
int convert(const char* cmd);
|
||||
};
|
||||
|
||||
bool TLettore::load_trc(const char* t)
|
||||
{
|
||||
const TFilename trc = t;
|
||||
bool ok = trc.exist();
|
||||
if (ok)
|
||||
{
|
||||
ifstream in(trc);
|
||||
ok = _trc.Read(in);
|
||||
}
|
||||
_curr.destroy(); // reset line sizes
|
||||
return ok;
|
||||
}
|
||||
|
||||
char* TLettore::get_line_buffer(int i, int size)
|
||||
{
|
||||
TToken_string* str = (TToken_string*)_curr.objptr(i);
|
||||
if (str == NULL)
|
||||
{
|
||||
str = new TToken_string(size);
|
||||
_curr.add(str, i);
|
||||
}
|
||||
char* buff = str->get_buffer(size);
|
||||
*buff = '\0';
|
||||
return buff;
|
||||
}
|
||||
|
||||
bool TLettore::read_record(istream& input)
|
||||
{
|
||||
bool ok = true;
|
||||
if (_lines <= 1 && _chars > 0) // Record a lunghezza fissa
|
||||
{
|
||||
char* buff = get_line_buffer(0, _chars);
|
||||
input.read(buff, _chars);
|
||||
buff[_chars] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = _chars;
|
||||
if (size <= 0)
|
||||
size = 1024;
|
||||
for (int i = 0; i < _lines; i++)
|
||||
{
|
||||
char* buff = get_line_buffer(i, size);
|
||||
input.getline(buff, size);
|
||||
buff[size] = '\0';
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
const TString& TLettore::get_field(const TXmlItem& field) const
|
||||
{
|
||||
int y = field.GetIntAttr("Y" ) - 1;
|
||||
if (y < 0) y = 0;
|
||||
|
||||
int x = field.GetIntAttr("X" ) - 1;
|
||||
if (x < 0) x = 0;
|
||||
|
||||
int l = field.GetIntAttr("Length");
|
||||
|
||||
const TString& str = _curr.row(y).mid(x, l);
|
||||
return str;
|
||||
}
|
||||
|
||||
void TLettore::smart_trim(TString& val, int mode) const
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 1: val.rtrim(); break;
|
||||
case 2: val.ltrim(); break;
|
||||
case 3: val.trim(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
const TXmlItem* TLettore::find_field(const TXmlItem& record, const TString& name) const
|
||||
{
|
||||
for (int i = 0; i < record.GetChildren(); i++)
|
||||
{
|
||||
const TXmlItem* field = record.GetChild(i);
|
||||
if (field->GetAttr("Name") == name)
|
||||
return field;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TLettore::evaluate(const TString& expr, const TXmlItem& recin, TString& val) const
|
||||
{
|
||||
TToken_string expression(expr, '+');
|
||||
val.cut(0);
|
||||
TString str;
|
||||
FOR_EACH_TOKEN(expression, tok)
|
||||
{
|
||||
str = tok; str.trim();
|
||||
if (str[0] == '\'' || str[0] == '"')
|
||||
{
|
||||
str.rtrim(1); str.ltrim(1);
|
||||
val << str;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool trim = false;
|
||||
if (str.starts_with("TRIM("))
|
||||
{
|
||||
str.ltrim(5); str.rtrim(1);
|
||||
str.trim();
|
||||
trim = true;
|
||||
}
|
||||
|
||||
const TXmlItem* infield = find_field(recin, str);
|
||||
if (infield != NULL)
|
||||
{
|
||||
str = get_field(*infield);
|
||||
if (trim)
|
||||
str.trim();
|
||||
val << str;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TLettore::convert(const TFilename& src, const TFilename& trc, const TFilename& dst)
|
||||
{
|
||||
if (!src.exist())
|
||||
{
|
||||
error_box("Non esiste il file di input\n%s", (const char*)src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!load_trc(trc))
|
||||
{
|
||||
error_box("Non esiste il tracciato record\n%s", (const char*)trc);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (dst.blank())
|
||||
{
|
||||
error_box("File di output non valido:\n%s", (const char*)dst);
|
||||
return 3;
|
||||
}
|
||||
|
||||
const TXmlItem* infile = _trc.FindFirst("Input");
|
||||
const TXmlItem* outfile = _trc.FindFirst("Output");
|
||||
if (infile == NULL || outfile == NULL)
|
||||
{
|
||||
error_box("Tracciato record non valido:\nNon esiste il tag <Input> o <Output>");
|
||||
return 4;
|
||||
}
|
||||
|
||||
const TXmlItem* recin = infile->FindFirst("Record");
|
||||
const TXmlItem* recout = outfile->FindFirst("Record");
|
||||
if (recin == NULL || recout == NULL)
|
||||
{
|
||||
error_box("Tracciato record non valido:\nNon esiste il tag <Record>");
|
||||
return 4;
|
||||
}
|
||||
|
||||
_lines = recin->GetIntAttr("Lines");
|
||||
if (_lines <= 0)
|
||||
_lines = 1;
|
||||
|
||||
_chars = recin->GetIntAttr("Chars");
|
||||
|
||||
_rseparator = esc(outfile->GetAttr("RecordSeparator"));
|
||||
_fseparator = esc(recout->GetAttr("FieldSeparator"));
|
||||
|
||||
const int inmode = infile->GetIntAttr("Binary") != 0 ? (ios::in|ios::binary) : ios::in;
|
||||
ifstream input(src, inmode);
|
||||
|
||||
const int outmode = outfile->GetIntAttr("Binary") != 0 ? (ios::out|ios::binary) : ios::out;
|
||||
ofstream output(dst, outmode);
|
||||
|
||||
TString expr, val;
|
||||
while (!input.eof())
|
||||
{
|
||||
read_record(input);
|
||||
for (int i = 0; i < recout->GetChildren(); i++)
|
||||
{
|
||||
const TXmlItem* outfield = recout->GetChild(i);
|
||||
outfield->GetEnclosedText(expr);
|
||||
if (expr.empty())
|
||||
expr = outfield->GetAttr("Name");
|
||||
evaluate(expr, *recin, val);
|
||||
smart_trim(val, outfield->GetIntAttr("Trim"));
|
||||
if (i > 0)
|
||||
output << _fseparator;
|
||||
output << val;
|
||||
}
|
||||
output << _rseparator;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TLettore::convert(const char* cmd)
|
||||
{
|
||||
TToken_string str(cmd, ' ');
|
||||
str.strip_d_spaces();
|
||||
const TFilename src = str.get();
|
||||
const TFilename trc = str.get();
|
||||
const TFilename dst = str.get();
|
||||
return convert(src, trc, dst);
|
||||
}
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
{
|
||||
TLettore app;
|
||||
const int err = app.convert(lpCmdLine);
|
||||
return err;
|
||||
}
|
877
omnia/array.cpp
Executable file
877
omnia/array.cpp
Executable file
@ -0,0 +1,877 @@
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "strings.h"
|
||||
|
||||
void TContainer::for_each( OPERATION_FUNCTION op )
|
||||
{
|
||||
TObject* curr = first_item();
|
||||
while(curr)
|
||||
{
|
||||
op(*curr);
|
||||
curr = succ_item();
|
||||
}
|
||||
}
|
||||
|
||||
void TContainer::for_each_that( OPERATION_FUNCTION op, CONDITION_FUNCTION match )
|
||||
{
|
||||
TObject* curr = first_that( match );
|
||||
while( curr )
|
||||
{
|
||||
op( *curr );
|
||||
curr = succ_that( );
|
||||
}
|
||||
}
|
||||
|
||||
TObject* TContainer::first_that( CONDITION_FUNCTION match )
|
||||
{
|
||||
_last_condition = match;
|
||||
if( _last_condition )
|
||||
{
|
||||
TObject* curr = first_item( );
|
||||
while( curr && !_last_condition( *curr ) )
|
||||
curr = succ_item( );
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
return first_item( );
|
||||
}
|
||||
|
||||
TObject* TContainer::last_that( CONDITION_FUNCTION match )
|
||||
{
|
||||
_last_condition = match;
|
||||
if( _last_condition )
|
||||
{
|
||||
TObject* curr = last_item( );
|
||||
while( curr && !_last_condition( *curr ) )
|
||||
curr = pred_item( );
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
return last_item( );
|
||||
}
|
||||
|
||||
TObject* TContainer::succ_that( )
|
||||
{
|
||||
if( _last_condition )
|
||||
{
|
||||
TObject* curr = succ_item( );
|
||||
while( curr && !_last_condition( *curr ) )
|
||||
curr = succ_item( );
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
return succ_item( );
|
||||
}
|
||||
|
||||
TObject* TContainer::pred_that( )
|
||||
{
|
||||
if( _last_condition )
|
||||
{
|
||||
TObject* curr = pred_item( );
|
||||
while( curr && !_last_condition( *curr ) )
|
||||
curr = pred_item( );
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
return pred_item( );
|
||||
}
|
||||
|
||||
long TContainer::count( CONDITION_FUNCTION match )
|
||||
{
|
||||
long c = 0;
|
||||
TObject* curr = first_item( );
|
||||
while( curr )
|
||||
if( match( *curr ) )
|
||||
c++;
|
||||
return c;
|
||||
}
|
||||
|
||||
TObject* TArray::first_item( )
|
||||
{
|
||||
_scanindex = first( );
|
||||
return ( _scanindex == size( ) )?NULL:_data[ _scanindex ];
|
||||
};
|
||||
|
||||
TObject* TArray::last_item( )
|
||||
{
|
||||
_scanindex = last( );
|
||||
return ( _scanindex == -1 )?NULL:_data[ _scanindex ];
|
||||
};
|
||||
|
||||
TObject* TArray::succ_item( )
|
||||
{
|
||||
_scanindex = succ( _scanindex );
|
||||
return ( _scanindex == size( ))?NULL:_data[ _scanindex ];
|
||||
};
|
||||
|
||||
TObject* TArray::pred_item( )
|
||||
{
|
||||
_scanindex = pred( _scanindex );
|
||||
return ( _scanindex == -1)?NULL:_data[ _scanindex ];
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Modifica la dimensione dell'array.
|
||||
void TArray::resize(
|
||||
int arraysize) // @parm Indica la nuova dimensione che deve assumere l'array.
|
||||
|
||||
// @comm Alloca la memoria necessaria per contentere i dati della nuova
|
||||
// dimensione inizializzando a NULL tutti i nuovi elementi aggiunti
|
||||
// all'array lasciando inalterati, sia in posizione che in
|
||||
// contenuto gli elementi gia' presenti.
|
||||
// <nl>Nel caso si cerchi di diminuire la dimensione viene dato un
|
||||
// messaggio di errore.
|
||||
|
||||
{
|
||||
CHECK(arraysize > _size, "Can't reduce array size.");
|
||||
|
||||
TObject** newdata = new TObject* [arraysize];
|
||||
memset(newdata, 0, arraysize*sizeof(TObject*));
|
||||
if (_data != NULL)
|
||||
{
|
||||
memcpy(newdata, _data, _size*sizeof(TObject*));
|
||||
delete _data;
|
||||
}
|
||||
_size = arraysize;
|
||||
_data = newdata;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Rimuove uno o tutti (default) gli elementi
|
||||
// @rdesc Ritorna uno dei seguenti parametri:
|
||||
//
|
||||
// @flag TRUE | Se l'operazione e' riuscita con successo
|
||||
// @flag FALSE | Se il numero di elementi e' rimasto invariato
|
||||
bool TArray::destroy(
|
||||
int index, // @parm Numero dell'elemento da eliminare (default -1)
|
||||
bool pack) // @parm Se true richiama la funzione <mf TArray::pack> per compattare gli elementi dell'array (default FALSE)
|
||||
|
||||
// @comm Permette la rimozione di uno (index > 0 ) o di tutti (default) gli
|
||||
// elementi dell'array assegnandone il valore NULL.
|
||||
// <nl>Nel caso il parametro pack sia TRUE permette di rendere contigui
|
||||
// tutti gli elementi diversi da NULL tramite la chiamata alla funzione
|
||||
// <mf TArray::pack>.
|
||||
|
||||
{
|
||||
const int old = _items;
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
for (int i = last(); i >= 0; i--) if (_data[i] != NULL)
|
||||
{
|
||||
delete _data[i];
|
||||
_data[i] = NULL;
|
||||
}
|
||||
_items = _next = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TObject* o = remove(index, pack);
|
||||
if (o) delete o;
|
||||
}
|
||||
|
||||
return _items < old;
|
||||
}
|
||||
|
||||
|
||||
TArray::TArray(int arraysize)
|
||||
: _size(0), _items(0), _next(0), _data(NULL)
|
||||
{
|
||||
if (arraysize)
|
||||
resize(arraysize);
|
||||
}
|
||||
|
||||
TArray::TArray()
|
||||
: _size(0), _items(0), _next(0), _data(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
TArray::TArray(const TArray& a)
|
||||
: _size(0), _items(0), _next(0), _data(NULL)
|
||||
{
|
||||
(*this) = a;
|
||||
}
|
||||
|
||||
TArray& TArray::operator= (const TArray& a)
|
||||
{
|
||||
destroy();
|
||||
if (size() < a.size())
|
||||
resize(a.size());
|
||||
for (int i = a.size()-1; i >= 0; i--)
|
||||
{
|
||||
const TObject* o = a.objptr(i);
|
||||
if (o != NULL)
|
||||
{
|
||||
_data[i] = o->dup();
|
||||
#ifdef DBG
|
||||
const long vir_tab1 = *((long*)o);
|
||||
const long vir_tab2 = *((long*)_data[i]);
|
||||
if (vir_tab1 != vir_tab2)
|
||||
NFCHECK("Duplicazione di elementi di array pericolosa");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
_items = ( int )a.items();
|
||||
_next = ( int )a._next;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TArray::~TArray()
|
||||
{
|
||||
if (ok())
|
||||
{
|
||||
destroy();
|
||||
delete _data;
|
||||
}
|
||||
}
|
||||
|
||||
const char* TArray::class_name() const
|
||||
{
|
||||
return "Array";
|
||||
}
|
||||
|
||||
|
||||
word TArray::class_id() const
|
||||
{
|
||||
return CLASS_ARRAY;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Stampa un array
|
||||
void TArray::print_on(
|
||||
ostream& out) const // @parm indica l'output sul quale reindirizzare la stampa (funzione standard del C++)
|
||||
|
||||
// @comm Permette di stampare sull'output passato come parametro il contenuto
|
||||
// dell'array, preceduto dal numero dell'elemetno a cui si riferisce.
|
||||
// <nl>Nel caso vi siano degli elementi vuoti (valore = NULL) viene
|
||||
// stampato il valore (null).
|
||||
|
||||
{
|
||||
for (int i = 0; i < size(); i++)
|
||||
{
|
||||
out.width(4);
|
||||
out << i << ' ';
|
||||
out.width();
|
||||
if (_data[i] != NULL) out << *_data[i];
|
||||
else out << "(null)";
|
||||
out << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Controlla se si tratta di un oggetto valido
|
||||
//
|
||||
// @rdesc Ritorna uno dei seguenti parametri:
|
||||
// @flag TRUE | Se l'array contiene degli elementi
|
||||
// @flag FALSE | Se l'array e' vuoto
|
||||
bool TArray::ok() const
|
||||
|
||||
// @comm Controlla se la dimensione dell'array e' uguale a 0 e se esistono
|
||||
// degli elementi diversi da NULL
|
||||
|
||||
{
|
||||
return(size() != 0 && (_data != NULL));
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
TObject& TArray::operator[] (int index) const
|
||||
{
|
||||
TObject* o = objptr(index);
|
||||
if (o == NULL)
|
||||
{
|
||||
NFCHECK("Can't access NULL array item %d of %d", index, _size);
|
||||
const int f = last();
|
||||
if (f >= 0)
|
||||
{
|
||||
o = objptr(f)->dup();
|
||||
((TArray*)this)->add(o, index);
|
||||
}
|
||||
CHECK(o, "Unrecoverable array access error");
|
||||
}
|
||||
return *o;
|
||||
}
|
||||
#endif
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Aggiunge un oggetto ad un array.
|
||||
//
|
||||
// @rdesc La funzione ritorna la posizione nella quale e' stato aggiunto
|
||||
// l'oggetto.
|
||||
int TArray::add(
|
||||
TObject *object, // @parm Oggetto da aggiungere nell'array
|
||||
int index) // @parm Posizione in cui aggiungere l'oggetto
|
||||
// @parm TObject | &object | Oggetto da aggiungere nell'array. L'oggetto viene duplicato
|
||||
|
||||
// @syntax add(TObject* object,int index);
|
||||
// @syntax add(TObject& object,int index);
|
||||
//
|
||||
// @comm Nel caso venga passata una posizione minore di 0 l'elemento viene aggiunto
|
||||
// in coda all'array, diversamente viene l'elemento presente viene
|
||||
// sostitito con l'oggetto passato nei prametri.
|
||||
// <nl>Se e' stato passato un indice minore della dimensione dell'array,
|
||||
// viene aumentata automaticamente la dimensione dell'array stesso tramite
|
||||
// la chiamata alla funzione <mf TArray::resize>.
|
||||
// <nl><nl>ATTENZIONE: Nel caso si passi l'oggetto per indirizzo deve
|
||||
// essere definita la funzione <mf TObject::dup>.
|
||||
//
|
||||
// @xref <mf TArray::insert>
|
||||
{
|
||||
if (index < 0)
|
||||
for (index = _next; index < size() && _data[index]; index++);
|
||||
if (index >= size())
|
||||
{
|
||||
long newsize = 3L * index / 2 + 1;
|
||||
if (newsize > INT_MAX)
|
||||
newsize = INT_MAX;
|
||||
resize((int)newsize);
|
||||
}
|
||||
|
||||
if (object != _data[index]) // Evita ricopiatura su se stesso
|
||||
{
|
||||
if (_data[index] != NULL)
|
||||
{
|
||||
delete _data[index];
|
||||
_items--;
|
||||
}
|
||||
|
||||
_data[index] = object;
|
||||
if (object != NULL)
|
||||
{
|
||||
_items++;
|
||||
_next = index+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index < _next)
|
||||
_next = index;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Inserisce un elemento dell'array nella posizione index
|
||||
//
|
||||
// @rdesc La funzione ritorna la posizione nella quale e' stato inserito l'oggetto.
|
||||
int TArray::insert(
|
||||
TObject *object, // @parm Oggetto da inserire nell'array
|
||||
int index, // @parm Posizione in cui inserire l'oggetto (puo' essere -1)
|
||||
bool force) // @parm Forza l'inserimento anche se la posizione e' vuota
|
||||
// @parm TObject | &object | Oggetto da inserire nell'array. L'oggetto viene duplicato
|
||||
|
||||
// @syntax insert(TObject* object, int index);
|
||||
// @syntax insert(TObject& object, int index);
|
||||
//
|
||||
// @comm Nel caso l'elemento della posizione passata sia diverso da NULL vengono
|
||||
// spostati di una posizione tutti gli elementi presenti nell'array.
|
||||
// La dimensione dell'array viene automaticamente aumentata nel caso
|
||||
// la stessa non sia sufficiente a contenere il nuovo oggetto.
|
||||
// <nl><nl>ATTENZIONE: Nel caso si passi l'oggetto per indirizzo deve
|
||||
// essere definita la funzione <mf TObject::dup>.
|
||||
//
|
||||
// @xref <mf TArray::add>
|
||||
{
|
||||
const int s = size();
|
||||
if ((index >= 0 && index < s) && (force || objptr(index)))
|
||||
{
|
||||
if (_data[s - 1]) // Se l'ultimo non e' vuoto ...
|
||||
add(NULL, s); // ... aggiungi un elemento in fondo
|
||||
for (int i = size()-1; i > index; i--) // size va aggiornato perche potrebbe essere cambiato
|
||||
_data[i] = _data[i - 1];
|
||||
_data[index] = NULL;
|
||||
}
|
||||
return add(object, index);
|
||||
}
|
||||
|
||||
int TArray::add(const TObject& object, int index)
|
||||
{
|
||||
TObject* objptr = object.dup();
|
||||
return add(objptr, index);
|
||||
}
|
||||
|
||||
int TArray::insert(const TObject& object, int index, bool force)
|
||||
{
|
||||
TObject* objptr = object.dup();
|
||||
return insert(objptr, index, force);
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Elimina l'elemento nella posizione index dell'array
|
||||
//
|
||||
// @rdesc Ritorna l'elemento dell'array eliminato senza farne la delete
|
||||
TObject* TArray::remove(
|
||||
int index, // @parm Indica la posizione dell'elemento da eliminare
|
||||
bool dopack) // @parm Indica se si vuole richiamare la funzione
|
||||
// <mf TArray::pack> (default FALSE) per spostare gli elementi successivi dell'array
|
||||
{
|
||||
CHECKD(index >= 0, "Can't remove array item ", index);
|
||||
|
||||
TObject* o = objptr(index);
|
||||
if (o)
|
||||
{
|
||||
_data[index] = NULL;
|
||||
_items--;
|
||||
if (index < _next)
|
||||
_next = index;
|
||||
}
|
||||
if (dopack && index < size())
|
||||
{
|
||||
const int last = size()-1;
|
||||
for (int i = index ; i < last; i++)
|
||||
_data[i] = _data[i+1];
|
||||
_data[last] = NULL;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
TObject* TArray::remove_item(bool pack )
|
||||
{
|
||||
return remove(_scanindex,pack);
|
||||
}
|
||||
|
||||
void TArray::swap(int i1, int i2)
|
||||
{
|
||||
TObject* o1 = remove(i1, FALSE);
|
||||
TObject* o2 = remove(i2, FALSE);
|
||||
if (o1) add(o1, i2);
|
||||
if (o2) add(o2, i1);
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Cerca il prossimo oggetto dell'array
|
||||
//
|
||||
// @rdesc Ritorna l'indice del prossimo elemento trovato o size() se non esiste
|
||||
int TArray::succ(int i) const
|
||||
|
||||
{
|
||||
CHECKD(i >= -1, "Bad array index ", i);
|
||||
for (i++; i < size(); i++)
|
||||
if (_data[i]) break;
|
||||
return i;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Cerca il precedente oggetto dell'array
|
||||
//
|
||||
// @rdesc Ritorna l'indice dell'elemento precedente o -1 se non esiste
|
||||
int TArray::pred(int i) const
|
||||
|
||||
{
|
||||
CHECKD(i <= size(), "Bad array index ", i);
|
||||
for (i--; i >= 0; i--)
|
||||
if (_data[i]) break;
|
||||
return i;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Cerca il primo oggetto dell'array
|
||||
//
|
||||
// @rdesc Ritorna l'indice del primo elemento trovato o size() se l'array e' vuoto
|
||||
int TArray::first() const
|
||||
|
||||
{
|
||||
return succ(-1);
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Cerca l'ultimo oggetto dell'array
|
||||
//
|
||||
// @rdesc Ritorna l'indice dell'ultimo elemento trovato o -1 se l'array e' vuoto
|
||||
int TArray::last() const
|
||||
|
||||
{
|
||||
return pred(size());
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Rende contigui tutti gli elementi non nulli
|
||||
void TArray::pack()
|
||||
|
||||
// @comm Riordina gli elementi dell'array facendo che tra di loro non ve ne
|
||||
// siano con valore uguale a NULL.
|
||||
{
|
||||
int next = 0;
|
||||
for (int i = 0; i < size(); i++)
|
||||
{
|
||||
if (_data[i] != NULL)
|
||||
{
|
||||
if (next < i)
|
||||
{
|
||||
_data[next] = _data[i];
|
||||
_data[i] = NULL;
|
||||
}
|
||||
next++;
|
||||
}
|
||||
}
|
||||
_next = next;
|
||||
}
|
||||
|
||||
// @doc INTERNAL
|
||||
|
||||
// @func Funzione per permettere il confonto tra 2 oggetti.
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag <gt>0 | se <p this> <gt> <p s>
|
||||
// @flag 0 | se <p this> == <p s>
|
||||
// @flag <lt>0 | se <p this> <lt> <p s>
|
||||
// @flag UNDEFINED | se l'ordine non e' definito
|
||||
static int sortable_compare(
|
||||
const TObject** o1, // @parm Primo oggetto da confrontare
|
||||
const TObject** o2) // @parm Secondo oggetto da confrontare
|
||||
|
||||
// @comm E' utilizzata dalla funzione <mf TArray::sort> come default per
|
||||
// stabilire il criteri di ordinamento degli oggetti passati.
|
||||
{
|
||||
if (o1 == o2)
|
||||
return 0; // qsort a volte confronta un oggetto con se stesso: per cui ne approfitto!
|
||||
|
||||
const TSortable* s1 = (const TSortable*)*o1;
|
||||
const TSortable* s2 = (const TSortable*)*o2;
|
||||
return s1->compare(*s2);
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Ordina i TObject secondo il criterio definito in <t COMPARE_FUNCTION>
|
||||
void TArray::sort(
|
||||
COMPARE_FUNCTION compare) // @parm Funzione indicante il criterio di ordinamento (default TSortable)
|
||||
|
||||
// @comm Nel caso non venga passata nessuna funzione che permetta di conforntare
|
||||
// i due oggetti viene utilizzato il criterio <c Tsortable>
|
||||
{
|
||||
typedef int (*qsortfunc)(const void*, const void*);
|
||||
if (compare == NULL) compare = sortable_compare;
|
||||
|
||||
pack();
|
||||
qsort(_data, items(), sizeof(TObject*), (qsortfunc)compare);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TPointer_array
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Rimuove uno o tutti (default) gli elementi
|
||||
// @rdesc Ritorna uno dei seguenti parametri:
|
||||
//
|
||||
// @flag TRUE | Se l'operazione e' riuscita con successo
|
||||
// @flag FALSE | Se il numero di elementi e' rimasto invariato
|
||||
bool TPointer_array::destroy(
|
||||
int index, // @parm Numero dell'elemento da eliminare (default -1)
|
||||
bool pack) // @parm Se true richiama la funzione <mf TArray::pack> per compattare gli elementi dell'array (default FALSE)
|
||||
|
||||
// @comm Permette la rimozione di uno (index > 0 ) o di tutti (default) gli
|
||||
// elementi dell'array assegnandone il valore NULL.
|
||||
// <nl>Nel caso il parametro pack sia TRUE permette di rendere contigui
|
||||
// tutti gli elementi diversi da NULL tramite la chiamata alla funzione
|
||||
// <mf TArray::pack>.
|
||||
|
||||
{
|
||||
if (data())
|
||||
{
|
||||
if (index < 0)
|
||||
memset(data(), 0, size() * sizeof(TObject*));
|
||||
else
|
||||
remove(index);
|
||||
}
|
||||
return TArray::destroy(index, pack);
|
||||
}
|
||||
|
||||
void TPointer_array::copy(const TArray& a)
|
||||
{
|
||||
destroy();
|
||||
if (size() < a.size())
|
||||
resize(a.size());
|
||||
|
||||
// for (int i = a.size()-1; i >= 0; i--)
|
||||
// add(a.objptr(i), i);
|
||||
memcpy(data(), a.data(), a.size() * sizeof(TObject*));
|
||||
_items = a._items;
|
||||
_next = a._next;
|
||||
}
|
||||
|
||||
int TPointer_array::add(TObject* object, int index)
|
||||
{
|
||||
if (index >= 0)
|
||||
remove(index);
|
||||
return TArray::add(object, index);
|
||||
}
|
||||
|
||||
int TPointer_array::add(const TObject& object, int index)
|
||||
{
|
||||
return add(&(TObject&)object, index);
|
||||
}
|
||||
|
||||
int TPointer_array::insert(const TObject& object, int index, bool force)
|
||||
{
|
||||
return TArray::insert(&(TObject&)object, index, force);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TBit_array
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TBit_array::TBit_array(long size)
|
||||
: _bit(NULL), _size(0)
|
||||
{
|
||||
if (size)
|
||||
resize(index(size));
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Copia l'array passato come parametro
|
||||
void TBit_array::copy(
|
||||
const TBit_array& ba) // @parm Array da copiare
|
||||
|
||||
// @comm Copia il contenuto dell'array passato come parametro.
|
||||
{
|
||||
if (_bit)
|
||||
{
|
||||
delete _bit;
|
||||
_bit = NULL;
|
||||
_size = 0;
|
||||
}
|
||||
resize(ba._size-1);
|
||||
memcpy(_bit, ba._bit, _size);
|
||||
}
|
||||
|
||||
TBit_array::TBit_array(const TBit_array& ba) : _bit(NULL), _size(0)
|
||||
{ copy(ba); }
|
||||
|
||||
TBit_array& TBit_array::operator=(const TBit_array& ba)
|
||||
{
|
||||
copy(ba);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
TBit_array::~TBit_array()
|
||||
{
|
||||
if (_bit)
|
||||
delete _bit;
|
||||
}
|
||||
|
||||
// Certified 100%
|
||||
void TBit_array::set()
|
||||
{
|
||||
if (_bit)
|
||||
memset(_bit, 0xFF, _size);
|
||||
}
|
||||
|
||||
// Certified 100%
|
||||
void TBit_array::reset()
|
||||
{
|
||||
if (_bit)
|
||||
memset(_bit, 0x0, _size);
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
// @doc EXTERNAL
|
||||
//
|
||||
// @mfunc Modifica la dimensione dell'array.
|
||||
void TBit_array::resize(
|
||||
word size) // @parm Indica la nuova dimensione che deve assumere l'array.
|
||||
|
||||
// @comm Alloca la memoria necessaria per contentere i dati della nuova
|
||||
// dimensione inizializzando a NULL tutti i nuovi elementi aggiunti
|
||||
// all'array lasciando inalterati, sia in posizione che in
|
||||
// contenuto gli elementi gia' presenti.
|
||||
{
|
||||
word oldsize = _size;
|
||||
byte* oldbit = _bit;
|
||||
|
||||
_size = size+1;
|
||||
_bit = new byte[_size];
|
||||
reset();
|
||||
|
||||
if (oldsize)
|
||||
{
|
||||
memcpy(_bit, oldbit, oldsize);
|
||||
delete oldbit;
|
||||
}
|
||||
}
|
||||
|
||||
bool TBit_array::operator[] (long n) const
|
||||
{
|
||||
const word i = index(n);
|
||||
if (i >= _size) return FALSE;
|
||||
return (_bit[i] & mask(n)) != 0;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
TBit_array& TBit_array::operator|= (const TBit_array& ba)
|
||||
{
|
||||
if (_size < ba._size)
|
||||
resize(ba._size);
|
||||
|
||||
for (word i = 0; i < _size; i++)
|
||||
_bit[i] |= ba._bit[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
void TBit_array::set(long n)
|
||||
{
|
||||
CHECKD(n >= 0, "Can't set a negative bit ", n);
|
||||
const word i = index(n);
|
||||
if (i >= _size)
|
||||
resize(i);
|
||||
_bit[i] |= mask(n);
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
void TBit_array::reset(long n)
|
||||
{
|
||||
const word i = index(n);
|
||||
if (i < _size)
|
||||
_bit[i] &= ~mask(n);
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
void TBit_array::not(long n)
|
||||
{
|
||||
const word i = index(n);
|
||||
if (i >= _size) resize(i);
|
||||
_bit[i] ^= mask(n);
|
||||
}
|
||||
|
||||
// Certified 90%
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Ritorna il numero di 1 presenti nell'array
|
||||
//
|
||||
// @rdesc Numero di 1 trovati.
|
||||
long TBit_array::ones() const
|
||||
|
||||
// @comm Passa tutto l'array di bit e conta quanti degli elementi presenti sono
|
||||
// settati ad 1.
|
||||
//
|
||||
// @xref <mf TBit_array::last_one> <mf TBit_array::first_one>
|
||||
{
|
||||
long one = 0;
|
||||
for (word i = 0; i < _size; i++)
|
||||
{
|
||||
const byte b = _bit[i];
|
||||
if (b)
|
||||
{
|
||||
for (byte m = 1; m; m <<= 1)
|
||||
if (b & m) one++;
|
||||
}
|
||||
}
|
||||
return one;
|
||||
}
|
||||
|
||||
// Certified 90%
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Ritorna la posizione dell'ultimo 1 nell'array
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori:
|
||||
// @flag >0 | Posizione nella quale si trova l'ultimo 1
|
||||
// @flag -1 | Se non sono presenti bit settati ad 1
|
||||
|
||||
long TBit_array::last_one() const
|
||||
|
||||
// @comm Cerca all'interno dell'array di bit la posizione dell'ultimo bit
|
||||
// settato ad 1
|
||||
//
|
||||
// @xref <mf TBit_array::first_one> <mf TBit_array::ones>
|
||||
{
|
||||
for (word i = _size; i--;)
|
||||
{
|
||||
const byte b = _bit[i];
|
||||
if (b)
|
||||
{
|
||||
for (byte j = 8; j--;)
|
||||
if ((1<<j) & b) return (long(i)<<3) + j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Certified 90%
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Ritorna la posizione del primo 1 nell'array
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori:
|
||||
//
|
||||
// @flag >0 | Posizione nella quale si trova il primo 1
|
||||
// @flag -1 | Se non sono presenti bit settati ad 1
|
||||
|
||||
long TBit_array::first_one() const
|
||||
|
||||
// @comm Cerca all'interno dell'array di bit la posizione del primo bit
|
||||
// settato ad 1
|
||||
//
|
||||
// @xref <mf TBit_array::last_one> <mf TBit_array::ones>
|
||||
{
|
||||
for (word i = 0; i < _size; i++)
|
||||
{
|
||||
const byte b = _bit[i];
|
||||
if (b)
|
||||
{
|
||||
for (byte j = 0; j < 8; j++)
|
||||
if ((1<<j) & b) return (long(i)<<3)+j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @mfunc Controlla se si tratta di un oggetto valido
|
||||
//
|
||||
// @rdesc Ritorna uno dei seguenti parametri:
|
||||
//
|
||||
// @flag TRUE | Se l'array contiene degli elementi
|
||||
// @flag FALSE | Se l'array e' vuoto
|
||||
bool TBit_array::ok() const
|
||||
|
||||
// @comm Controlla se la dimensione dell'array e' maggiore di 0 e se esistono
|
||||
// degli elementi diversi da NULL
|
||||
{
|
||||
return _bit != NULL && _size > 0;
|
||||
}
|
||||
|
||||
|
||||
void TBit_array::set(const char* numbers)
|
||||
{
|
||||
TToken_string s(numbers, ' ');
|
||||
for (const char* n = s.get(0); n; n = s.get())
|
||||
if (isdigit(*n)) set(atol(n));
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
//
|
||||
// @mfunc Stampa un array
|
||||
void TBit_array::print_on(
|
||||
ostream& out) const // @parm Indica l'output sul quale reindirizzare la stampa (funzione standard del C++)
|
||||
|
||||
// @comm Stampa tutti gli indici degli elementi diversi da 0
|
||||
{
|
||||
const long last = _size<<3;
|
||||
for (long i = 1; i < last; i++)
|
||||
if (operator[](i)) out << ' ' << i;
|
||||
}
|
||||
|
||||
|
324
omnia/array.h
Executable file
324
omnia/array.h
Executable file
@ -0,0 +1,324 @@
|
||||
#ifndef __ARRAY_H
|
||||
#define __ARRAY_H
|
||||
|
||||
#ifndef __OBJECT_H
|
||||
#include "object.h"
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0L
|
||||
#endif
|
||||
|
||||
// @doc EXTERNAL
|
||||
//
|
||||
// @type COMPARE_FUNCTION | Prototipo funzione di confronto tra elementi della
|
||||
// classe <c TObject> da passare al metodo sort dei <c TArray>
|
||||
typedef int (*COMPARE_FUNCTION)(const TObject**, const TObject**);
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type CONDITION_FUNCTION | Prototipo funzione di ricerca/filtro
|
||||
// per i derivati di <c TObject> da passare ai metodi dei <c TContainer>
|
||||
typedef bool (*CONDITION_FUNCTION) ( const TObject& );
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type OPERATION_FUNCTION | Prototipo funzione attuatore
|
||||
// da passare ai metodi sort dei <c TContainer>
|
||||
typedef void (*OPERATION_FUNCTION) ( const TObject& );
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TContainer | Generico contenitore ad accesso casuale (con indice)
|
||||
// @base public | TObject
|
||||
class TContainer : public TObject
|
||||
{
|
||||
|
||||
// @author:(INTERNAL) Matteo
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
private:
|
||||
// @cmember:(INTERNAL) Ultima condizione di ricerca/filtro (vedi <t CONDITION_FUNCTION>)
|
||||
CONDITION_FUNCTION _last_condition;
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
|
||||
// @cmember Ritorna un puntatore al primo oggetto del contenitore
|
||||
virtual TObject* first_item( ) pure;
|
||||
// @cmember Ritorna un puntatore all'ultimo oggetto del contenitore
|
||||
virtual TObject* last_item( ) pure;
|
||||
// @cmember Ritorna un puntatore all'oggetto successivo all'oggetto corrente
|
||||
virtual TObject* succ_item( ) pure;
|
||||
// @cmember Ritorna un puntatore all'oggetto che precede l'oggetto corrente
|
||||
virtual TObject* pred_item( ) pure;
|
||||
// @cmember Ritorna il numero di oggetti nel contenitore
|
||||
virtual long objects( ) pure;
|
||||
|
||||
// @cmember Cerca il successivo elemento che soddisfa la <t OPERATION_FUNCTION>
|
||||
virtual void for_each( OPERATION_FUNCTION );
|
||||
// @cmember Cerca il successivo elemento che soddisfa la <t OPERATION_FUNCTION>
|
||||
// per ogni elemento di <t CONDITION_FUNCTION>
|
||||
virtual void for_each_that( OPERATION_FUNCTION, CONDITION_FUNCTION = NULL );
|
||||
|
||||
// @cmember Ritorna il puntatore al primo oggetto che soddisfa la condizione
|
||||
virtual TObject* first_that( CONDITION_FUNCTION = NULL );
|
||||
// @cmember Ritorna il puntatore all'ultimo oggetto che soddisfa la condizione
|
||||
virtual TObject* last_that( CONDITION_FUNCTION = NULL );
|
||||
// @cmember Ritorna il prossimo oggetto che soddisfa la condizione. Va usata con first_that per scandire il container
|
||||
virtual TObject* succ_that( );
|
||||
// @cmember Ritorna il precedente oggetto che soddisfa la condizione. Va usata con last_that per scandire il container all'indietro
|
||||
virtual TObject* pred_that( );
|
||||
// @cmember Ritorna il numero di elementi che soddisfano la condizione
|
||||
virtual long count( CONDITION_FUNCTION = NULL );
|
||||
// @cmember Ritorna l'oggetto successivo a quello corrente
|
||||
TObject* operator++ ()
|
||||
{ return succ_item( ); };
|
||||
// @cmember Ritorna l'oggetto che precede quello corrente
|
||||
TObject* operator-- ()
|
||||
{ return pred_item( ); };
|
||||
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TArray | Classe per la definizione degli array
|
||||
//
|
||||
// @base public | TContainer
|
||||
class TArray : public TContainer
|
||||
|
||||
// @author:(INTERNAL) Guido
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
{
|
||||
friend class TPointer_array;
|
||||
|
||||
// @cmember:(INTERNAL) Array di puntatori ad oggetti
|
||||
TObject** _data;
|
||||
// @cmember:(INTERNAL) Dimensione dell'array
|
||||
int _size;
|
||||
// @cmember:(INTERNAL) Numero di elementi presenti nell'array
|
||||
int _items;
|
||||
// @cmember:(INTERNAL) Prossimo elemento libero nell'array
|
||||
int _next;
|
||||
|
||||
// @cmember:(INTERNAL) Indice per la scansione sequenziale
|
||||
int _scanindex;
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
TObject** data() const { return _data; }
|
||||
|
||||
// @cmember Modifica la dimensione dell'array.
|
||||
void resize(int newdim);
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore. Crea un array (chiama <mf TArray::resize>)
|
||||
TArray(int arraysize);
|
||||
// @cmember Costruttore. Crea un array (non chiama <mf TArray::resize>)
|
||||
TArray();
|
||||
// @cmember Costruttore. Copia tutto l'array e ne duplica gli elementi
|
||||
TArray(const TArray&);
|
||||
|
||||
// @cmember Distruttore
|
||||
virtual ~TArray() ;
|
||||
// @cmember Ritorna il nome della classe
|
||||
virtual const char* class_name() const ;
|
||||
// @cmember Ritorna l'id della class
|
||||
virtual word class_id() const ;
|
||||
// @cmember Stampa un array
|
||||
virtual void print_on(ostream& out) const ;
|
||||
// @cmember Controlla se si tratta di un oggetto valido
|
||||
virtual bool ok() const ;
|
||||
|
||||
// @cmember Ritorna la grandezza dell'array
|
||||
int size() const
|
||||
{ return _size; }
|
||||
// @cmember Ritorna numero di oggetti nell'array
|
||||
virtual long objects( )
|
||||
{ return _items; }
|
||||
|
||||
// @cmember Ritorna numero di oggetti nell'array
|
||||
virtual int items( ) const
|
||||
{ return _items; }
|
||||
|
||||
|
||||
// @cmember Ritorna il primo elemento dell'array
|
||||
virtual TObject* first_item( );
|
||||
// @cmember Ritorna l'ultimo elemento dell'array
|
||||
virtual TObject* last_item( );
|
||||
// @cmember Ritorna il successivo elemento dell'array rispetto all'elemento corrente
|
||||
virtual TObject* succ_item( );
|
||||
// @cmember Ritorna il precedente elemento dell'array rispetto all'elemento corrente
|
||||
virtual TObject* pred_item( );
|
||||
|
||||
// @cmember Ritorna l'indice del primo oggetto
|
||||
int first() const;
|
||||
// @cmember Ritorna l'indice dell'ultimo oggetto
|
||||
int last() const;
|
||||
// @cmember Ritorna l'indice del primo oggetto dopo l'i-esimo
|
||||
int succ(int i) const;
|
||||
// @cmember Ritorna l'indice del primo oggetto che precede l'i-esimo
|
||||
int pred(int i) const;
|
||||
|
||||
// @cmember Ritorna l'oggetto nella posizione index
|
||||
TObject& operator[] (int index) const ;
|
||||
// @cmember Ritorna l'oggetto nella posizione index
|
||||
TObject* objptr(int index) const ;
|
||||
// @cmember Assegna all'array l'oggetto passato
|
||||
TArray& operator= (const TArray& a);
|
||||
|
||||
// @cmember Rimuove uno o tutti (default) gli elementi
|
||||
virtual bool destroy(int index = -1, bool pack = FALSE);
|
||||
// @cmember Aggiunge un oggetto ad un array.
|
||||
virtual int add(TObject* obj, int index = -1) ;
|
||||
// @cmember Inserisce un elemento dell'array nella posizione index
|
||||
virtual int insert(TObject* obj, int index = 0, bool force = FALSE);
|
||||
|
||||
// @cmember Aggiunge un oggetto all'array. L'oggetto viene duplicato
|
||||
virtual int add(const TObject& object, int index = -1) ;
|
||||
// @cmember Inserisce un oggetto alla posizione index
|
||||
virtual int insert(const TObject& object, int index = 0, bool force = FALSE);
|
||||
// @cmember Elimina l'elemento nella posizione index dell'array
|
||||
TObject* remove(int index, bool pack = FALSE);
|
||||
// @cmember Elimina l'elemento nella posizione index dell'array
|
||||
TObject* remove_item(bool pack = FALSE) ;
|
||||
// @cmember Scambia di posto due elementi dell'array
|
||||
void swap(int i1, int i2);
|
||||
// @cmember Rende contigui tutti gli elementi non nulli
|
||||
virtual void pack();
|
||||
// @cmember Ordina i TObject secondo il criterio definito in <t COMPARE_FUNCTION>
|
||||
void sort(COMPARE_FUNCTION = NULL);
|
||||
};
|
||||
|
||||
inline TObject* TArray::objptr(int index) const
|
||||
{
|
||||
return (index < _size && index >= 0) ? _data[index] : NULL;
|
||||
}
|
||||
|
||||
#ifndef DBG
|
||||
inline TObject& TArray::operator[] (int index) const
|
||||
{
|
||||
return *objptr(index);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define FOR_EACH_ARRAY_ITEM(__arr, __r, __obj) \
|
||||
TObject* __obj; \
|
||||
for (int __r = __arr.first(); \
|
||||
__obj = __arr.objptr(__r); \
|
||||
__r = __arr.succ(__r))
|
||||
|
||||
#define FOR_EACH_ARRAY_ITEM_BACK(__arr, __r, __obj) \
|
||||
TObject* __obj; \
|
||||
for (int __r = __arr.last(); \
|
||||
__obj = __arr.objptr(__r); \
|
||||
__r = __arr.pred(__r))
|
||||
|
||||
|
||||
class TPointer_array : public TArray
|
||||
{
|
||||
protected:
|
||||
void copy(const TArray& a);
|
||||
|
||||
public:
|
||||
virtual bool destroy(int index = -1, bool pack = FALSE);
|
||||
virtual int add(TObject* object, int index = -1);
|
||||
virtual int add(const TObject& object, int index = -1);
|
||||
virtual int insert(const TObject& object, int index = 0, bool force = FALSE);
|
||||
virtual TPointer_array& operator= (const TArray& a) { copy(a); return *this; }
|
||||
virtual TPointer_array& operator= (const TPointer_array& a) { copy(a); return *this; }
|
||||
|
||||
long get_long(int index) const { return (long)objptr(index); }
|
||||
int get_int(int index) const { return (int)get_long(index); }
|
||||
int add_long(long value, int index = -1) { return add((TObject*)value, index); }
|
||||
int insert_long(long value, int index = -1) { return TArray::insert((TObject*)value, index, TRUE); }
|
||||
|
||||
TPointer_array() { }
|
||||
TPointer_array(int size) : TArray(size) { }
|
||||
TPointer_array(const TArray& a) { copy(a); }
|
||||
TPointer_array(const TPointer_array& a) { copy(a); }
|
||||
virtual ~TPointer_array() { destroy(); }
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TBit_array | Come la classe <c TArray> ma i suoi elementi sono bit;
|
||||
// questo permette di costruire array piu' piccoli rispetto
|
||||
// alla classe TArray.
|
||||
//
|
||||
// @base public | TObject
|
||||
class TBit_array : public TObject
|
||||
|
||||
// @author:(INTERNAL) Guido
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
{
|
||||
// @cmember:(INTERNAL) dimensione dell'array
|
||||
word _size;
|
||||
// @cmember:(INTERNAL) bit in cui sono contenuti i dati
|
||||
byte* _bit;
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember Controlla se si tratta di un oggetto valido
|
||||
virtual bool ok() const;
|
||||
// @cmember Stampa un array
|
||||
virtual void print_on(ostream& out) const;
|
||||
|
||||
// @cmember Modifica la dimensione dell'array.
|
||||
void resize(word size);
|
||||
// @cmember Copia nell'array l'elemento passato come parametro
|
||||
void copy(const TBit_array& ba);
|
||||
// @cmember Ritorna il numero del byte contenente il bit <p n>
|
||||
word index(long n) const
|
||||
{ return word(n >> 3); }
|
||||
// @cmember Ritorna la posizione del bit <p n> all'interno del byte
|
||||
byte mask(long n) const
|
||||
{ return byte(1 << (n & 0x7)); }
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore. Crea un array di (chiama <mf TBit_array::resize>)
|
||||
TBit_array(long size = 0);
|
||||
// @cmember Costruttore. Crea un array di (chiama <mf TBit_array::copy>)
|
||||
TBit_array(const TBit_array& ba);
|
||||
// @cmember Distruttore
|
||||
virtual ~TBit_array();
|
||||
|
||||
// @cmember Assegna all'array l'oggetto passato
|
||||
TBit_array& operator=(const TBit_array& ba);
|
||||
// @cmember Ritorna l'oggetto puntato da n
|
||||
bool operator[] (long n) const;
|
||||
// @cmember Ritorna l'or logico tra due Bit_array modificando l'oggetto corrente
|
||||
TBit_array& operator |=(const TBit_array& b);
|
||||
|
||||
// @cmember Ritorna il numero di bit nell'array
|
||||
long items() const { return 8L * _size; }
|
||||
// @cmember Ritorna la posizione del primo 1 nell'array (-1 se non lo trova)
|
||||
long first_one() const;
|
||||
// @cmember Ritorna la posizione dell'ultimo 1 nell'array (-1 se non lo trova)
|
||||
long last_one() const;
|
||||
// @cmember Ritorna il numero di 1 presenti nell'array
|
||||
long ones() const;
|
||||
|
||||
// @cmember Setta ad 1 il bit n-esimo dell'array
|
||||
void set(long n);
|
||||
// @cmember Setta a 0 il bit n-esimo dell'array
|
||||
void reset(long n);
|
||||
// @cmember Not logico del bit n-esimo dell'array
|
||||
void not(long n);
|
||||
|
||||
// @cmember Setta il bit n-esimo a seconda del valore passato come secondo elemento
|
||||
void set(long n, bool on) { on ? set(n) : reset(n); }
|
||||
// @cmember Setta ad 1 tutti i bit dell'array
|
||||
void set();
|
||||
// @cmember Setta a 0 tutti i bit dell'array
|
||||
void reset();
|
||||
// @cmember Data una stringa setta ad 1 gli elementi indicati della stringa
|
||||
void set(const char* numbers);
|
||||
};
|
||||
|
||||
#endif
|
450
omnia/assoc.cpp
Executable file
450
omnia/assoc.cpp
Executable file
@ -0,0 +1,450 @@
|
||||
#include <stdlib.h>
|
||||
#include "assoc.h"
|
||||
|
||||
// @ccost:(INTERNAL) HASH_SIZE | 883 | Dimensione della tabella hash
|
||||
const int HASH_SIZE = 883;
|
||||
|
||||
THash_object::~THash_object()
|
||||
{
|
||||
if (_obj != NULL)
|
||||
delete _obj;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
THash_object* TAssoc_array::random_hash_object()
|
||||
{
|
||||
THash_object* o = NULL;
|
||||
if (items() > 0)
|
||||
{
|
||||
int bucket = rand() % _bucket.size();
|
||||
if (_bucket.objptr(bucket) == NULL)
|
||||
bucket = _bucket.succ(bucket);
|
||||
if (_bucket.objptr(bucket) == NULL)
|
||||
bucket = _bucket.pred(bucket);
|
||||
const TArray* arr = (const TArray*)_bucket.objptr(bucket);
|
||||
if (arr != NULL)
|
||||
{
|
||||
const int item = rand() % arr->size();
|
||||
o = (THash_object*)arr->objptr(item);
|
||||
if (o != NULL)
|
||||
{
|
||||
_rowitem = bucket;
|
||||
_colitem = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// @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 Oggetto 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])
|
||||
{
|
||||
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 di cui cercare 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_object : 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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TCache
|
||||
// Un simpatico contenitore che può dimenticare i contenuti
|
||||
// a patto che riusciate a fornire un metodo per ricrearli!
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TObject* TCache::key2obj(const char* key)
|
||||
{
|
||||
NFCHECK("Pure key2obj function not implemented");
|
||||
return new TString(key); // Place holder
|
||||
}
|
||||
|
||||
void TCache::discarding(const THash_object* obj)
|
||||
{
|
||||
// Nothing to do normally
|
||||
}
|
||||
|
||||
TObject* TCache::objptr(const TString& key)
|
||||
{
|
||||
const int hv = key.hash() % _data.size();
|
||||
THash_object* ho = (THash_object*)_data.objptr(hv);
|
||||
TObject* obj = NULL;
|
||||
if (ho != NULL && ho->key() == key)
|
||||
{
|
||||
obj = &ho->obj();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = key2obj(key);
|
||||
if (obj != NULL)
|
||||
{
|
||||
if (ho != NULL)
|
||||
{
|
||||
discarding(ho);
|
||||
_data.destroy(hv);
|
||||
}
|
||||
ho = new THash_object(key, obj);
|
||||
_data.add(ho, hv);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
TObject* TCache::objptr(size_t s)
|
||||
{
|
||||
TString16 key; key.format("%10lu", s);
|
||||
return objptr(key);
|
||||
}
|
||||
|
||||
void TCache::destroy()
|
||||
{
|
||||
for (int i = _data.last(); i >= 0; i--)
|
||||
{
|
||||
THash_object* ho = (THash_object*)_data.objptr(i);
|
||||
if (ho != NULL)
|
||||
{
|
||||
discarding(ho);
|
||||
_data.destroy(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCache::TCache(size_t size) : _data(size > 0 ? size : HASH_SIZE)
|
||||
{ }
|
||||
|
||||
TCache::~TCache()
|
||||
{
|
||||
destroy();
|
||||
}
|
182
omnia/assoc.h
Executable file
182
omnia/assoc.h
Executable file
@ -0,0 +1,182 @@
|
||||
#ifndef __ASSOC_H
|
||||
#define __ASSOC_H
|
||||
|
||||
#ifndef __STRINGS_H
|
||||
#include "strings.h"
|
||||
#endif
|
||||
|
||||
// @doc INTERNAL
|
||||
|
||||
// @class THash_object | Classe per la definizione degli elementi di una tabella hash.
|
||||
//
|
||||
// @base public | TObject
|
||||
class THash_object : public TObject
|
||||
|
||||
// @author:(INTERNAL) Guido
|
||||
|
||||
{
|
||||
// @cfriend TAssoc_array
|
||||
friend class TAssoc_array;
|
||||
|
||||
// @access:(INTERNAL) Private Member
|
||||
|
||||
// @cmember:(INTERNAL) Chiave d'ordinamento
|
||||
TString _key;
|
||||
// @cmember:(INTERNAL) Oggetto della tabella da ordinare
|
||||
TObject* _obj;
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
|
||||
// @cmember Ritorna la chiave di ordinamento
|
||||
const TString& key() const
|
||||
{ return _key; }
|
||||
// @cmember Ritorna l'oggetto
|
||||
TObject& obj() const
|
||||
{ return *_obj; }
|
||||
|
||||
// @cmember Costruttore (inizializza la chiave ed opzionalmente l'oggetto)
|
||||
THash_object(const char* k, TObject* o = NULL) : _key(k), _obj(o)
|
||||
{}
|
||||
// @cmember Distruttore
|
||||
virtual ~THash_object();
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TAssoc_array | Tabella hash di oggetti generici
|
||||
//
|
||||
// @base public |TObject
|
||||
class TAssoc_array : public TContainer
|
||||
|
||||
// @author:(INTERNAL) Guido
|
||||
|
||||
//@access:(INTERNAL) Private Member
|
||||
{
|
||||
// @cmember:(INTERNAL) Numero di oggetti contenuti nella tabella
|
||||
word _cnt;
|
||||
// @cmember:(INTERNAL) Numero di righe della tabella hash
|
||||
word _row;
|
||||
// @cmember:(INTERNAL) Numero di colonne della tabella hash
|
||||
word _col;
|
||||
// @cmember:(INTERNAL) Numero di righe della tabella hash per i metodi _item
|
||||
int _rowitem;
|
||||
// @cmember:(INTERNAL) Numero di colonne della tabella hash per i metodi _item
|
||||
int _colitem;
|
||||
// @cmember:(INTERNAL) Array contenente i dati veri e propri
|
||||
TArray _bucket;
|
||||
|
||||
// @access Protected member
|
||||
protected:
|
||||
TArray& bucket(int index);
|
||||
|
||||
// @cmember Cerca l'oggetto con chiave k
|
||||
THash_object* _lookup(const char* k, bool& isnew, bool insert = FALSE);
|
||||
// @cmember Copia tutto l'array associativo e ne duplica gli elementi
|
||||
TAssoc_array & copy(const TAssoc_array & a);
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Duplica l'array associativo copiandone gli elementi.
|
||||
virtual TObject* dup () const { return new TAssoc_array(*this);}
|
||||
|
||||
// @cmember Ritorna un puntatore al primo oggetto
|
||||
virtual TObject* first_item( );
|
||||
// @cmember Ritorna un puntatore all'ultimo oggetto
|
||||
virtual TObject* last_item( );
|
||||
// @cmember Ritorna un puntatore all'oggetto successivo al quello corrente
|
||||
virtual TObject* succ_item( );
|
||||
// @cmember Ritorna un puntatore all'oggetto che precede quello corrente
|
||||
virtual TObject* pred_item( );
|
||||
// @cmember Ritorna un puntatore ad un THash_object casuale (anche NULL)
|
||||
THash_object* random_hash_object();
|
||||
|
||||
// @cmember Ritorna il numero di elementi presenti come long
|
||||
virtual long objects() { return _cnt; }
|
||||
|
||||
// @cmember Ritorna il numero di elementi presenti
|
||||
int items() const { return _cnt; }
|
||||
// @cmember Cancella tutti gli elementi
|
||||
virtual void destroy();
|
||||
|
||||
// @cmember Aggiunge un oggetto. Se era gia' presente guarda il parametro force
|
||||
bool add(const char* key, TObject* obj = NULL, bool force = FALSE);
|
||||
|
||||
// @cmember Aggiunge una copia dell'oggetto
|
||||
bool add(const char* key, const TObject& obj, bool force = FALSE);
|
||||
|
||||
// @cmember Elimina un oggetto
|
||||
bool remove(const char* key);
|
||||
|
||||
// @cmember Controlla l'esistenza di una chiave
|
||||
bool is_key(const char* key) const ;
|
||||
|
||||
// @cmember Ritorna l'oggetto con chiave key
|
||||
TObject* objptr(const char* key) const ;
|
||||
|
||||
// @cmember Trova l'oggetto indicizzato
|
||||
TObject& find(const char* key) const ;
|
||||
|
||||
// @cmember Ritorna l'indice del oggetto con chiave key (piu' intuitivo di <mf TAssoc_array::find>)
|
||||
TObject& operator[] (const char* key) const
|
||||
{ return find(key); }
|
||||
|
||||
// iterazione come TToken_string
|
||||
// si puo' adoperare get() e get_hashobj() intercambiabilmente ma
|
||||
// non sono indipendenti (entrambe avanzano gli stessi contatori)
|
||||
|
||||
// @cmember Azzera il numero di riga e colonna corrente della tabella hash
|
||||
void restart()
|
||||
{ _row = 0; _col = 0; }
|
||||
// @cmember Ritorna solo l'oggetto
|
||||
TObject* get();
|
||||
// @cmember Ritorna l'oggetto e la relativa chiave
|
||||
THash_object* get_hashobj();
|
||||
|
||||
// @cmember Mette chiavi e opzionalmente valori (come stringa) nel <c TString_array> passato
|
||||
int get_keys(TString_array& kl, bool add_values = FALSE);
|
||||
// @cmember Operatore di assegnamento tra array associativi
|
||||
TAssoc_array& operator= (const TAssoc_array & a)
|
||||
{ return copy(a); }
|
||||
|
||||
// @cmember Costruttore
|
||||
TAssoc_array() : _cnt(0), _row(0), _col(0)
|
||||
{}
|
||||
// @cmember Costruttore. Copia tutto l'array associativo e ne duplica gli elementi
|
||||
TAssoc_array(const TAssoc_array& a) : _cnt(0), _row(0), _col(0)
|
||||
{ copy(a); }
|
||||
// @cmember Distruttore
|
||||
virtual ~TAssoc_array()
|
||||
{ destroy(); }
|
||||
};
|
||||
|
||||
class TCache : public TObject
|
||||
{
|
||||
TArray _data;
|
||||
|
||||
protected:
|
||||
virtual void discarding(const THash_object* obj);
|
||||
virtual TObject* key2obj(const char* key) pure;
|
||||
|
||||
public:
|
||||
TObject* objptr(const TString& key);
|
||||
TObject* objptr(size_t nkey);
|
||||
|
||||
void destroy(); // Not very useful, but who knows?
|
||||
TCache(size_t size = 0); // 883 assigned by default
|
||||
virtual ~TCache();
|
||||
};
|
||||
|
||||
#define FOR_EACH_ASSOC_STRING(__ass, __obj, __key, __str) \
|
||||
const char *__key, *__str; __ass.restart(); \
|
||||
for (THash_object* __obj = __ass.get_hashobj(); \
|
||||
__obj && ((__str = (const TString&)__obj->obj()) != NULL, __obj && (__key = __obj->key()) != NULL); \
|
||||
__obj = __ass.get_hashobj())
|
||||
|
||||
#define FOR_EACH_ASSOC_OBJECT(__ass, __obj, __key, __itm) \
|
||||
const char *__key; TObject* __itm; __ass.restart(); \
|
||||
for (THash_object* __obj = __ass.get_hashobj(); \
|
||||
__obj && (__itm = &__obj->obj()) != NULL, __obj && (__key = __obj->key()) != NULL; \
|
||||
__obj = __ass.get_hashobj())
|
||||
|
||||
#endif
|
181
omnia/checks.cpp
Executable file
181
omnia/checks.cpp
Executable file
@ -0,0 +1,181 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "checks.h"
|
||||
|
||||
const char* const AppTitle = "Omnia";
|
||||
|
||||
#define buildmsg() char msg[256];va_list argptr;va_start(argptr,fmt);vsprintf(msg,fmt,argptr);va_end(argptr)
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg fatal_box | Crea una finestra di ERRORE FATALE con il relativo messaggio
|
||||
bool fatal_box(
|
||||
const char* fmt, ...) // @parm Messaggio da stampare nella finestra
|
||||
// (il formato e' come nella printf del C)
|
||||
// @comm Il programma viene interrotto al momento in cui si e' verificato l'errore.
|
||||
{
|
||||
buildmsg();
|
||||
MessageBox(NULL, msg, AppTitle, MB_OK | MB_ICONSTOP);
|
||||
exit(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg error_box | Crea una finestra di ERRORE con il relativo messaggio
|
||||
bool error_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con il bottone OK
|
||||
// e l'icona punto esclamativo.
|
||||
{
|
||||
buildmsg();
|
||||
MessageBox(NULL, msg, AppTitle, MB_OK | MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg warning_box | Crea una finestra di ATTENZIONE con il relativo messaggio
|
||||
bool warning_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con il bottone OK
|
||||
// e l'icona punto di domanda.
|
||||
{
|
||||
buildmsg();
|
||||
MessageBox(NULL, msg, AppTitle, MB_OK | MB_ICONEXCLAMATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg message_box | Crea una finestra di INFORMAZIONE con relativo il messaggio
|
||||
bool message_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con il bottone OK
|
||||
// e l'icona informazioni.
|
||||
{
|
||||
buildmsg();
|
||||
MessageBox(NULL, msg, AppTitle, MB_OK | MB_ICONINFORMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg sorry_box | Crea una finestra di SCUSE con il relativo messaggio
|
||||
bool sorry_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con il bottone OK
|
||||
// e l'icona informazioni.
|
||||
{
|
||||
buildmsg();
|
||||
MessageBox(NULL, msg, AppTitle, MB_OK | MB_ICONINFORMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
// @msg yesno_box | Crea una finestra di RICHIESTA con il relativo messaggio
|
||||
bool noyes_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
{
|
||||
buildmsg();
|
||||
int ret = MessageBox(NULL, msg, AppTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
|
||||
return ret == IDYES;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg yesno_box | Crea una finestra di RICHIESTA con il relativo messaggio
|
||||
bool yesno_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con i bottni SI e NO
|
||||
// e l'icona col punto di domanda.
|
||||
//
|
||||
// @rdesc Ritorna il risultato della richiesta:
|
||||
//
|
||||
// @flag 1 | Se viene premuto il taso SI
|
||||
// @flag 0 | Se viene premuto il taso NO
|
||||
{
|
||||
buildmsg();
|
||||
int ret = MessageBox(NULL, msg, AppTitle, MB_ICONQUESTION | MB_YESNO);
|
||||
return ret == IDYES;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg yesnofatal_box | Crea una finestra di RICHIESTA con il relativo
|
||||
// messaggio, ma permette di terminare il programma
|
||||
bool yesnofatal_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con i bottoni SI e NO
|
||||
// e l'icona col punto di domanda.
|
||||
// <nl>A differenza della <m yesno_box> permette di terminare il programma
|
||||
// se viene premuto il tasto SI
|
||||
//
|
||||
// @rdesc Ritorna il risultato della richiesta:
|
||||
//
|
||||
// @flag 1 | Se viene premuto il tasto SI
|
||||
// @flag 0 | Se viene premuto il tasto NO
|
||||
//
|
||||
// @xref <m yesno_box> <m yesnofatal_box>
|
||||
{
|
||||
buildmsg();
|
||||
|
||||
#ifdef DBG
|
||||
char s[256]; sprintf(s, "%s\nContinuare ugualmente?", msg);
|
||||
const bool ret = yesno_box("%s", s);
|
||||
if (!ret)
|
||||
#endif
|
||||
fatal_box(msg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg yesnocancel_box | Crea una finestra di RICHIESTA con il relativo messaggio
|
||||
int yesnocancel_box(
|
||||
const char* fmt, // @parm Messaggio da stampare nella finestra
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Se si opera in ambiente Windows crea la finestra con i bottoni SI e NO
|
||||
// e l'icona col punto di domanda.
|
||||
//
|
||||
// @rdesc Ritorna il risultato della richiesta:
|
||||
//
|
||||
// @flag K_YES | Se viene premuto il tasto SI
|
||||
// @flag K_NO | Se viene premuto il tasto NO
|
||||
// @flag K_ESC | Se viene premuto il tosto ESC
|
||||
//
|
||||
// @xref <m yesno_box> <m yesnofatal_box>
|
||||
{
|
||||
buildmsg();
|
||||
int ret = MessageBox(NULL, msg, AppTitle, MB_ICONQUESTION | MB_YESNOCANCEL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
// @msg __trace | Permette di mandare dei messaggi nel file trace.log
|
||||
bool __trace(
|
||||
const char* fmt, // @parm Messaggio da stampare
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
// @comm Usato in fase di debug, permette di vedere se il programma ha
|
||||
// fatto certe operazioni (deve essere definito il simbolo TRC in
|
||||
// fase di compilazione).
|
||||
//
|
||||
// @rdesc Ritorna non 0 se riesca ad aprire il file trace.log
|
||||
{
|
||||
static FILE* f = NULL;
|
||||
if (f == NULL)
|
||||
f = fopen("trace.log", "w");
|
||||
if (f != NULL)
|
||||
{
|
||||
buildmsg();
|
||||
fprintf(f, "%s\n", msg);
|
||||
fflush(f);
|
||||
}
|
||||
return f != NULL;
|
||||
}
|
||||
|
95
omnia/checks.h
Executable file
95
omnia/checks.h
Executable file
@ -0,0 +1,95 @@
|
||||
#ifndef __CHECKS_H
|
||||
#define __CHECKS_H
|
||||
|
||||
#ifndef __STDTYPES_H
|
||||
#include "stdtypes.h"
|
||||
#endif
|
||||
|
||||
bool message_box(const char* fmt, ...);
|
||||
bool warning_box(const char* fmt, ...);
|
||||
bool sorry_box(const char* fmt, ...);
|
||||
bool error_box(const char* fmt, ...);
|
||||
bool fatal_box(const char* fmt, ...);
|
||||
bool noyes_box(const char* fmt, ...);
|
||||
bool yesno_box(const char* fmt, ...);
|
||||
int yesnocancel_box(const char* fmt, ...);
|
||||
bool yesnofatal_box(const char* fmt, ...);
|
||||
bool __trace(const char* fmt, ...);
|
||||
|
||||
// Utilizzate in fase di debug (definire il simbolo DBG in compilazione)
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
#ifdef DBG
|
||||
// @msg CHECK | Macro che richiama una <m fatal_box> per stampare messaggi a video
|
||||
#define CHECK(p, m) ( (p) ? (void)0 : (void) fatal_box( \
|
||||
"Check failed in %s, line %d:\n\r%s", \
|
||||
__FILE__, __LINE__, m) )
|
||||
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
|
||||
// @parm | m | Messaggio da stampare
|
||||
//
|
||||
// @comm Viene richiamata se <p p> e' FALSE.
|
||||
// <nl>Utilizzata in fase di debug (definire il simbolo DBG in compilazione).
|
||||
//
|
||||
// @xref <m CHECKS> <m CHECKD>
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg CHECKS | Macro che richiama una <m fatal_box> per stampare messaggi a video
|
||||
#define CHECKS(p, m, s0) ( (p) ? (void)0 : (void) fatal_box( \
|
||||
"Check failed in %s, line %d:\n\r%s%s", \
|
||||
__FILE__, __LINE__, m, s0) )
|
||||
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
|
||||
// @parm | m | Messaggio da stampare
|
||||
// @parm | s0 | Stringa aggiuntiva da stampare
|
||||
//
|
||||
// @comm Viene richiamata se <p p> e' FALSE. Oltre al messaggio passato in <p m>
|
||||
// stampa anche una strina aggiuntiva passata in <p s0>.
|
||||
// <nl>Utilizzata in fase di debug (definire il simbolo DBG in compilazione).
|
||||
//
|
||||
// @xref <m CHECK> <m CHECKD>
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg CHECKD | Macro che richiama una <m fatal_box> per stampare messaggi a video
|
||||
#define CHECKD(p, m, d0) ( (p) ? (void)0 : (void) fatal_box( \
|
||||
"Check failed in %s, line %d:\n%s%d", \
|
||||
__FILE__, __LINE__, m, d0) )
|
||||
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
|
||||
// @parm | m | Messaggio da stampare
|
||||
// @parm | d0 | Stringa aggiuntiva da stampare
|
||||
//
|
||||
// @comm Viene richiamata se <p p> e' FALSE. Oltre al messaggio passato in <p m>
|
||||
// stampa anche un numero passato in <p d0>.
|
||||
// <nl>Utilizzata in fase di debug (definire il simbolo DBG in compilazione).
|
||||
//
|
||||
// @xref <m CHECKS> <m CHECK>
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg CHECKD | Macro che richiama una <m yesnofatal_box> per stampare messaggi d'errore a video
|
||||
#define NFCHECK yesnofatal_box
|
||||
|
||||
// @xref <m CHECKS> <m CHECK>
|
||||
|
||||
#else
|
||||
|
||||
#define CHECK(p, m)
|
||||
#define CHECKS(p, m, s)
|
||||
#define CHECKD(p, m, d)
|
||||
#define NFCHECK 1 ? 0 : yesnofatal_box
|
||||
|
||||
#endif
|
||||
|
||||
// Utilizzata in fase di debug (definire il simbolo TRC in compilazione)
|
||||
|
||||
#ifdef TRC
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @msg TRACE | Macro che richiama la funzione <m __trace>
|
||||
#define TRACE __trace
|
||||
#else
|
||||
#define TRACE 1 ? 0 : __trace
|
||||
#endif
|
||||
|
||||
#endif // __CHECKS_H
|
71
omnia/classes.h
Executable file
71
omnia/classes.h
Executable file
@ -0,0 +1,71 @@
|
||||
#ifndef __CLASSES_H
|
||||
#define __CLASSES_H
|
||||
|
||||
// @N
|
||||
// Codici identificativi delle classi
|
||||
// @END
|
||||
|
||||
// @M
|
||||
#define CLASS_ERROR 0
|
||||
#define CLASS_OBJECT 1
|
||||
#define CLASS_SORTABLE 2
|
||||
|
||||
#define CLASS_STRING 10
|
||||
#define CLASS_FIXED_STRING 11
|
||||
#define CLASS_FILENAME 12
|
||||
#define CLASS_TOKEN_STRING 13
|
||||
|
||||
#define CLASS_APPLICATION 20
|
||||
#define CLASS_RELATION_APPLICATION 21
|
||||
#define CLASS_PRINT_APPLICATION 22
|
||||
|
||||
#define CLASS_PRINTER 50
|
||||
#define CLASS_PRINTROW 51
|
||||
|
||||
#define CLASS_CONTAINER 100
|
||||
#define CLASS_ARRAY 101
|
||||
#define CLASS_STACK 102
|
||||
|
||||
#define CLASS_WINDOW 200
|
||||
#define CLASS_SHEET 201
|
||||
#define CLASS_MASK 210
|
||||
#define CLASS_FIELD 220
|
||||
#define CLASS_TEXT_FIELD 221
|
||||
#define CLASS_LINE_FIELD 222
|
||||
#define CLASS_RECTANGLE_FIELD 223
|
||||
#define CLASS_GROUPBOX_FIELD 224
|
||||
#define CLASS_OPERABLE_FIELD 230
|
||||
#define CLASS_BUTTON_FIELD 231
|
||||
#define CLASS_SHEET_FIELD 232
|
||||
#define CLASS_BROWSEFILE_FIELD 233
|
||||
#define CLASS_MEMO_FIELD 234
|
||||
#define CLASS_ZOOM_FIELD 235
|
||||
#define CLASS_EDITABLE_FIELD 240
|
||||
#define CLASS_BOOLEAN_FIELD 241
|
||||
#define CLASS_LIST_FIELD 242
|
||||
#define CLASS_RADIO_FIELD 243
|
||||
#define CLASS_EDIT_FIELD 244
|
||||
#define CLASS_REAL_FIELD 245
|
||||
#define CLASS_DATE_FIELD 246
|
||||
#define CLASS_GRID_FIELD 247
|
||||
#define CLASS_TREE_FIELD 248
|
||||
#define CLASS_CURRENCY_FIELD 249
|
||||
#define CLASS_GOLEM_CLIENT_FIELD 250
|
||||
|
||||
#define CLASS_BASEISAMFILE 300
|
||||
#define CLASS_ISAMFILE 301
|
||||
#define CLASS_SYSTEMISAMFILE 302
|
||||
#define CLASS_LOCALISAMFILE 303
|
||||
#define CLASS_ISAMTEMPFILE 304
|
||||
#define CLASS_EXTERNISAMFILE 304
|
||||
#define CLASS_SORTEDFILE 310
|
||||
|
||||
#define CLASS_RECTYPE 350
|
||||
#define CLASS_VARIABLE_RECTYPE 351
|
||||
#define CLASS_AUTO_VARIABLE_RECTYPE 352
|
||||
#define CLASS_EXT_RECTYPE 353
|
||||
|
||||
#define CLASS_GOLEM 900
|
||||
|
||||
// @END
|
||||
#endif // __CLASSES_H
|
89
omnia/object.cpp
Executable file
89
omnia/object.cpp
Executable file
@ -0,0 +1,89 @@
|
||||
#define __OBJECT_CPP
|
||||
|
||||
#include "object.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Object
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
const char* TObject::class_name() const
|
||||
{
|
||||
return "Object";
|
||||
}
|
||||
|
||||
word TObject::class_id() const
|
||||
{
|
||||
return CLASS_OBJECT;
|
||||
}
|
||||
|
||||
bool TObject::is_kind_of(word cid) const
|
||||
{
|
||||
return cid == CLASS_OBJECT;
|
||||
}
|
||||
|
||||
|
||||
bool TObject::ok() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
TObject* TObject::dup() const
|
||||
|
||||
{
|
||||
CHECK(FALSE, "Can't duplicate an Object");
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
void TObject::print_on(ostream& out) const
|
||||
|
||||
{
|
||||
out << class_name();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Error Object
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
const char* TError_Object::class_name() const
|
||||
{
|
||||
return "Error_Object";
|
||||
}
|
||||
|
||||
|
||||
word TError_Object::class_id() const
|
||||
{
|
||||
return CLASS_ERROR;
|
||||
}
|
||||
|
||||
bool TError_Object::is_kind_of(word cid) const
|
||||
{
|
||||
return cid == CLASS_ERROR || TObject::is_kind_of(cid);
|
||||
}
|
||||
|
||||
bool TError_Object::ok() const
|
||||
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Sortable
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
const char* TSortable::class_name() const
|
||||
{
|
||||
return "Sortable";
|
||||
}
|
||||
|
||||
word TSortable::class_id() const
|
||||
{
|
||||
return CLASS_SORTABLE;
|
||||
}
|
||||
|
||||
bool TSortable::is_kind_of(word cid) const
|
||||
{
|
||||
return cid == CLASS_SORTABLE || TObject::is_kind_of(cid);
|
||||
}
|
268
omnia/object.h
Executable file
268
omnia/object.h
Executable file
@ -0,0 +1,268 @@
|
||||
#ifndef __OBJECT_H
|
||||
#define __OBJECT_H
|
||||
|
||||
#ifndef __IOSTREAM_H
|
||||
#include <iostream.h>
|
||||
#endif
|
||||
|
||||
#ifndef __CLASSES_H
|
||||
#include "classes.h"
|
||||
#endif
|
||||
|
||||
#ifndef __STDTYPES_H
|
||||
#include "stdtypes.h"
|
||||
#endif
|
||||
|
||||
#ifndef __CHECKS_H
|
||||
#include "checks.h"
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TObject | Classe base per la definizione della gerarchia degli oggetti
|
||||
class TObject
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Distruttore
|
||||
virtual ~TObject()
|
||||
{}
|
||||
// @cmember Ritorna il nome della classe
|
||||
virtual const char* class_name() const;
|
||||
// @cmember Ritorna l'id della classe
|
||||
virtual word class_id() const;
|
||||
// @cmember Controlla se si tratta di un oggetto derivato dalla classe <p cid>
|
||||
virtual bool is_kind_of(word cid) const;
|
||||
// @cmember Controlla se si tratta di un oggetto valido (sempre TRUE)
|
||||
virtual bool ok() const;
|
||||
// @cmember Duplica un'oggetto
|
||||
virtual TObject* dup() const;
|
||||
// @cmember Permette di stampare l'oggetto
|
||||
virtual void print_on(ostream& out) const;
|
||||
// @cmember Permette di leggere l'oggetto da istream
|
||||
virtual void read_from(istream&)
|
||||
{}
|
||||
// @cmember Ritorna il codice hash dell'oggetto
|
||||
virtual word hash() const
|
||||
{ return 0; }
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Error Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TError_Object | Classe per poter ritornare un oggetto sempre errato (ok() == false)
|
||||
//
|
||||
// @base public | TObject
|
||||
class TError_Object : public TObject
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Ritorna il nome dell'oggetto
|
||||
virtual const char* class_name() const;
|
||||
// @cmember Ritorna l'id della classe
|
||||
virtual word class_id() const;
|
||||
// @cmember Controlla se si tratta di un oggetto derivato dalla classe <p cid>
|
||||
virtual bool is_kind_of(word cid) const;
|
||||
// @cmember Controlla se si tratta di un oggetto valido (sempre FALSE)
|
||||
virtual bool ok() const;
|
||||
|
||||
// @xref <c TObject>
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Error Object
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// @class TSortable | Classe per la comparazione degli oggetti
|
||||
//
|
||||
// @base public | TObject
|
||||
class TSortable : public TObject
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access Public Memebr
|
||||
public:
|
||||
// @cmember Permette la comparazione degli oggetti
|
||||
// <nl>Ritorna: <gt>0 se <p this> <gt> <p s>
|
||||
// <nl> 0 se <p this> == <p s>
|
||||
// <nl> <lt>0 se <p this> <lt> <p s>
|
||||
// <nl> UNDEFINED se l'ordine non e' definito
|
||||
virtual int compare(const TSortable& s) const pure;
|
||||
// @cmember Ritorna il nome della classe
|
||||
virtual const char* class_name() const;
|
||||
// @cmember Ritorna l'id della classe
|
||||
virtual word class_id() const;
|
||||
// @cmember Controlla se si tratta di un oggetto derivato dalla classe <p cid>
|
||||
virtual bool is_kind_of(word cid) const;
|
||||
// @cmember Distruttore
|
||||
virtual ~TSortable()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// inline functions
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline ostream& | operator <lt><lt> | Permette di reindirizzare l'oggeto per la stampa
|
||||
|
||||
// @rdesc Ritorna l'output sul quale e' stata reindirizzata la stampa
|
||||
inline ostream& operator <<(
|
||||
ostream& out, // @parm Indica l'output sul quale stampare l'oggetto
|
||||
const TObject& obj) // @parm Oggetto da stampare
|
||||
{
|
||||
obj.print_on(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline istream& | operator <gt><gt> | Permette di leggere l'oggetto
|
||||
//
|
||||
// @rdesc Ritorna l'input dal quale e' stato letto l'oggetto
|
||||
inline istream& operator >>(
|
||||
istream& in, // @parm Input da cui leggere l'oggetto
|
||||
TObject& obj) // @parm Indirizzo in cui posizionare l'oggetto letto
|
||||
|
||||
// @comm Legge dall'input passato come parametro l'oggetto, nel caso si tratti
|
||||
// di un oggetto on valido viene dato un messaggio di errore.
|
||||
{
|
||||
obj.read_from(in);
|
||||
CHECK(obj.ok(), "Can't read an Object from a stream");
|
||||
return in;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator == | Controlla se 2 oggetti sono uguali
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag TRUE | Se i due oggetti sono uguali
|
||||
// @flag FALSE | Se i due oggetti sono diversi
|
||||
inline bool operator ==(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
// @comm Controlla se i due oggetti passati come parametro sono uguali
|
||||
// utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res == 0 || res == UNDEFINED;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator <gt> | Controlla se un oggetto e' maggiore dell'altro
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori:
|
||||
//
|
||||
// @flag TRUE | Se <p a> e' maggiore di <p b>
|
||||
// @flag FALSE | Se <p b> e' maggiore o uguale a <p a>
|
||||
inline bool operator >(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
|
||||
// @comm Controlla se l'oggetti passato come primo parametro e' maggiore del
|
||||
// secondo utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res > 0 || res == UNDEFINED;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator <lt> | Controlla se un oggetto e' minore dell'altro
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag TRUE | Se <p a> e' minore di <p b>
|
||||
// @flag FALSE | Se <p b> e' minore o uguale a <p a>
|
||||
inline bool operator <(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
|
||||
// @comm Controlla se l'oggetti passato come primo parametro e' minore del
|
||||
// secondo utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res < 0 || res == UNDEFINED;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator <gt>= | Controlla se un oggetto e' maggiore o uguale all'altro
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag TRUE | Se <p a> e' maggiore o uguale a <p b>
|
||||
// @flag FALSE | Se <p b> e' maggiore <p a>
|
||||
inline bool operator >=(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
|
||||
//
|
||||
// @comm Controlla se l'oggetti passato come primo parametro e' maggiore o uguale al
|
||||
// secondo utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res >= 0 || res == UNDEFINED;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator <lt>= | Controlla se un oggetto e' minore o uguale all'altro
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag TRUE | Se <p a> e' minore o uguale a <p b>
|
||||
// @flag FALSE | Se <p b> e' minore <p a>
|
||||
inline bool operator <=(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
|
||||
// @comm Controlla se l'oggetti passato come primo parametro e' minore o uguale al
|
||||
// secondo utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res <= 0 || res == UNDEFINED;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func inline bool | operator != | Controlla se 2 oggetti sono diversi
|
||||
//
|
||||
// @rdesc Ritorna i seguenti valori
|
||||
//
|
||||
// @flag TRUE | Se i due oggetti sono diversi
|
||||
// @flag FALSE | Se i due oggetti sono uguali
|
||||
inline bool operator !=(
|
||||
const TSortable& a, // @parm Primo oggetto da confrontare
|
||||
const TSortable& b) // @parm Secondo oggetto da confrontare
|
||||
|
||||
// @comm Controlla se i due oggetti passati come parametro sono diversi
|
||||
// utilizzando il criterio di comparazione previsto per l'oggetto.
|
||||
{
|
||||
int res = a.compare(b);
|
||||
return res != 0 && res != UNDEFINED;
|
||||
}
|
||||
|
||||
#ifdef __OBJECT_CPP
|
||||
#define extern
|
||||
#endif
|
||||
|
||||
extern TError_Object error_object;
|
||||
|
||||
#undef extern
|
||||
|
||||
#endif // __OBJECT_H
|
2
omnia/stdtypes.cpp
Executable file
2
omnia/stdtypes.cpp
Executable file
@ -0,0 +1,2 @@
|
||||
|
||||
|
59
omnia/stdtypes.h
Executable file
59
omnia/stdtypes.h
Executable file
@ -0,0 +1,59 @@
|
||||
#ifndef __STDTYPES_H
|
||||
#define __STDTYPES_H
|
||||
|
||||
#ifndef DBG
|
||||
#ifndef NDEBUG
|
||||
#define DBG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define pure =0
|
||||
|
||||
#define HIDDEN static
|
||||
|
||||
#define EOL -1
|
||||
#define NOERR 0
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type bool | Tipo booleano che puo' assumere i valori TRUE (definito come 1)
|
||||
// e FALSE (definito come 0).
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#define TRUE true
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned short bool;
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type word | Tipo per la definizione di tipi di lunghezza pari a due byte
|
||||
typedef unsigned short word;
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type dword | Tipo per la definizione di tipi di lunghezza pari a quattro byte
|
||||
typedef unsigned int dword;
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type byte | Tipo per la definizione di tipi di lunghezza pari ad un byte
|
||||
typedef unsigned char byte;
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @type KEY | Tipo per la definizione di variabili destinati a contenere i caratteri
|
||||
// immessi da tastiera
|
||||
typedef unsigned short KEY;
|
||||
|
||||
#define UNDEFINED -32767
|
||||
|
||||
|
||||
#endif // __STDTYPES_H
|
||||
|
||||
|
1841
omnia/strings.cpp
Executable file
1841
omnia/strings.cpp
Executable file
File diff suppressed because it is too large
Load Diff
740
omnia/strings.h
Executable file
740
omnia/strings.h
Executable file
@ -0,0 +1,740 @@
|
||||
#ifndef __STRINGS_H
|
||||
#define __STRINGS_H
|
||||
|
||||
#ifndef _INC_STRING
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ARRAY_H
|
||||
#include "array.h"
|
||||
#endif
|
||||
|
||||
#define SAFE_PIPE_CHR '¦'
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class Classe per la definizione della stringhe
|
||||
//
|
||||
// @base public | TObject
|
||||
class TString : public TObject
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember Puntatore alla stringa
|
||||
char* _str;
|
||||
// @cmember Lunghezza della stringa
|
||||
int _size;
|
||||
|
||||
// @cmember Espande la stringa per altri caratteri
|
||||
int make_room(int size);
|
||||
// @cmember Inizializza con la stringa puntata da char* di lunghezza size
|
||||
TString& set(const char*);
|
||||
|
||||
// @cmember Costruttore per consentire la derivazione delle TFixed_string
|
||||
TString(char* str, int size) : _str(str), _size(size)
|
||||
{}
|
||||
|
||||
// @access Public member
|
||||
public:
|
||||
// @cmember Cambia la dimensione della stringa eventualmente preservandone il contenuto iniziale
|
||||
virtual void resize(int size, bool cpy);
|
||||
|
||||
// @cmember Costruttore
|
||||
TString();
|
||||
// @cmember Costruttore di default per una stringa data
|
||||
TString(int size, char c='\0');
|
||||
// @cmember Costruttore a partire da una stringa s
|
||||
TString(const char* s);
|
||||
// @cmember Costruttore da un oggetto TString s
|
||||
TString(const TString& s);
|
||||
// @cmember Distruttore
|
||||
virtual ~TString();
|
||||
|
||||
// @cmember Ritorna il nome della classe
|
||||
virtual const char* class_name() const;
|
||||
// @cmember Ritorna l'identificatore della classe
|
||||
virtual word class_id() const;
|
||||
// @cmember Controlla se si tratta di una stringa valida (diversa da NULL)
|
||||
virtual bool ok() const
|
||||
{ return _str != NULL; }
|
||||
// @cmember Duplica una stringa
|
||||
virtual TObject* dup() const;
|
||||
// @cmember Stampa una stringa
|
||||
virtual void print_on(ostream& out) const;
|
||||
// @cmember Legge una stringa
|
||||
virtual void read_from(istream& in);
|
||||
// @cmember Ritorna il valore hash della stringa
|
||||
virtual word hash() const;
|
||||
|
||||
// @cmember const char * | operator const char*() | | Trasforma una stringa
|
||||
// in puntatore a carattere
|
||||
operator const char*() const
|
||||
{ return (const char*)_str; }
|
||||
// @cmember Ritorna un riferimento al carattere i-esimo della stringa
|
||||
char& operator[](int i)
|
||||
{
|
||||
CHECKD(i >= 0 && i <= _size, "Bad string subscript: ", i);
|
||||
return _str[i];
|
||||
}
|
||||
// @cmember Ritorna il carattere i-esimo della stringa
|
||||
char operator[](int i) const
|
||||
{
|
||||
CHECKD(i >= 0 && i <= _size, "Bad string subscript: ", i);
|
||||
return _str[i];
|
||||
}
|
||||
|
||||
// @cmember Ritorna la dimensione allocata della stringa
|
||||
int size() const
|
||||
{ return _size; }
|
||||
// @cmember Ritorna la lunghezza della stringa (numero di caratteri)
|
||||
int len() const
|
||||
{ return _str ? strlen(_str) : 0; }
|
||||
// @cmember Controlla se la stringa e' vuota (TRUE se non contiene caratteri)
|
||||
bool empty() const
|
||||
{ return *_str == '\0'; }
|
||||
// @cmember Controlla se la stringa non e' vuota (TRUE se contiene caratteri)
|
||||
bool not_empty() const
|
||||
{ return *_str != '\0'; }
|
||||
// @cmember Controlla se la stringa e' vuota o contiene solo whitespace (TRUE se vuota)
|
||||
bool blank() const;
|
||||
|
||||
// @cmember Ritorna la posizione della prima occorrenza carattere char nell'oggetto TString
|
||||
int find(char, int from = 0) const;
|
||||
// @cmember Ritorna la posizione dell'ultima occorrenza carattere char nell'oggetto TString
|
||||
int rfind(char) const;
|
||||
// @cmember Ritorna la posizione della stringa s nell'oggetto TString
|
||||
int find(const char* s, int from = 0) const;
|
||||
// @cmember Sostituisce le occorrenze di <p find_char> col carattere <p replace_char>
|
||||
int replace(char find_char, char replace_char);
|
||||
|
||||
// @cmember Ritorna l'oggetto TString composto dai count caratteri da sinistra
|
||||
const TString& left(int count) const;
|
||||
// @cmember Ritorna l'oggetto TString composto dai count caratteri a partire da from
|
||||
const TString& mid(int from, int count = -1) const;
|
||||
// @cmember Ritorna la stringa da from a to (escluso)
|
||||
const TString& sub(int from, int to = -1) const;
|
||||
// @cmember Ritorna l'oggetto TString composto dai count caratteri da destra
|
||||
const TString& right(int count) const;
|
||||
|
||||
// @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri da sinistra
|
||||
TString sleft(int count) const
|
||||
{ return ((TString)left(count)); }
|
||||
// @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri a partire da from
|
||||
TString smid(int from, int count = -1) const
|
||||
{ return ((TString)mid(from, count)); }
|
||||
// @cmember Ritorna un oggetto TString temporaneo composto dai caratteri da from a to (escluso)
|
||||
TString ssub(int from, int to = -1) const
|
||||
{ return ((TString)sub(from, to)); }
|
||||
// @cmember Ritorna un oggetto TString temporaneo composto dai count caratteri da destra
|
||||
TString sright(int count) const
|
||||
{ return ((TString)right(count)); }
|
||||
|
||||
// @cmember Riempe la stringa con n caratteri c
|
||||
TString& fill(char c, int n = -1);
|
||||
// @cmember Riempe la stringa con n caratteri spazio (chiama <mf TString::resize>)
|
||||
TString& spaces(int n = -1)
|
||||
{ return fill(' ', n); }
|
||||
// @cmember Sovrascrive la stringa s dalla posizione pos
|
||||
TString& overwrite(const char* s, int pos = 0, int len = 0);
|
||||
// @cmember Inserisce la stringa s dalla posizione pos
|
||||
TString& insert(const char* s, int pos = 0);
|
||||
|
||||
// @cmember Elimina tutti i caratteri contenuti in k
|
||||
TString& strip(const char* k);
|
||||
// @cmember Elimina tutti gli spazi non contenuti tra apici singoli o doppi
|
||||
TString& strip_spaces();
|
||||
// @cmember Elimina tutti gli spazi doppi
|
||||
TString& strip_d_spaces();
|
||||
// @cmember Elimina gli spazi da sinistra o i primi n caratteri (da sinistra).
|
||||
TString& ltrim(int n = 0);
|
||||
// @cmember Elimina gli spazi da destra o i primi n caratteri (da destra).
|
||||
TString& rtrim(int n = 0);
|
||||
// @cmember Composizione di <mf TString::ltrim> e <mf TString::rtrim> per eliminare
|
||||
// gli spazi iniziali e finali
|
||||
TString& trim();
|
||||
// @cmember Aggiunge spazi a destra fino alla dimensione indicata
|
||||
TString& rpad(const int n,const char c=' ');
|
||||
// @cmember Aggiunge spazi a destra fino alla dimensione indicata
|
||||
TString& lpad(const int n,const char c=' ');
|
||||
|
||||
// @cmember Giustifica l'oggetto stringa a destra
|
||||
TString& right_just(int n = -1, char c = ' ');
|
||||
// @cmember Centra l'oggetto stringa
|
||||
TString& center_just(int n = -1, char c = ' ');
|
||||
// @cmember Giustifica l'oggetto stringa a sinistra
|
||||
TString& left_just(int n = -1, char c = ' ');
|
||||
|
||||
// @cmember Formatta una stringa usando il formato dato da pic
|
||||
TString& picture(const char* pic, const char* s);
|
||||
|
||||
// @cmember Copia n caratteri nella stringa oggetto
|
||||
int strncpy(const char* s, int n);
|
||||
|
||||
// @cmember Manda un output formattato alla stringa oggetto
|
||||
virtual TString& format(const char* fmt, ...);
|
||||
|
||||
// @cmember Tronca la stringa alla posizione n-esima.
|
||||
TString& cut(int n);
|
||||
|
||||
// @cmember Ritorna il buffer interno della stringa (usare con attenzione!)
|
||||
char* get_buffer(int min_size = -1);
|
||||
|
||||
// @cmember Converte la stringa in maiuscolo
|
||||
TString& upper(int from =0, int to=-1);
|
||||
// @cmember Converte la stringa in minuscolo
|
||||
TString& lower(int from =0, int to=-1);
|
||||
// @cmember Permette di trovare il plurale di una stringa
|
||||
TString& add_plural(long num, const char * name);
|
||||
|
||||
// @cmember Assegna la stringa passata con indirizzo
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set(s._str); }
|
||||
// @cmember Assegna la stringa passata
|
||||
const TString& operator =(const char* s)
|
||||
{ return set(s); }
|
||||
|
||||
// @cmember Fa scorrere a sinistra la stringa e restituisce l'ultimo carattere scartato
|
||||
char shift(int n=1);
|
||||
// @cmember Fa scorrere a destra la stringa e restituisce l'ultimo carattere scartato
|
||||
char rshift(int n=1)
|
||||
{return shift(-n);}
|
||||
// @cmember Concatena una stringa all'oggetto stringa
|
||||
TString& operator <<(const char*);
|
||||
// @cmember Concatena un carattere all'oggetto stringa
|
||||
TString& operator <<(char);
|
||||
// @cmember Concatena un intero all'oggetto stringa
|
||||
TString& operator <<(int);
|
||||
// @cmember Concatena un long all'oggetto stringa
|
||||
TString& operator <<(long);
|
||||
// @cmember Concatena un double all'oggetto stringa
|
||||
TString& operator <<(double);
|
||||
// @cmember Concatena un oggetto all'oggetto stringa
|
||||
TString& operator <<(const TObject& obj);
|
||||
// @cmember Concatena una stringa all'oggetto stringa (usato per aumentare l'efficienza)
|
||||
TString& operator <<(const TString& str);
|
||||
|
||||
|
||||
// @cmember Controlla se due stringhe sono uguali
|
||||
bool operator ==(const char* s) const
|
||||
{ return s ? strcmp(_str, s) == 0 : empty();}
|
||||
// @cmember Controlla se due stringhe sono uguali
|
||||
bool operator ==(char* s) const
|
||||
{ return s ? strcmp(_str, s) == 0 : empty();}
|
||||
// @cmember Controlla se due stringe sono uguali
|
||||
bool operator ==(const TString& s) const
|
||||
{ return strcmp(_str, s._str) == 0; }
|
||||
// @cmember Controlla se due stringhe sono diverse
|
||||
bool operator !=(const char* s) const
|
||||
{ return s ? strcmp(_str, s) != 0 : not_empty();}
|
||||
// @cmember Controlla se due stringhe sono diverse
|
||||
bool operator !=(char* s) const
|
||||
{ return s ? strcmp(_str, s) != 0 : not_empty();}
|
||||
// @cmember Controlla se due stringhe sono diverse
|
||||
bool operator !=(const TString& s) const
|
||||
{ return strcmp(_str, s._str) != 0; }
|
||||
// @cmember Controlla se una stringa e' minore di un'altra
|
||||
bool operator <(const char* s) const
|
||||
{ return s ? strcmp(_str, s) < 0 : FALSE;}
|
||||
// @cmember Controlla se una stringa e' maggiore di un'altra
|
||||
bool operator >(const char* s) const
|
||||
{ return s ? strcmp(_str, s) > 0 : not_empty();}
|
||||
// @cmember Controlla se una stringa e' maggiore o uguale ad un'altra
|
||||
bool operator >=(const char* s) const
|
||||
{ return s ? strcmp(_str, s) >= 0 : TRUE;}
|
||||
// @cmember Controlla se una stringa e' minore o uguale ad un'altra
|
||||
bool operator <=(const char* s) const
|
||||
{ return s ? strcmp(_str, s) <= 0 : empty();}
|
||||
// @cmember Controlla se una stringa e' minore di un'altra
|
||||
bool operator <(const TString & s) const
|
||||
{ return strcmp(_str, s._str) < 0; }
|
||||
// @cmember Controlla se una stringa e' maggiore di un'altra
|
||||
bool operator >(const TString & s) const
|
||||
{ return strcmp(_str, s._str) > 0; }
|
||||
// @cmember Controlla se una stringa e' maggiore o uguale ad un'altra
|
||||
bool operator >=(const TString & s) const
|
||||
{ return strcmp(_str, s._str) >= 0; }
|
||||
// @cmember Controlla se una stringa e' minore o uguale ad un'altra
|
||||
bool operator <=(const TString & s) const
|
||||
{ return strcmp(_str, s._str) <= 0; }
|
||||
// @cmember Compara due stringhe (o i primi max caratteri)
|
||||
int compare(const char* s, int max = -1, bool ignorecase = FALSE) const;
|
||||
// @cmember Controlla se la strinvga comincia per s
|
||||
bool starts_with(const char* s, bool ignorecase = FALSE) const;
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TFixed_string | Classe per la definizione di stringhe di lunghezza
|
||||
// fissa e non rilocabili dinamicamente
|
||||
//
|
||||
// @base public | TString
|
||||
class TFixed_string : public TString
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember Causa un erroe fatale
|
||||
virtual void resize(int size, bool cpy);
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore
|
||||
TFixed_string(const char* str, int size = -1);
|
||||
// @cmember Distruttore
|
||||
virtual ~TFixed_string();
|
||||
|
||||
// @cmember Manda un output formattato alla stringa oggetto
|
||||
virtual TString& format(const char* fmt, ...);
|
||||
|
||||
// @cmember Assegna la stringa passata con indirizzo
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set((const char*)s); }
|
||||
// @cmember Assegna la stringa passata
|
||||
const TString& operator =(const char* str)
|
||||
{ return set(str); }
|
||||
};
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString4 | Definisce le stringhe di 4 caratteri
|
||||
//
|
||||
// @base public | TFixed_string
|
||||
//
|
||||
// @author:(INTERNAL) Augusto
|
||||
//
|
||||
// @comm Questa classe e' identica alla <c TString16> per quanto riguarda i public member e quindi
|
||||
// si rimanda a tale classe per ulteriori spiegazioni.
|
||||
class TString4 : public TFixed_string
|
||||
{
|
||||
char _str4[5];
|
||||
|
||||
public:
|
||||
TString4(const char* s = "") : TFixed_string(_str4, 5) { set(s); }
|
||||
TString4(const TString& s) : TFixed_string(_str4, 5) { set(s); }
|
||||
TString4(const TString4& s) : TFixed_string(_str4, 5) { set(s); }
|
||||
const TString& operator =(const char* s) { return set(s); }
|
||||
const TString& operator =(const TString& s) { return set((const char*)s); }
|
||||
const TString& operator =(const TString4& s) { return set((const char*)s); }
|
||||
};
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString8 | Definisce le stringhe di 8 caratteri
|
||||
//
|
||||
// @base public | TFixed_string
|
||||
//
|
||||
// @author:(INTERNAL) Augusto
|
||||
//
|
||||
// @comm Questa classe e' identica alla <c TString16> per quanto riguarda i public member e quindi
|
||||
// si rimanda a tale classe per ulteriori spiegazioni.
|
||||
class TString8 : public TFixed_string
|
||||
{
|
||||
char _str8[9];
|
||||
|
||||
public:
|
||||
TString8(const char* s = "") : TFixed_string(_str8, 9) { set(s); }
|
||||
TString8(const TString& s) : TFixed_string(_str8, 9) { set(s); }
|
||||
TString8(const TString8& s) : TFixed_string(_str8, 9) { set(s); }
|
||||
const TString& operator =(const char* s) { return set(s); }
|
||||
const TString& operator =(const TString& s) { return set((const char*)s); }
|
||||
const TString& operator =(const TString8& s) { return set((const char*)s); }
|
||||
};
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString16 | Definisce le stringhe di 16 caratteri
|
||||
//
|
||||
// @base public | TFixed_string
|
||||
class TString16 : public TFixed_string
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access:(INTERNAL) Private member
|
||||
|
||||
// @cmember:(INTERNAL) Stringa di 16 caratteri
|
||||
char _str16[17];
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Duplica una stringa di 16 caratteri
|
||||
virtual TObject* dup() const { return new TString16(_str16); }
|
||||
|
||||
// @cmember Costruttore
|
||||
TString16(const char* s = "") : TFixed_string(_str16, 17)
|
||||
{ set(s); }
|
||||
// @cmember Costruttore
|
||||
TString16(const TString& s) : TFixed_string(_str16, 17)
|
||||
{ set(s); }
|
||||
// @cmember Costruttore
|
||||
TString16(const TString16& s) : TFixed_string(_str16, 17)
|
||||
{ set(s); }
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const char* s)
|
||||
{ return set(s); }
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set((const char*)s); }
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const TString16& s)
|
||||
{ return set((const char*)s); }
|
||||
|
||||
// @comm Sono definite anche le classi <c TString80> e <c TString256> per le
|
||||
// stringhe rispettivamente di 80 e 256 caratteri. I class member sono
|
||||
// gli stessi, la differenza e' solo nel numero di caratteri della stringa.
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString80 | Definisce le stringhe di 80 caratteri
|
||||
//
|
||||
// @base public | TFixed_string
|
||||
//
|
||||
// @author:(INTERNAL) Guido
|
||||
//
|
||||
// @comm Questa classe e' identica alla <c TString16> per quanto riguarda i public member e quindi
|
||||
// si rimanda a tale classe per ulteriori spiegazioni.
|
||||
class TString80 : public TFixed_string
|
||||
{
|
||||
char _str80[81];
|
||||
|
||||
public:
|
||||
// @cmember Duplica una stringa di 80 caratteri
|
||||
virtual TObject* dup() const { return new TString80(_str80); }
|
||||
|
||||
TString80(const char* s = "") : TFixed_string(_str80, 81) { set(s); }
|
||||
TString80(const TString& s) : TFixed_string(_str80, 81) { set(s); }
|
||||
TString80(const TString80& s) : TFixed_string(_str80, 81) { set(s); }
|
||||
const TString& operator =(const char* s) { return set(s); }
|
||||
const TString& operator =(const TString& s) { return set((const char*)s); }
|
||||
const TString& operator =(const TString80& s) { return set((const char*)s); }
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString256 | Definisce le stringhe di 256 caratteri
|
||||
//
|
||||
// @base public | TFixed_string
|
||||
//
|
||||
// @author:(INTERNAL) Guido
|
||||
//
|
||||
// @comm Questa classe e' identica alla <c TString16> per quanto riguarda i public member e quindi
|
||||
// si rimanda a tale classe per ulteriori spiegazioni.
|
||||
class TString256 : public TFixed_string
|
||||
{
|
||||
char _str256[257];
|
||||
|
||||
public:
|
||||
// @cmember Duplica una stringa di 256 caratteri
|
||||
virtual TObject* dup() const { return new TString256(_str256); }
|
||||
|
||||
TString256(const char* s = "") : TFixed_string(_str256, 257) { set(s); }
|
||||
TString256(const TString& s) : TFixed_string(_str256, 257) { set(s); }
|
||||
TString256(const TString256& s) : TFixed_string(_str256, 257) { set(s); }
|
||||
const TString& operator =(const char* s) { return set(s); }
|
||||
const TString& operator =(const TString& s) { return set((const char*)s); }
|
||||
const TString& operator =(const TString256& s) { return set((const char*)s); }
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TFilename | Classe per la gestione dei nome dei file
|
||||
//
|
||||
// @base public | TString
|
||||
class TFilename : public TString
|
||||
// @author:(INTERNAL) Guido
|
||||
|
||||
{
|
||||
// @comm Nel caso di utilizzo di Windows 95 occorre cambiare le classe base in <c TString256>
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore
|
||||
TFilename(const char* n = "") : TString(256)
|
||||
{ set(n); }
|
||||
// @cmember Costruttore
|
||||
TFilename(const TString& n) : TString(256)
|
||||
{ set(n); }
|
||||
// @cmember Costruttore
|
||||
TFilename(const TFilename& n) : TString(256)
|
||||
{ set(n); }
|
||||
|
||||
// @cmember Assegnazione tra TFilename e stringa
|
||||
const TString& operator =(const char* s)
|
||||
{ return set(s); }
|
||||
// @cmember Assegnazione tra TFilename e TString
|
||||
const TString& operator =(const TString& s)
|
||||
{ return set((const char*)s); }
|
||||
// @cmember Assegnazione tra TFilename e TFilename
|
||||
const TString& operator =(const TFilename& s)
|
||||
{ return set((const char*)s); }
|
||||
|
||||
// @cmember Controlla il formato del nome del file
|
||||
virtual bool ok() const;
|
||||
|
||||
// @cmember Ritorna l'estensione del file
|
||||
const char* ext() const;
|
||||
// @cmember Imposta come estensione la stringa puntata da char*
|
||||
void ext(const char*);
|
||||
|
||||
// @cmember Concatena un nome di file ad una directory
|
||||
TFilename& add(const char* n);
|
||||
|
||||
// @cmember Controlla se si tratta di un path assoluto
|
||||
bool is_absolute_path() const;
|
||||
// @cmember Controlla se si tratta di un path relativo
|
||||
bool is_relative_path() const { return !is_absolute_path(); }
|
||||
// @cmember Trasforma un path da relativo ad assoluto
|
||||
const TFilename& make_absolute_path();
|
||||
// @cmember Testa se il file esiste
|
||||
bool exist() const;
|
||||
// @cmember Cerca nel path il nome del file corrente e scrive il path assoluto in path
|
||||
bool search_in_path(TFilename& path) const;
|
||||
// @cmember Ritorna il nome del file
|
||||
const char* name() const;
|
||||
// @cmember Ritorna il nome del direttorio
|
||||
const char* path() const;
|
||||
// @cmember Genera il nome di un file temporaneo
|
||||
const TFilename& temp(const char* prefix = NULL, const char* extension = NULL);
|
||||
// @cmember Genera il nome della directory temporanea
|
||||
const TFilename& tempdir();
|
||||
// @cmember Genera il nome della directory corrente
|
||||
const TFilename& currdir();
|
||||
// @cmember Prepone il nome della dir custom
|
||||
bool custom_path(const char* path_list = NULL);
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TToken_string | Contiene una stringa formata da piu' stringhe
|
||||
// separate da un carattere (di solito il pipe)
|
||||
//
|
||||
// @base public | TString
|
||||
class TToken_string : public TString
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access:(INTERNAL) Private Member
|
||||
|
||||
// @cmember:(INTERNAL) Carattere separatore
|
||||
char _separator;
|
||||
// @cmember:(INTERNAL) Puntatore all'ultimo
|
||||
int _last;
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember Inserisce l'n-esima stringa
|
||||
bool set_item(const char* v, int n);
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore
|
||||
TToken_string(const char* = "", char separator = '|');
|
||||
// @cmember Costruttore
|
||||
TToken_string(int n, char separator = '|');
|
||||
// @cmember Costruttore
|
||||
TToken_string(const TToken_string& s);
|
||||
// @cmember Distruttore
|
||||
~TToken_string();
|
||||
|
||||
// @cmember Crea un duplicato della token string
|
||||
virtual TObject* dup() const;
|
||||
// @cmember Setta il carattere separatore a s
|
||||
void separator(char s);
|
||||
// @cmember Ritorna il carattere separatore
|
||||
char separator() const { return _separator; }
|
||||
|
||||
// @cmember Rimette all'inizio il puntatore
|
||||
void restart()
|
||||
{ _last = empty() ? -1 : 0; }
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const char* s)
|
||||
{ set(s);restart();return *this; }
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const TString& s)
|
||||
{ set(s);restart();return *this; }
|
||||
// @cmember Assegna una stringa
|
||||
const TToken_string& operator =(const TToken_string& s);
|
||||
|
||||
// @cmember Aggiunge una stringa
|
||||
void add(const char* s, int n = -1);
|
||||
// @cmember Aggiunge un carattere
|
||||
void add(char c, int pos = -1);
|
||||
// @cmember Aggiunge un long
|
||||
void add(long n, int pos = -1);
|
||||
// @cmember Aggiunge un intero
|
||||
void add(int n, int pos = -1);
|
||||
// @cmember Toglie la stringa di posizione pos
|
||||
void destroy(int pos);
|
||||
|
||||
// @cmember Ritorna il prossimo token
|
||||
const char* get();
|
||||
// @cmember Ritorna un token
|
||||
const char* get(int n);
|
||||
// @cmember Ritorna un carattere (chiama <mf TToken_string::get>)
|
||||
char get_char(int n = -1);
|
||||
// @cmember Ritorna un intero (chiama <mf TToken_string::get>)
|
||||
int get_int(int n = -1);
|
||||
// @cmember Ritorna un intero esteso (chiama <mf TToken_string::get>)
|
||||
long get_long(int n = -1);
|
||||
|
||||
// TToken_string new age: const methods;
|
||||
// @cmember Ritorna l'ennesimo token
|
||||
bool get(int n, TString& tok) const;
|
||||
// @cmember Ritorna l'ennesimo char
|
||||
bool get(int n, char& tok) const;
|
||||
// @cmember Ritorna l'ennesimo int
|
||||
bool get(int n, int& tok) const;
|
||||
// @cmember Ritorna l'ennesimo long
|
||||
bool get(int n, long& tok) const;
|
||||
|
||||
// @cmember Ritorna la posizione dell'item s
|
||||
int get_pos(const char* s);
|
||||
// @cmember Ritorna la posizione dell'item s
|
||||
int get_pos(long s);
|
||||
// @cmember Ritorna il numero di token presenti
|
||||
int items() const;
|
||||
// @cmember Controlla se tutti i token sono nulli
|
||||
bool empty_items() const;
|
||||
};
|
||||
|
||||
#define FOR_EACH_TOKEN(__tok, __str) \
|
||||
for (const char* __str = __tok.get(0); __str; __str = __tok.get())
|
||||
#define FOR_EACH_STR_TOKEN(__tok, __str) \
|
||||
TString __str;for (int __t=0;__tok.get(__t,__str);__t++)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Mitica token string che sceglie da sola il separatore
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TAuto_token_string : public TToken_string
|
||||
{
|
||||
protected:
|
||||
TAuto_token_string& create(const char* ts);
|
||||
|
||||
public:
|
||||
TAuto_token_string& operator=(const char* ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TString& ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TToken_string& ts) { return create(ts); }
|
||||
TAuto_token_string& operator=(const TAuto_token_string& ts) { return create(ts); }
|
||||
TAuto_token_string(int sz = 50) : TToken_string(sz) { }
|
||||
TAuto_token_string(const char* ts) { create(ts); }
|
||||
virtual ~TAuto_token_string() { }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TParagraph_string
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TParagraph_string | Classe che serve per spezzare le stringhe in paragrafi
|
||||
// lunghi al massimo la lunghezza fissata
|
||||
//
|
||||
// @base public | TToken_string
|
||||
class TParagraph_string : public TToken_string
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access:(INTERNAL) Private Member
|
||||
|
||||
// @cmember:(INTERNAL) Lunghezza massima del paragrafo
|
||||
int _width;
|
||||
|
||||
// @access Protected Member
|
||||
protected:
|
||||
// @cmember Spezza la stringa in paragrafi di lunghezza massima fissata
|
||||
void tokenize();
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Costruttore
|
||||
TParagraph_string(const char* s, int width);
|
||||
|
||||
// @cmember Distruttore
|
||||
virtual ~TParagraph_string() { }
|
||||
|
||||
// @cmember Assegna una stringa
|
||||
const TString& operator =(const char* s);
|
||||
// @cmember Assegna un oggetto stringa
|
||||
const TString& operator =(const TString & s)
|
||||
{ return operator=((const char *) s);}
|
||||
// @cmember Permette di assegnare la lunghezza massima del paragrafo
|
||||
void set_width(int width)
|
||||
{ _width = width; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// DES TString_array
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TString_array | Array di stringhe
|
||||
//
|
||||
// @base public | TArray
|
||||
class TString_array : public TArray
|
||||
// @author:(INTERNAL) Guido
|
||||
{
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Ritorna la stringa n dell'array (se non c'e' ritorna errore)
|
||||
TToken_string& row(int n)
|
||||
{ return (TToken_string&)operator[](n); }
|
||||
// @cmember Ritorna la stringa n dell'array (se non c'e' ritorna errore)
|
||||
const TToken_string& row(int n) const
|
||||
{ return (TToken_string&)operator[](n); }
|
||||
// @cmember Restituisce il puntatore alla stringa n dell'array (NULL se non esiste)
|
||||
TToken_string* rowptr(int n)
|
||||
{ return (TToken_string*)objptr(n); }
|
||||
// @cmember assegnamento di un array
|
||||
const TString_array& operator=(const TString_array& a);
|
||||
// @cmember Aggiunge una Token string all'array (chiama <mf TArray::add>)
|
||||
int add(TToken_string* s, int n = -1)
|
||||
{ return TArray::add(s, n); }
|
||||
// @cmember Aggiunge un oggetto stringa all'array (chiama <mf TArray::add>)
|
||||
int add(const TToken_string& s, int n = -1);
|
||||
// @cmember Aggiunge una stringa all'array (chiama <mf TArray::add>)
|
||||
int add(const char* s, int n = -1);
|
||||
// @cmember Cerca una stringa nell'array
|
||||
int find(const char* s, int from = 0) const;
|
||||
// @cmember Ordina alfabeticamente l'array
|
||||
void sort(bool ascendig = TRUE);
|
||||
|
||||
// @cmember Costruttore
|
||||
TString_array(int size = 8) : TArray(size)
|
||||
{}
|
||||
// @cmember Distruttore
|
||||
virtual ~TString_array()
|
||||
{}
|
||||
};
|
||||
|
||||
TString& user();
|
||||
|
||||
TToken_string& get_tmp_string(int len = -1);
|
||||
|
||||
const TToken_string& empty_string();
|
||||
#define EMPTY_STRING empty_string()
|
||||
|
||||
#define FOR_EACH_ARRAY_ROW(__arr, __r, __riga) \
|
||||
TToken_string* __riga; \
|
||||
for (int __r = (__arr).first(); \
|
||||
__riga = (TToken_string*)(__arr).objptr(__r); \
|
||||
__r = (__arr).succ(__r))
|
||||
|
||||
#define FOR_EACH_ARRAY_ROW_BACK(__arr, __r, __riga) \
|
||||
TToken_string* __riga; \
|
||||
for (int __r = (__arr).last(); \
|
||||
__riga = (TToken_string*)(__arr).objptr(__r); \
|
||||
__r = (__arr).pred(__r))
|
||||
|
||||
const char SLASH =
|
||||
#if XVT_OS == XVT_OS_WIN32
|
||||
'\\';
|
||||
#else
|
||||
'/';
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
454
omnia/utility.cpp
Executable file
454
omnia/utility.cpp
Executable file
@ -0,0 +1,454 @@
|
||||
#include <ctype.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "strings.h"
|
||||
#include "utility.h"
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di copiare un file
|
||||
//
|
||||
// @rdesc Ritorna il risultato dell'operazione:
|
||||
//
|
||||
// @flag TRUE | Se l'operazione e' stata effettuata con successo
|
||||
// @flag FALSE | Se l'operazione non e' stata effettuata con successo
|
||||
bool fcopy(
|
||||
const char* orig, // @parm Nome del file di origine
|
||||
const char* dest, // @parm Nome del file di destinazione
|
||||
bool append) // @parm Controllo per aggiungere il contenuto del
|
||||
// file <p dest> in coda al file <p orig> (default FALSE)
|
||||
|
||||
// @comm Nel caso vengano ravvisati degli errori durante l'operazione vengono
|
||||
// creati dei box di comunicazione che indicano la causa del problema
|
||||
{
|
||||
CHECK(orig && *orig && dest && *dest, "fcopy: Invalid file name");
|
||||
|
||||
const char* const rflag = "rb";
|
||||
const char* wflag = append ? "ab" : "wb";
|
||||
|
||||
// Copia il file su se stesso?
|
||||
if (stricmp(orig, dest) == 0)
|
||||
return TRUE; // Or FALSE?
|
||||
|
||||
FILE* i = fopen(orig, rflag);
|
||||
if (i == NULL)
|
||||
return error_box("Impossibile leggere il file %s\nda copiare in %s", orig, dest);
|
||||
|
||||
FILE* o = fopen(dest, wflag);
|
||||
if (o == NULL)
|
||||
{
|
||||
fclose(i);
|
||||
return error_box("Impossibile creare il file %s\nper copiare il file %s", dest, orig);
|
||||
}
|
||||
|
||||
const int size = 16*1024;
|
||||
TString buffer(size);
|
||||
|
||||
bool ok = TRUE;
|
||||
while (ok)
|
||||
{
|
||||
const word letti = fread(buffer.get_buffer(), 1, size, i);
|
||||
ok = fwrite(buffer.get_buffer(), 1, letti, o) == letti;
|
||||
if (letti < size) break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
error_box("Errore di scrittura: controllare lo spazio libero sul disco!");
|
||||
|
||||
fclose(o);
|
||||
fclose(i);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Controlla l'esistenza di un file
|
||||
//
|
||||
// @rdesc Ritrona i seguenti valori:
|
||||
//
|
||||
// @flag TRUE | Se il file esiste
|
||||
// @flag FALSE | Se il file non esiste
|
||||
bool fexist(
|
||||
const char* file) // @parm Nome del file di cui contrallare l'esistenza
|
||||
{
|
||||
int err = access(file, 0x00);
|
||||
return err == 0;
|
||||
}
|
||||
|
||||
long fsize(const char* name)
|
||||
{
|
||||
long s = 0;
|
||||
if (name && *name)
|
||||
{
|
||||
FILE* f = fopen(name, "r");
|
||||
if (f != NULL)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
s = ftell(f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di creare una directory
|
||||
//
|
||||
// @rdesc Ritorna il risultato dell'operazione
|
||||
//
|
||||
// @flag TRUE | Se l'operazione e' avvenuta con successo
|
||||
// @flag FALSE | Se l'operazione non e' riuscita
|
||||
bool make_dir(
|
||||
const char* dir) // @parm Nome della directory da creare
|
||||
{
|
||||
int res = mkdir(dir);
|
||||
return res == 0;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Ritorna la lista dei file il cui nome corrisponde alla stringa (con caratteri
|
||||
// jolly) passata.
|
||||
//
|
||||
// @rdesc Ritorna il numero di file che soddisfano la condizione passata (numero di elementi
|
||||
// di result)
|
||||
int list_files(
|
||||
const char* filelist, // @parm Stringa contenente la maschera di estrazione
|
||||
TString_array& result) // @parm Array da riempire con la lista dei file
|
||||
|
||||
{
|
||||
/*
|
||||
TFilename dir(filelist);
|
||||
for (int i = dir.len()-1; i >= 0; i--)
|
||||
if (dir[i] == '/' || dir[i] == '\\' || dir[i] == ':') break;
|
||||
|
||||
TFilename mask(dir.mid(i+1));
|
||||
dir.cut(i > 0 ? i+1 : 0);
|
||||
|
||||
xvt_fsys_save_dir();
|
||||
|
||||
if (dir.not_empty())
|
||||
{
|
||||
DIRECTORY directory; xvt_fsys_convert_str_to_dir(dir.get_buffer(), &directory);
|
||||
BOOLEAN ok = xvt_fsys_set_dir(&directory);
|
||||
if (!ok)
|
||||
{
|
||||
error_box("Impossibile entrare in %s", (const char*)dir);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SLIST files = xvt_fsys_list_files("", mask.get_buffer(), FALSE);
|
||||
const int count = xvt_slist_count(files);
|
||||
|
||||
for (SLIST_ELT e = xvt_slist_get_first(files); e; e = xvt_slist_get_next(files, e))
|
||||
{
|
||||
char* f = xvt_slist_get(files, e, NULL);
|
||||
if (dir.not_empty())
|
||||
{
|
||||
mask = dir;
|
||||
mask.add(f);
|
||||
result.add(mask);
|
||||
}
|
||||
else
|
||||
result.add(f);
|
||||
}
|
||||
|
||||
xvt_slist_destroy(files);
|
||||
xvt_fsys_restore_dir();
|
||||
|
||||
return count;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di ritornare una stringa formattata
|
||||
//
|
||||
// @rdesc Ritorna la stringa desiderata
|
||||
char* format(
|
||||
const char* fmt, // @parm Formato che deve essere dato alla stringa
|
||||
...) // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
|
||||
|
||||
// @comm Il funzionamento e' come la <f sprintf> del C, solo che non e' necessario passare la
|
||||
// stringa di destinazione alla funzione.
|
||||
{
|
||||
va_list pars;
|
||||
|
||||
char buf[512];
|
||||
va_start(pars, fmt);
|
||||
const int tot = vsprintf(buf, fmt, pars);
|
||||
va_end(pars);
|
||||
|
||||
CHECK(tot < 512, "Ue'! Ma quanto scrivi?");
|
||||
TString& tmp = get_tmp_string();
|
||||
tmp = buf;
|
||||
|
||||
return tmp.get_buffer();
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Converte la coppia nome-parametro in una stringa che identifica il programma
|
||||
//
|
||||
// @rdesc Ritorna la stringa identificante il programma
|
||||
const char* cmd2name(
|
||||
const char* argv0, // @parm Nome del programma
|
||||
const char* argv1) // @parm Nome del parametro (default "")
|
||||
{
|
||||
TFilename app(argv0);
|
||||
app = app.name();
|
||||
if (argv1 && *argv1)
|
||||
app << ' ' << argv1;
|
||||
else
|
||||
{
|
||||
const char* space = strchr(argv0, ' ');
|
||||
if (space != NULL)
|
||||
app << space;
|
||||
}
|
||||
|
||||
app.lower();
|
||||
|
||||
const int par = app.find(" -");
|
||||
const int num = par > 0 ? atoi(app.mid(par+2))+1 : 1;
|
||||
|
||||
const char c = (num > 9) ? ('a'+num-10) : ('0'+num);
|
||||
app.cut(3);
|
||||
app << c << "00";
|
||||
|
||||
TString& tmp = get_tmp_string();
|
||||
tmp = app;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Conversione in cifre romane
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
HIDDEN const char * cifre_romane = "IVXLCDM@";
|
||||
HIDDEN const int valori_cifre [] = { 1, 5, 10, 50, 100, 500, 1000, -1 };
|
||||
|
||||
HIDDEN int ctoi(char c)
|
||||
{
|
||||
if (c == '\0') return 0;
|
||||
|
||||
c = toupper(c);
|
||||
for (int i = 0; cifre_romane[i]; i++)
|
||||
if (cifre_romane[i] == c) return valori_cifre[i];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Converte una cifra romana in intero normale
|
||||
//
|
||||
// @rdesc Ritorna l'equivalente in numeri della cifra romane
|
||||
int rtoi(
|
||||
const char * val) // @parm Stringa contenente la cifra scritta in numeri romani
|
||||
{
|
||||
if (val == NULL) return 0;
|
||||
|
||||
int tot = 0;
|
||||
int value = ctoi (val[0]);
|
||||
for (int i = 1; value > 0; i++)
|
||||
{
|
||||
const int next_val = ctoi(val[i]);
|
||||
if (value < next_val) tot -= value;
|
||||
else tot += value;
|
||||
value = next_val;
|
||||
}
|
||||
|
||||
return (value == 0) ? tot : -1;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Converte un numero intero nell'equivalente cifra romana
|
||||
//
|
||||
// @rdesc Ritorna una stringa contenente la cifra romana
|
||||
const char* itor(
|
||||
int num) // @parm Intero da convertire in cifra romana
|
||||
{
|
||||
HIDDEN char roman_string[16];
|
||||
int cifra = 0;
|
||||
|
||||
for (int pos = 7; pos--;)
|
||||
{
|
||||
int val = valori_cifre[pos];
|
||||
int quanti = num / val;
|
||||
if (quanti < 4)
|
||||
{
|
||||
if ((pos & 1) && quanti == 1 && (num/valori_cifre[pos-1]) == 9)
|
||||
{
|
||||
roman_string[cifra++] = cifre_romane[pos-1];
|
||||
roman_string[cifra++] = cifre_romane[pos+1];
|
||||
val = valori_cifre[pos-1];
|
||||
quanti = 9;
|
||||
}
|
||||
else for (int i = 0; i < quanti; i++)
|
||||
roman_string[cifra++] = cifre_romane[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
roman_string[cifra++] = cifre_romane[pos];
|
||||
roman_string[cifra++] = cifre_romane[pos+1];
|
||||
}
|
||||
|
||||
num -= quanti * val;
|
||||
}
|
||||
|
||||
roman_string[cifra] = '\0';
|
||||
return roman_string;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di codificare i caratteri di escape
|
||||
//
|
||||
// @rdesc Ritorna il carattere codificato
|
||||
const char* esc(
|
||||
const char* s) // @parm Stringa da codificare
|
||||
{
|
||||
const char *s1 = s == NULL ? "" : s;
|
||||
char* encoded = get_tmp_string().get_buffer(strlen(s));
|
||||
char* s2 = encoded;
|
||||
while (*s1)
|
||||
{
|
||||
if (*s1 == '\\')
|
||||
{
|
||||
s1++;
|
||||
switch (tolower(*s1))
|
||||
{
|
||||
case 'b' : *s2++ = '\b'; break;
|
||||
case 'e' : *s2++ = '\033'; break;
|
||||
case 'f' : *s2++ = '\f'; break;
|
||||
case 'n' : *s2++ = '\n'; break;
|
||||
case 'r' : *s2++ = '\r'; break;
|
||||
case 't' : *s2++ = '\t'; break;
|
||||
default :
|
||||
{
|
||||
if (isdigit(*s1))
|
||||
{
|
||||
int base = 10;
|
||||
if (*s1 == '0')
|
||||
{
|
||||
s1++;
|
||||
if (tolower(*s1) == 'x')
|
||||
{
|
||||
s1++;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
*s2 = 0;
|
||||
char c = tolower(*s1);
|
||||
while (isdigit(c) || (base == 16 && c >= 'a' && c <= 'f'))
|
||||
{
|
||||
*s2 *= base;
|
||||
if (isdigit(*s1)) *s2 += (*s1 - 48);
|
||||
else *s2 += (*s1 - 'a' + 10) & 0x0F;
|
||||
s1++;
|
||||
c = tolower(*s1);
|
||||
}
|
||||
s2++; s1--;
|
||||
}
|
||||
else *s2++ = *s1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (*s1 == '^')
|
||||
{
|
||||
s1++;
|
||||
*s2++ = (tolower(*s1) - 'a' + 1);
|
||||
}
|
||||
else *s2++ = *s1 ;
|
||||
s1++;
|
||||
}
|
||||
*s2 = '\0';
|
||||
return encoded;
|
||||
}
|
||||
|
||||
const char* unesc(
|
||||
const char* s) // @parm Stringa da decodificare
|
||||
{
|
||||
char *decoded = get_tmp_string().get_buffer(strlen(s)*4);
|
||||
char* s2 = decoded;
|
||||
for (const char *s1 = s; *s1; s1++)
|
||||
{
|
||||
const char& c = *s1;
|
||||
if (c >= '\0' && c < ' ')
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '\n':
|
||||
*s2++ = '\\'; *s2++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*s2++ = '\\'; *s2++ = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
*s2++ = '\\'; *s2++ = 't';
|
||||
break;
|
||||
default:
|
||||
*s2++ = '\\'; *s2++ = '0'; *s2++ = 'x';
|
||||
sprintf(s2, "%02x", int(c)); s2 += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
*s2++ = c;
|
||||
}
|
||||
*s2 = '\0';
|
||||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
HIDDEN const char * const encryption_key = "QSECOFR-";
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di criptare una parola
|
||||
//
|
||||
// @rdesc Ritorna la stringa criptata
|
||||
const char * encode(
|
||||
const char * data) // @parm Stringa da criptare
|
||||
|
||||
// @xref <f decode>
|
||||
{
|
||||
char* tmp = get_tmp_string(50).get_buffer();
|
||||
for (int i = 0; data[i]; i++)
|
||||
tmp[i] = data[i] + (i < 8 ? encryption_key[i] : data[i - 8]);
|
||||
tmp[i] = '\0';
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @func Permette di decodificare una stringa criptata
|
||||
//
|
||||
// @rdesc Ritorna la stringa in chiaro
|
||||
const char * decode(
|
||||
const char * data) // @parm Stringa criptata da tradurre
|
||||
|
||||
// @xref <f encode>
|
||||
{
|
||||
char* tmp = get_tmp_string(50).get_buffer();
|
||||
for (int i = 0; data[i]; i++)
|
||||
tmp[i] = data[i] - (i < 8 ? encryption_key[i] : tmp[i - 8]);
|
||||
tmp[i] = '\0';
|
||||
return tmp;
|
||||
}
|
||||
|
37
omnia/utility.h
Executable file
37
omnia/utility.h
Executable file
@ -0,0 +1,37 @@
|
||||
#ifndef __UTILITY_H
|
||||
#define __UTILITY_H
|
||||
|
||||
#ifndef __STDTYPES_H
|
||||
#include "stdtypes.h"
|
||||
#endif
|
||||
|
||||
class TString_array;
|
||||
class TFilename;
|
||||
|
||||
char* format (const char* fmt, ...);
|
||||
const char* cmd2name(const char* argv0, const char* argv1 = "");
|
||||
int rtoi(const char * roman);
|
||||
const char* itor(int i);
|
||||
bool fcopy(const char* orig, const char* dest, bool append=FALSE);
|
||||
bool fexist(const char* file);
|
||||
long fsize(const char* file);
|
||||
|
||||
bool make_dir(const char* file);
|
||||
int list_files(const char* mask, TString_array& result);
|
||||
|
||||
const char* encode(const char* data);
|
||||
const char* decode(const char* data);
|
||||
|
||||
inline bool is_slash(char s) // @parm Carattere da confrontare
|
||||
{ return s == '\\' || s == '/'; }
|
||||
|
||||
inline bool is_not_slash(char s) // @parm Carattere da confrontare
|
||||
{ return s != '\\' && s != '/'; }
|
||||
|
||||
const char* esc(const char* str); // Trasforma le sequenze "\n" nel carattere '\n'
|
||||
const char* unesc(const char* str); // Trasforma i caratteri '\n' nella sequenza "\n"
|
||||
|
||||
#define ODD(x) (x & 1)
|
||||
#define EVEN(x) !(x & 1)
|
||||
|
||||
#endif /* __UTILITY_H */
|
504
omnia/xml.cpp
Executable file
504
omnia/xml.cpp
Executable file
@ -0,0 +1,504 @@
|
||||
#include <ctype.h>
|
||||
#include <fstream.h>
|
||||
#include <stdlib.h>
|
||||
#include <strstrea.h>
|
||||
|
||||
#include "xml.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Utilities
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void Spaces(ostream& outf, int nSpaces)
|
||||
{
|
||||
outf << '\n';
|
||||
if (nSpaces > 0)
|
||||
{
|
||||
TString str(nSpaces, ' ');
|
||||
str.print_on(outf);
|
||||
}
|
||||
}
|
||||
|
||||
int hex2int(const char* str)
|
||||
{
|
||||
int n = 0;
|
||||
for (int i = 0; str[i]; i++)
|
||||
{
|
||||
if (str[i] >= '0' && str[i] <= '9')
|
||||
{
|
||||
n *= 16;
|
||||
n += str[i]-'0';
|
||||
} else
|
||||
if (str[i] >= 'A' && str[i] <= 'F')
|
||||
{
|
||||
n *= 16;
|
||||
n += str[i]-'A'+10;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const TString& EscapeSequence(char cStart, istream& inf)
|
||||
{
|
||||
TString& str = get_tmp_string();
|
||||
|
||||
if (cStart == '&')
|
||||
{
|
||||
for (char c = inf.get(); c != ';'; c = inf.get())
|
||||
str << c;
|
||||
if (str == "lt") return str ="<";
|
||||
if (str == "gt") return str =">";
|
||||
if (str == "nbsp") return str =" ";
|
||||
if (str == "Agrave") return str ="À";
|
||||
if (str == "Egrave") return str ="È";
|
||||
if (str == "Eacuto") return str ="É";
|
||||
if (str == "Igrave") return str ="Ì";
|
||||
if (str == "Ograve") return str ="Ò";
|
||||
if (str == "Ugrave") return str ="Ù";
|
||||
if (str == "agrave") return str ="à";
|
||||
if (str == "egrave") return str ="è";
|
||||
if (str == "eacuto") return str ="é";
|
||||
if (str == "igrave") return str ="ì";
|
||||
if (str == "ograve") return str ="ò";
|
||||
if (str == "ugrave") return str ="ù";
|
||||
|
||||
const char tmp[2] = { cStart, '\0' };
|
||||
str.insert(tmp);
|
||||
} else
|
||||
if (cStart == '%')
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
str << inf.get();
|
||||
char c = hex2int(str);
|
||||
str = c;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void WriteXmlString(ostream& outf, const char* str)
|
||||
{
|
||||
for (int i = 0; str[i]; i++)
|
||||
{
|
||||
char c = str[i];
|
||||
if (c < 0 || strchr("<>/&", c) != NULL)
|
||||
{
|
||||
unsigned int n = (unsigned char)c;
|
||||
TString8 tmp; tmp.format("%%%02X", n);
|
||||
tmp.print_on(outf);
|
||||
}
|
||||
else
|
||||
outf << c;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TXmlAttr
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TXmlAttr : public TString
|
||||
{
|
||||
public:
|
||||
void Write(ostream& outf) const;
|
||||
TXmlAttr(const char* str) : TString(str) { }
|
||||
};
|
||||
|
||||
void TXmlAttr::Write(ostream& outf) const
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
outf << '"' << '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isdigit((*this)[0]))
|
||||
{
|
||||
print_on(outf);
|
||||
}
|
||||
else
|
||||
{
|
||||
outf << '"';
|
||||
print_on(outf);
|
||||
outf << '"';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TXmlItem
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TXmlItem& TXmlItem::SetAttr(const char* strAttr, const char* strVal)
|
||||
{
|
||||
if (m_Attributes == NULL)
|
||||
m_Attributes = new TAssoc_array;
|
||||
m_Attributes->remove(strAttr);
|
||||
m_Attributes->add(strAttr, new TXmlAttr(strVal));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TString& TXmlItem::GetAttr(const char* strAttr) const
|
||||
{
|
||||
if (m_Attributes != NULL)
|
||||
{
|
||||
const TXmlAttr* str = (const TXmlAttr*)m_Attributes->objptr(strAttr);
|
||||
if (str != NULL)
|
||||
return *str;
|
||||
}
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
int TXmlItem::GetIntAttr(const char* strAttr) const
|
||||
{
|
||||
return atoi(GetAttr(strAttr));
|
||||
}
|
||||
|
||||
int TXmlItem::GetChildren() const
|
||||
{
|
||||
int n = 0;
|
||||
if (m_Children != NULL)
|
||||
n = m_Children->items();
|
||||
return n;
|
||||
}
|
||||
|
||||
TXmlItem* TXmlItem::GetChild(size_t n) const
|
||||
{
|
||||
TXmlItem* i = NULL;
|
||||
if (m_Children != NULL)
|
||||
i = (TXmlItem*)m_Children->objptr(n);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
bool TXmlItem::GetWord(istream& inf, TString& str) const
|
||||
{
|
||||
str.cut(0);
|
||||
|
||||
int cFirstChar = EOF;
|
||||
while (!inf.eof())
|
||||
{
|
||||
cFirstChar = inf.get();
|
||||
if (cFirstChar <= 0 || cFirstChar > ' ')
|
||||
break;
|
||||
}
|
||||
if (cFirstChar == EOF)
|
||||
return false;
|
||||
|
||||
const bool bIsString = cFirstChar == '"' || cFirstChar == '\'';
|
||||
if (!bIsString)
|
||||
{
|
||||
str << char(cFirstChar);
|
||||
if (strchr("<=/>", cFirstChar) != NULL)
|
||||
return true; // Simboli terminali
|
||||
}
|
||||
|
||||
while (!inf.eof())
|
||||
{
|
||||
int c = inf.get();
|
||||
if (bIsString)
|
||||
{
|
||||
if (c == cFirstChar)
|
||||
break;
|
||||
if (c >= '\0' && c <= ' ')
|
||||
c = ' ';
|
||||
str << char(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c >= '\0' && c <= ' ')
|
||||
break;
|
||||
if (strchr("<=/>", c))
|
||||
{
|
||||
inf.putback(char(c));
|
||||
break;
|
||||
}
|
||||
str << char(c);
|
||||
}
|
||||
}
|
||||
return str.not_empty();
|
||||
}
|
||||
|
||||
int TXmlItem::ReadTag(istream& inf)
|
||||
{
|
||||
TString str;
|
||||
if (!GetWord(inf, str))
|
||||
return -1;
|
||||
|
||||
if (str[0] != '<') // No tag = sequence of words
|
||||
{
|
||||
bool bFirstChar = true;
|
||||
while (!inf.eof())
|
||||
{
|
||||
char c = inf.get();
|
||||
if (c == '<')
|
||||
{
|
||||
inf.putback(c);
|
||||
break;
|
||||
}
|
||||
if (bFirstChar)
|
||||
{
|
||||
str << ' ';
|
||||
bFirstChar = false;
|
||||
}
|
||||
if (c == '&' || c == '#' || c == '%')
|
||||
str << EscapeSequence(c, inf);
|
||||
else
|
||||
str << c;
|
||||
}
|
||||
SetTag("");
|
||||
SetText(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TString name, tmp;
|
||||
|
||||
bool bChildrenFollow = true;
|
||||
GetWord(inf, m_strTag);
|
||||
if (m_strTag == "/") // Sto leggendo un tag di chiusura del tipo </SOAP-ENV>
|
||||
{
|
||||
bChildrenFollow = false;
|
||||
GetWord(inf, tmp);
|
||||
m_strTag << tmp;
|
||||
}
|
||||
|
||||
while (GetWord(inf, name))
|
||||
{
|
||||
if (name[0] == '>')
|
||||
return bChildrenFollow ? +1 : 0;
|
||||
|
||||
if (name[0] == '/')
|
||||
{
|
||||
bChildrenFollow = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ho letto un nome di attributo
|
||||
GetWord(inf, tmp);
|
||||
if (tmp.empty() || tmp[0] != '=')
|
||||
break;
|
||||
// Leggo il valore dell'attributo
|
||||
GetWord(inf, tmp);
|
||||
SetAttr(name, tmp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
TXmlItem& TXmlItem::AddChild(TXmlItem* pItem)
|
||||
{
|
||||
if (m_Children == NULL)
|
||||
m_Children = new TArray;
|
||||
if (pItem == NULL)
|
||||
pItem = new TXmlItem;
|
||||
m_Children->add(pItem);
|
||||
return *pItem;
|
||||
}
|
||||
|
||||
TXmlItem& TXmlItem::AddChild(const char* strTagName)
|
||||
{
|
||||
TXmlItem& i = AddChild((TXmlItem*)NULL);
|
||||
i.SetTag(strTagName);
|
||||
return i;
|
||||
}
|
||||
|
||||
TXmlItem& TXmlItem::AddSoapString(const char* name, const char* value, bool typized)
|
||||
{
|
||||
TXmlItem& xmlVar = AddChild(name);
|
||||
if (typized)
|
||||
xmlVar.SetAttr("xsi:type", "xsd:string");
|
||||
xmlVar.AddChild("").SetText(value);
|
||||
return xmlVar;
|
||||
}
|
||||
|
||||
TXmlItem& TXmlItem::AddSoapInt(const char* name, int value, bool typized)
|
||||
{
|
||||
TXmlItem& xmlVar = AddChild(name);
|
||||
if (typized)
|
||||
xmlVar.SetAttr("xsi:type", "xsd:int");
|
||||
TString16 str; str << value;
|
||||
xmlVar.AddChild("").SetText(str);
|
||||
return xmlVar;
|
||||
}
|
||||
|
||||
void TXmlItem::RemoveLastChild()
|
||||
{
|
||||
if (m_Children != NULL)
|
||||
m_Children->destroy(m_Children->last());
|
||||
}
|
||||
|
||||
bool TXmlItem::Read(istream& inf)
|
||||
{
|
||||
Destroy();
|
||||
const int res = ReadTag(inf);
|
||||
if (res > 0) // There are children ahead
|
||||
{
|
||||
while (!inf.eof())
|
||||
{
|
||||
TXmlItem& item = AddChild("/"); // Add dummy child
|
||||
if (item.Read(inf))
|
||||
{
|
||||
if (item.m_strTag[0] == '/')
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
RemoveLastChild(); // Remove dummy child
|
||||
}
|
||||
return res >= 0;
|
||||
}
|
||||
|
||||
TXmlItem* TXmlItem::ForEach(XmlItemCallback cb, long jolly)
|
||||
{
|
||||
if (cb(*this, jolly))
|
||||
return this;
|
||||
|
||||
for (int n = 0; ; n++)
|
||||
{
|
||||
TXmlItem* c = GetChild(n);
|
||||
if (c == NULL)
|
||||
break;
|
||||
c = c->ForEach(cb, jolly);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool GetEnclosedTextCallback(TXmlItem& item, long jolly)
|
||||
{
|
||||
TString* strText = (TString*)jolly;
|
||||
const TString& str = item.GetText();
|
||||
if (!str.empty())
|
||||
{
|
||||
if (!strText->empty())
|
||||
*strText << " ";
|
||||
*strText << str;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TXmlItem::GetEnclosedText(TString& text) const
|
||||
{
|
||||
text.cut(0);
|
||||
((TXmlItem*)this)->ForEach(GetEnclosedTextCallback, (long)&text);
|
||||
return text.not_empty();
|
||||
}
|
||||
|
||||
TXmlItem& TXmlItem::AddEnclosedText(const char* str)
|
||||
{
|
||||
TXmlItem* item = FindFirst("");
|
||||
if (item == NULL)
|
||||
item = &AddChild("");
|
||||
if (item->m_strText == NULL)
|
||||
item->SetText(str);
|
||||
else
|
||||
*item->m_strText << str;
|
||||
return *item;
|
||||
}
|
||||
|
||||
TXmlItem& operator<<(TXmlItem& item, const char* str)
|
||||
{
|
||||
item.AddEnclosedText(str);
|
||||
return item;
|
||||
}
|
||||
|
||||
void TXmlItem::Write(ostream& outf, int tab) const
|
||||
{
|
||||
if (!GetTag().empty())
|
||||
{
|
||||
Spaces(outf, tab);
|
||||
outf << '<';
|
||||
GetTag().print_on(outf);
|
||||
if (m_Attributes != NULL)
|
||||
{
|
||||
TAssoc_array& ass = *m_Attributes;
|
||||
FOR_EACH_ASSOC_OBJECT(ass, h, k, a)
|
||||
{
|
||||
outf << ' ';
|
||||
outf.write(k, strlen(k));
|
||||
outf << '=';
|
||||
const TXmlAttr* attr = (const TXmlAttr*)a;
|
||||
attr->Write(outf);
|
||||
}
|
||||
}
|
||||
if (GetChildren() > 0)
|
||||
{
|
||||
outf << '>';
|
||||
for (int n = 0; ; n++)
|
||||
{
|
||||
TXmlItem* c = GetChild(n);
|
||||
if (c == NULL)
|
||||
break;
|
||||
c->Write(outf, tab+1);
|
||||
}
|
||||
if (GetChild(n-1)->GetText().empty())
|
||||
Spaces(outf, tab);
|
||||
outf << '<' << '/';
|
||||
GetTag().print_on(outf);
|
||||
outf << '>';
|
||||
}
|
||||
else
|
||||
outf << ' ' << '/' << '>';
|
||||
}
|
||||
else
|
||||
GetText().print_on(outf);
|
||||
}
|
||||
|
||||
void TXmlItem::AsString(TString& str) const
|
||||
{
|
||||
for (size_t nSize = 8192; ; nSize *= 2)
|
||||
{
|
||||
char* buf = str.get_buffer(nSize);
|
||||
memset(buf, 0, nSize);
|
||||
ostrstream outf(buf, nSize);
|
||||
Write(outf, 0);
|
||||
if (buf[nSize-1] == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TXmlItem::Save(const char* strFilename) const
|
||||
{
|
||||
ofstream outf(strFilename);
|
||||
Write(outf, 0);
|
||||
}
|
||||
|
||||
static bool FindFirstCallback(TXmlItem& item, long jolly)
|
||||
{
|
||||
const char* strTag = (const char*)jolly;
|
||||
return item.GetTag() == strTag;
|
||||
}
|
||||
|
||||
void TXmlItem::Destroy()
|
||||
{
|
||||
m_strTag.cut(0);
|
||||
if (m_strText)
|
||||
m_strText->cut(0);
|
||||
if (m_Attributes)
|
||||
m_Attributes->destroy();
|
||||
if (m_Children)
|
||||
m_Children->destroy();
|
||||
}
|
||||
|
||||
TXmlItem* TXmlItem::FindFirst(const char* strTag) const
|
||||
{
|
||||
return ((TXmlItem*)this)->ForEach(FindFirstCallback, (long)strTag);
|
||||
}
|
||||
|
||||
TXmlItem::TXmlItem()
|
||||
: m_strTag(7), m_Attributes(NULL), m_Children(NULL), m_strText(NULL)
|
||||
{ }
|
||||
|
||||
TXmlItem::~TXmlItem()
|
||||
{
|
||||
if (m_strText)
|
||||
delete m_strText;
|
||||
if (m_Attributes)
|
||||
delete m_Attributes;
|
||||
if (m_Children)
|
||||
delete m_Children;
|
||||
}
|
||||
|
86
omnia/xml.h
Executable file
86
omnia/xml.h
Executable file
@ -0,0 +1,86 @@
|
||||
#ifndef __XML_H
|
||||
#define __XML_H
|
||||
|
||||
#ifndef __ASSOC_H
|
||||
#include "assoc.h"
|
||||
#endif
|
||||
|
||||
class TXmlItem;
|
||||
|
||||
typedef bool (*XmlItemCallback)(TXmlItem& item, long jolly);
|
||||
|
||||
class TXmlItem : public TObject
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(TXmlItem);
|
||||
|
||||
TString m_strTag;
|
||||
TString* m_strText;
|
||||
TAssoc_array* m_Attributes;
|
||||
TArray* m_Children;
|
||||
|
||||
protected:
|
||||
bool GetWord(istream& input, TString& str) const;
|
||||
int ReadTag(istream& input);
|
||||
|
||||
TXmlItem& AddChild(TXmlItem* pItem);
|
||||
|
||||
public:
|
||||
const TString& GetTag() const { return m_strTag; }
|
||||
void SetTag(const char* strTag) { m_strTag = strTag; }
|
||||
|
||||
const TString& GetText() const
|
||||
{
|
||||
if (m_strText != NULL)
|
||||
return *m_strText;
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
void SetText(const char* str)
|
||||
{
|
||||
if (m_strText == NULL)
|
||||
m_strText = new TString(str);
|
||||
else
|
||||
*m_strText = str;
|
||||
}
|
||||
|
||||
TXmlItem& AddEnclosedText(const char* str);
|
||||
bool GetEnclosedText(TString& str) const;
|
||||
|
||||
TXmlItem& SetAttr(const char* strAttr, const char* strVal);
|
||||
const TString& GetAttr(const char* strAttr) const;
|
||||
int GetIntAttr(const char* strAttr) const;
|
||||
|
||||
TXmlItem& AddChild(const char* strTag);
|
||||
TXmlItem& AddSoapString(const char* name, const char* value, bool typized = false);
|
||||
TXmlItem& AddSoapInt(const char* name, int value, bool typized = false);
|
||||
|
||||
int GetChildren() const;
|
||||
TXmlItem* GetChild(size_t n) const;
|
||||
void RemoveLastChild();
|
||||
|
||||
void Destroy();
|
||||
bool Read(istream& input);
|
||||
void Write(ostream& output, int nTab) const;
|
||||
void AsString(TString& str) const;
|
||||
|
||||
void Save(const char* strFilename) const;
|
||||
|
||||
TXmlItem* ForEach(XmlItemCallback cb, long jolly = 0);
|
||||
TXmlItem* FindFirst(const char* strTag) const;
|
||||
|
||||
TXmlItem();
|
||||
~TXmlItem();
|
||||
};
|
||||
|
||||
TXmlItem& operator<<(TXmlItem& item, const char* str);
|
||||
|
||||
//ostream& operator<<(ostream& outf, const char* str);
|
||||
//ostream& operator<<(ostream& outf, TString str);
|
||||
//istream& operator>>(istream& inf, TString& str);
|
||||
void Spaces(ostream& outf, int nSpaces);
|
||||
void WriteXmlString(ostream& outf, const char* str);
|
||||
int hex2int(const char* str);
|
||||
|
||||
#define endl "\r\n";
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user