diff --git a/src/include01/array.cpp b/src/include01/array.cpp index 9d09e05e9..ccc4ba4e8 100644 --- a/src/include01/array.cpp +++ b/src/include01/array.cpp @@ -148,15 +148,15 @@ void TArray::resize( // @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 +// @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 per compattare gli elementi dell'array (default FALSE) + bool pack) // @parm Se true richiama la funzione 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 nullptr. - // Nel caso il parametro pack sia TRUE permette di rendere contigui + // Nel caso il parametro pack sia true permette di rendere contigui // tutti gli elementi diversi da nullptr tramite la chiamata alla funzione // . @@ -278,8 +278,8 @@ void TArray::print_on( // @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 +// @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 @@ -420,7 +420,7 @@ int TArray::insert(const TObject& object, int index, bool force) TObject* TArray::remove( int index, // @parm Indica la posizione dell'elemento da eliminare bool dopack) // @parm Indica se si vuole richiamare la funzione - // (default FALSE) per spostare gli elementi successivi dell'array + // (default false) per spostare gli elementi successivi dell'array { CHECKD(index >= 0, "Can't remove array item ", index); @@ -449,8 +449,8 @@ TObject* TArray::remove_item(bool pack ) void TArray::swap(int i1, int i2) { - TObject* o1 = remove(i1, FALSE); - TObject* o2 = remove(i2, FALSE); + TObject* o1 = remove(i1, false); + TObject* o2 = remove(i2, false); if (o1) add(o1, i2); if (o2) add(o2, i1); } @@ -855,15 +855,15 @@ int TFiles_array::find(const char* s, int from) const // @parm Posizione dalla q // @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 +// @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 per compattare gli elementi dell'array (default FALSE) + bool pack) // @parm Se true richiama la funzione 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 nullptr. - // Nel caso il parametro pack sia TRUE permette di rendere contigui + // Nel caso il parametro pack sia true permette di rendere contigui // tutti gli elementi diversi da nullptr tramite la chiamata alla funzione // . @@ -1028,7 +1028,7 @@ void TBit_array::resize( bool TBit_array::operator[] (long n) const { const word i = index(n); - if (i >= _size) return FALSE; + if (i >= _size) return false; return (_bit[i] & mask(n)) != 0; } @@ -1167,8 +1167,8 @@ bool TBit_array::some_one() const // // @rdesc Ritorna uno dei seguenti parametri: // -// @flag TRUE | Se l'array contiene degli elementi -// @flag FALSE | Se l'array e' vuoto +// @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 @@ -1361,7 +1361,7 @@ TObject* TMatrix::remove( int r, // @parm Riga in cui aggiungere l'oggetto int c, // @parm Colonna in cui aggiungere l'oggetto bool dopack) // @parm Indica se si vuole richiamare la funzione - // (default FALSE) per spostare gli elementi successivi dell'array + // (default false) per spostare gli elementi successivi dell'array { TArray & rw = operator[](r); diff --git a/src/include01/array.h b/src/include01/array.h index 282a07504..e7bac4f4a 100644 --- a/src/include01/array.h +++ b/src/include01/array.h @@ -5,6 +5,10 @@ #include #endif +#ifndef __RECTYPES_H +#include +#endif + #ifndef NULL #define NULL 0L #endif @@ -95,12 +99,11 @@ public: // @class TFilepos | oggetto per incapsulare una posizione su file (streampos) // @base public | TObject -class TFilepos : public TObject +class TFilepos : public TSortable // @author:(INTERNAL) Alex { // @access:(INTERNAL) Private Member - // @cmember:(INTERNAL) posizione streampos _pos; @@ -109,13 +112,16 @@ protected: // @cmember Permette di stampare l'oggetto virtual void print_on(ostream& out) const { out << _pos; } - // @cmember Duplica il numero reale (vedi classe ) - virtual TObject* dup() const { return new TFilepos(*this); } + TFilepos & copy(const TFilepos & p) { _pos = p._pos; return *this; } // @access Public Member public: - const streampos & pos() const { return _pos ; } - TFilepos& operator =(const TFilepos& p) { _pos = p._pos; return *this; } + virtual int compare(const TSortable& s) const { return (int)(_pos - ((const TFilepos&)s)._pos); } + // @cmember Duplica la posizione (vedi classe ) + virtual TObject* dup() const { return new TFilepos(*this); } + streampos val() const { return _pos ; } + operator streampos() const { return val(); } + TFilepos& operator =(const TFilepos& p) { return copy(p); } // @cmember Aggiunge ad un reale il valore passato (passato per indirizzo) // @cmember Costruttore TFilepos() : _pos(0L) {} @@ -131,6 +137,29 @@ public: virtual ~TFilepos() {} }; +class TORecnotype :public TSortable // @author:(INTERNAL) Bonazzi + // TORecnotype per utilizzarlo negli array +{ + TRecnotype _r; + +protected: + // @cmember Permette di stampare l'oggetto + virtual void print_on(ostream& out) const { out << _r; } + + TORecnotype & copy(const TORecnotype & r) { _r = r._r; return *this; } + +public: + virtual int compare(const TSortable& s) const override { return int(_r - ((TORecnotype&)s)._r); } + virtual TObject* dup() const { return new TORecnotype(*this); } + TRecnotype val() const { return _r; } + operator long() const { return val(); } + TORecnotype & operator ==(TORecnotype& r) { return copy(r); } + TORecnotype & operator ==(TRecnotype r) { _r = r; return *this; } + + TORecnotype(TRecnotype r = 0L) : _r(r) { } + ~TORecnotype() = default; +}; + // @doc EXTERNAL // @class TContainer | Generico contenitore ad accesso casuale (con indice) @@ -241,8 +270,6 @@ public: virtual bool is_kind_of(word cid) 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 @@ -272,7 +299,9 @@ public: int succ(int i) const; // @cmember Ritorna l'indice del primo oggetto che precede l'i-esimo int pred(int i) const; - + + // @cmember Controlla se si tratta di un oggetto valido + bool ok() const; // @cmember Ritorna l'oggetto nella posizione index TObject& operator[] (int index) const ; // @cmember Ritorna l'oggetto nella posizione index @@ -471,6 +500,7 @@ public: virtual ~TFiles_array() {} }; + class TPointer_array : public TArray { protected: diff --git a/src/include01/config.cpp b/src/include01/config.cpp index 11db56108..f683910c4 100644 --- a/src/include01/config.cpp +++ b/src/include01/config.cpp @@ -603,7 +603,7 @@ bool TConfig::set(const char* var, long value, const char* section, bool force, int index) { TString16 t; t << value; - return set(var,t,section,force,index); + return set(var, t, section, force, index); } bool TConfig::set_color(const char* var, COLOR col, const char* section, @@ -940,6 +940,13 @@ void ini_del_memo(const char* file, const char* para, const char* name) ini_remove(file, para, name, i); } +void ini_remove_paragraph(const char* file, const char* para) +{ + TConfig cfg(file, para); + + cfg.remove_all(); +} + int ini_get_rows_memo(const char* file, const char* para, const char* name) { int idx = 0; @@ -1128,7 +1135,6 @@ bool ini_remove_array(int cfg, const char* para, const char* name) return ini_remove_array(filename, para, name); } - const TString& ini_get_memo(int cfg, const char* para, const char* name) { DECLARE_FILENAME(cfg); @@ -1177,6 +1183,12 @@ void ini_del_memo(int cfg, const char* para, const char* name) ini_del_memo(filename, para, name); } +void ini_remove_paragraph(int cfg, const char* para) +{ + DECLARE_FILENAME(cfg); + ini_remove_paragraph(filename, para); +} + const TString& get_oem_info(const char* varname, const char* def) { TString& tmp = get_tmp_string(50); diff --git a/src/include01/config.h b/src/include01/config.h index 5e83dfaed..9b86f293f 100644 --- a/src/include01/config.h +++ b/src/include01/config.h @@ -221,6 +221,7 @@ void ini_set_memo (const char* file, const char* paragraph, const char* na int ini_get_rows_memo(const char* file, const char* paragraph, const char* name); const TString& ini_get_line_memo(const char* file, const char* paragraph, const char* name, int idx); void ini_del_memo (const char* file, const char* para, const char* name); +void ini_remove_paragraph(const char* file, const char* para); // High level utilities bool ini_get_bool (int cfg, const char* para, const char* name, bool defval = false, int idx = -1); @@ -240,6 +241,7 @@ bool ini_remove_array(int cfg, const char* para, const char* name); const TString& ini_get_memo (int cfg, const char* para, const char* name); void ini_set_memo (int cfg, const char* para, const char* name, const char* msg); void ini_del_memo (int cfg, const char* para, const char* name); +void ini_remove_paragraph(int cfg, const char* para); const TString& get_oem_info(const char* varname, const char* defval = ""); // ini_get_string(CONFIG_OEM, "OEM_?", varname, defval); bool is_aga_version(bool power_user_only = false); diff --git a/src/include01/expr.cpp b/src/include01/expr.cpp index 4035eafdb..225a6b5ee 100644 --- a/src/include01/expr.cpp +++ b/src/include01/expr.cpp @@ -907,6 +907,9 @@ void TExpression::eval() evalstack.push(perc); } break; + case _abs: + evalstack.peek_real() = abs(evalstack.peek_real()); + break; default: NFCHECK("operazione non valida %d", (int) instr.getsym()); break; @@ -926,22 +929,22 @@ HIDDEN char _tok[255]; TCodesym TExpression::tok2fun(const char* tok) const { - const int MAX_TOK = 35; - HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "BETWEEN","BOOL", "CEIL", "CF_CHECK", + const int MAX_TOK = 36; + HIDDEN const char* fnstr[MAX_TOK] = { "ABS", "ANSI", "BETWEEN","BOOL", "CEIL", "CF_CHECK", "COS", "EXP", "EXP10", "IF", "LEFT", "LEN", "LOG", "LOG10", "MAX", "MID", "MIN", "NUM", "PERC", "PI_CHECK","POW", "RIGHT", "ROUND", "SCON2PERC", "SCORP","SIN", "SQR", "SQRT", "STR", "SUBSTR", "TAN", "TRIM", "TRUNC", - "UPPER", "YEAR", "ZEROFILL" }; + "UPPER", "YEAR", "ZEROFILL", }; - HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _between, _bool, _ceil, _cfcheck, + HIDDEN TCodesym fntok[MAX_TOK] = { _abs, _ansi, _between, _bool, _ceil, _cfcheck, _cos, _exp, _exp10, _if, _left, _len, _log, _log10, _max, _mid, _min, _num, _perc, _picheck, _pow, _right, _round, _scon2perc,_scorp, _sin, _sqr, _sqrt, _str, _substr, _tan, _trim, - _trunc, _upper, _year, _zerofill }; + _trunc, _upper, _year, _zerofill}; int f = 0, l = MAX_TOK-1, i = MAX_TOK/2; for (;;) @@ -1260,6 +1263,7 @@ TCodesym TExpression::__factor(TCodesym startsym) case _year: case _scon2perc: case _bool: + case _abs: sym = __function(1); _code.add(startsym); break; diff --git a/src/include01/expr.h b/src/include01/expr.h index f4f546462..fb16c049c 100644 --- a/src/include01/expr.h +++ b/src/include01/expr.h @@ -80,6 +80,7 @@ enum TCodesym { _zerofill, // @emem riepie di zeri l'inizio di una stringa _scon2perc, // @emem converte una espressione in percentuale di sconto _bool, // @emem converte una espressione in booleano (0 o 1) + _abs // @emem valore assoluto }; // @doc INTERNAL diff --git a/src/include01/golem.cpp b/src/include01/golem.cpp index b5a083363..0cf0bd87c 100644 --- a/src/include01/golem.cpp +++ b/src/include01/golem.cpp @@ -84,7 +84,8 @@ bool html2pdf(const char* url, const char * dest) TExternal_app app(cmd); - return app.run(false, false) == 0; + app.run(false, false); + return true; } bool xml2html(const char* xml, const char * style, bool add, const char * dest) @@ -657,7 +658,7 @@ bool TGolem_field::on_key(KEY key) do_message(0); } else - if (key == K_ESC) + if (key == K_ESC && _tool) update_tool(); } else diff --git a/src/include01/isam.cpp b/src/include01/isam.cpp index 83ec04b78..90f220b11 100644 --- a/src/include01/isam.cpp +++ b/src/include01/isam.cpp @@ -450,21 +450,21 @@ HIDDEN void browse_null(char *start, int nc) // Traduce l'espressione chiave di CodeBase -HIDDEN int __build_key(const RecDes& recd, int numkey, const RecType recin, char *key, bool build_x_cb) +HIDDEN int __build_key(const RecDes& recd, int numkey, const RecType recin, char *key, bool build_x_cb, bool token = false) /* *recd; descrittore record */ /* numkey; numero chiave */ /* recin; buffer contenente il record */ /* *key; valore della chiave */ /* build_x_cb flag di costruzione per codebase */ { - CHECKD(numkey > 0, "Can't build key ", numkey); - - const char null_char = -1; + CHECKD(numkey > 0, "Can't build key ", numkey); - key[0] = '\0'; + const char null_char = -1; + + key[0] = '\0'; if (numkey-- <= recd.NKeys) { - int l = 0; + int l = 0; for (int i = 0; i < recd.Ky[numkey].NkFields; i++) { @@ -476,71 +476,71 @@ HIDDEN int __build_key(const RecDes& recd, int numkey, const RecType recin, cha int off, len; if (kd.FromCh[i] == 255) - { + { off = rf.RecOff; len = rf.Len; - } + } else { off = rf.RecOff + kd.FromCh[i]; len = kd.ToCh[i] - kd.FromCh[i] + 1; } - if ((l + len) > 255) - { - key[0] = '\0'; - return(_iskeylenerr); - } + if ((l + len) > 255) + { + key[0] = '\0'; + return(_iskeylenerr); + } if (f == _boolfld) { - const bool on = *(recin + off) > ' ' && strchr("STXY", *(recin + off)) != NULL; - key[l] = on ? 'T' : 'F'; + const bool on = *(recin + off) > ' ' && strchr("STXY", *(recin + off)) != NULL; + key[l] = on ? 'T' : 'F'; } else - strncpy((key + l), (recin + off), len); + strncpy((key + l), (recin + off), len); - if (recin[off] == '\0') - { - memset(key + l, ' ', len); + if (recin[off] == '\0') + { + memset(key + l, ' ', len); if ((f == _intfld) || (f == _longfld) || (f == _wordfld) || - (f == _intzerofld) || (f == _longzerofld)) - key[l + len - 1] = build_x_cb ? '0' : null_char; - } - else - if ((f == _intfld) || (f == _longfld) || (f == _wordfld) || (f == _intzerofld) || (f == _longzerofld)) + (f == _intzerofld) || (f == _longzerofld)) + key[l + len - 1] = build_x_cb ? '0' : null_char; + } + else + if ((f == _intfld) || (f == _longfld) || (f == _wordfld) || (f == _intzerofld) || (f == _longzerofld)) { - int w = l, j = l + len; - while (w < j && key[w] == ' ') w++; - while (w < j && key[w] == '0') key[w++] = ' '; - if (w == j) key[w-1] = build_x_cb ? '0' : null_char; - } - if (upp) - for (int i = l+len-1; i >= l; i--) - key[i] = toupper(key[i]); + int w = l, j = l + len; + while (w < j && key[w] == ' ') w++; + while (w < j && key[w] == '0') key[w++] = ' '; + if (w == j) key[w - 1] = build_x_cb ? '0' : null_char; + } + if (upp) + for (int i = l + len - 1; i >= l; i--) + key[i] = toupper(key[i]); - l += len; - } - - // rtrim - if (build_x_cb) - { - for (l--; l>=0 && key[l] == ' '; l--); - key[l + 1] = '\0'; - } - else - { - for (l--; l>=0 && (key[l] == ' ' || key[l] == null_char); l--); - key[l + 1] = '\0'; - for (;l >= 0; l--) - if (key[l] == null_char) - key[l] = '0'; - } - - return(NOERR); - } - return(_ispatherr); + l += len; + if (!build_x_cb && token && i < recd.Ky[numkey].NkFields - 1) + key[l++] = '¶'; + } + + // rtrim + if (build_x_cb) + { + for (l--; l >= 0 && key[l] == ' '; l--); + key[l + 1] = '\0'; + } + else + { + for (l--; l >= 0 && (key[l] == ' ' || key[l] == null_char); l--); + key[l + 1] = '\0'; + for (; l >= 0; l--) + if (key[l] == null_char) + key[l] = '0'; + } + return(NOERR); + } + return(_ispatherr); } - HIDDEN int cisread(int fhnd, int knum, TRectype& record, int mode, TRecnotype& curr_recno) { CHECKD(fhnd >= 0, "Can't use codebase handle ", fhnd); @@ -3635,6 +3635,18 @@ const char* TRectype::build_key(int num) const return tmp; } +const TToken_string & TRectype::build_token_key(int num) const +{ + TString256 str; + TToken_string& tmp = get_tmp_string(256); + + __build_key(rec_des(), num, string(), str.get_buffer(), false, true); + str.replace("¶", "|"); + tmp = str; + return tmp; +} + + const char* TRectype::last_key_field(int key) const { const KeyDes& kd = rec_des().Ky[key]; diff --git a/src/include01/isam.h b/src/include01/isam.h index f1f112daf..492dc5099 100644 --- a/src/include01/isam.h +++ b/src/include01/isam.h @@ -195,6 +195,8 @@ public: // @cmember Ritorna il valaore della chiave

-esima di ordinamento sul file const char* build_key(int key = 1) const; + // @cmember Ritorna il valaore della chiave

-esima di ordinamento sul file come Token_string + const TToken_string & TRectype::build_token_key(int num) const; // @cmember Confronta le chiavi di due record int compare_key(const TRectype& rec, int key = 1, int skip_last = 0) const; // @cmember Ritorna true se le chiavi di due record sono uguali (vedi ) diff --git a/src/include01/isamrpc.cpp b/src/include01/isamrpc.cpp index a79a55db2..470fad45d 100644 --- a/src/include01/isamrpc.cpp +++ b/src/include01/isamrpc.cpp @@ -2,22 +2,22 @@ #include #include #include +#include -static TSocketClient* _client = NULL; - -static CONNID _connection = 0; +HIDDEN TSocketClient* _client = nullptr; +HIDDEN CONNID _connection = 0; bool rpc_Start() { bool ok = true; - if (_client == NULL) + if (_client == nullptr) { srand(clock()); _client = new TSocketClient; if (!_client->IsOk()) { delete _client; - _client = NULL; + _client = nullptr; ok = error_box(TR("Errore di inizializzazione del socket client.")); } } @@ -29,7 +29,7 @@ bool rpc_Stop() if (_client) { delete _client; - _client = NULL; + _client = nullptr; _connection = 0; } return true; @@ -44,7 +44,7 @@ bool rpc_Call(const char* cmd) int rpc_Timeout(int sec) { - CHECK(_client != NULL, "Client not initialized"); + CHECK(_client != nullptr, "Client not initialized"); const int to = _client->Timeout(); if (sec >= 0) _client->SetTimeout(sec); @@ -295,13 +295,13 @@ static unsigned int create_password(TString& pass) bool rpc_UserLogin(const char* server, const char* user, const char* dummy_password, const char* application) { - if (_client == NULL) + if (_client == nullptr) { if (!rpc_Start()) return false; } - const bool local = server == NULL || *server == '\0' || + const bool local = server == nullptr || *server == '\0' || xvt_str_same(server, "127.0.0.1") || xvt_str_same(server, "localhost"); TString80 name; @@ -484,7 +484,7 @@ bool http_dir(const char* server, const char* remote_dir, TString_array& list, i } bool http_post(const char* server, const char* remote_file, TString & content, char * & answer, size_t& length, - int timeout, int port, bool port_stmt, int type, const char * agent, const char* authorization) + int timeout, int port, bool port_stmt, http_media_types type, const char * agent, const char* authorization) { TSocketClient client; @@ -515,7 +515,7 @@ bool http_post(const char* server, const char* remote_file, TString & content, c bool http_post(const char* server, const char* remote_file, const char* local_file, char * & answer, size_t& length, - int timeout, int port, bool port_stmt, int type, const char * agent, const char* authorization) + int timeout, int port, bool port_stmt, http_media_types type, const char * agent, const char* authorization) { TSocketClient client; @@ -544,6 +544,90 @@ bool http_post(const char* server, const char* remote_file, return ok; } +bool http_curl_get(const char* url, const char* remote_file, const char* local_file, const char* user, const char * password) +{ + TString remote = url; + + remote << remote_file; + + int rescode = xvt_http_get(remote, local_file, user, password); + + bool ok = rescode > 199 && rescode < 400; + + if (!ok) + error_box(FR("Impossibile ricevere il file %s errore %d"), remote_file, rescode); + return ok; +} + +bool http_curl_dir(const char* url, const char* remote_dir, const char * type, bool subdirs, TString_array& list, const char* user, const char * password) +{ + TString remote = url; + + list.destroy(); + remote << remote_dir; + if (!remote.ends_with("/")) + remote << "/"; + + SLIST files = xvt_fsys_list_files("", remote, subdirs); + const int count = xvt_slist_count(files); + + if (count > 0) + { + for (SLIST_ELT e = xvt_slist_get_first(files); e; e = xvt_slist_get_next(files, e)) + { + const char* n = xvt_slist_get(files, e, nullptr); + + list.add(n); + } + } + xvt_slist_destroy(files); + return list.items() > 0; +} + +bool http_curl_post(const char* url, const char* remote_file, + http_media_types type, TString& request, TString& answer, + const char* user, const char * password) +{ + TFilename temp; + TString remote = url; + + remote << remote_file ; + temp.temp("post"); + int rescode = xvt_http_post(remote, temp, http_content(type), request, user, password); + + bool ok = rescode > 199 && rescode < 400; + + if (!ok) + error_box(FR("Post fallito %s errore %d"), (const char *)remote, + (const char *)rescode); + else + { + long size = fsize(temp); + ifstream resp(temp); + char * buffer = new char[size + 1]; + + resp.read(buffer, size); + buffer[size] = '\0'; + answer = buffer; + } + return ok; +} + +bool http_curl_put(const char* url, const char* local_file, const char* remote_file, const char* user, const char * password) +{ + TString remote = url; + + remote << remote_file; + + int rescode = xvt_http_get(local_file, remote, user, password); + + bool ok = rescode > 199 && rescode < 400; + + if (!ok) + error_box(FR("Impossibile inviare il file %s errore %d"), local_file, rescode); + return ok; +} + bool ftp_get(const char* server, const char* remote_file, const char* local_file, int port, const char * user, const char* pass) { diff --git a/src/include01/isamrpc.h b/src/include01/isamrpc.h index 0979ee005..6dd4cb9c8 100644 --- a/src/include01/isamrpc.h +++ b/src/include01/isamrpc.h @@ -3,13 +3,18 @@ #ifndef __REAL_H #include -#endif +#endif -#define CONTENT_TXT 0 -#define CONTENT_JSON 1 +#ifndef __STRINGS_H +#include +#endif + +#ifndef __MEDIATYPES_H +#include +#endif bool rpc_Call(const char* cmd); -char* rpc_Request(const char* cmd, unsigned long& size, real& time); +// char* rpc_Request(const char* cmd, unsigned long& size, real& time); bool rpc_DongleHasModule(word af); bool rpc_DongleModules(TBit_array& ba); @@ -27,14 +32,33 @@ bool rpc_Start(); bool rpc_Stop(); bool http_isredirected_server(TString & server, TFilename & remote_file, int port = 0, const char* authorization = nullptr); + bool http_get(const char* server, const char* remote_file, const char* local_file, int port = 80, const char * agent = nullptr, const char* authorization = nullptr); bool http_dir(const char* server, const char* remote_dir, TString_array & list, int port = 80, const char * agent = nullptr, const char* authorization = nullptr); bool http_post(const char* server, const char* remote_file, TString & content, char * & answer, size_t& length, - int timeout, int port = 80, bool port_stmt = true, int type = CONTENT_TXT, const char * agent = nullptr, const char* authorization = nullptr); + int timeout, int port = 80, bool port_stmt = true, int type = media_txt, const char * agent = nullptr, const char* authorization = nullptr); bool http_post(const char* server, const char* remote_file, const char* local_file, char * & answer, size_t& length, - int timeout, int port = 80, bool port_stmt = true, int type = CONTENT_TXT, const char * agent = nullptr, const char* authorization = nullptr); + int timeout, int port = 80, bool port_stmt = true, http_media_types type = media_txt, const char * agent = nullptr, const char* authorization = nullptr); + +bool http_curl_get(const char* url, const char* remote_file, + const char* local_file, + const char* user = nullptr, + const char * password = nullptr); +bool http_curl_dir(const char* url, const char* remote_dir, + const char * type, bool subdirs, TString_array& list, + const char* user = nullptr, + const char * password = nullptr); +bool http_curl_post(const char* url, const char* remote_file, + http_media_types type, TString& request, + TString& answer, const char* user = nullptr, + const char * password = nullptr); +bool http_curl_put(const char* url, const char* local_file, + const char* remote_file, + const char* user = nullptr, + const char * password = nullptr); + bool ftp_get(const char* server, const char* remote_file, const char* local_file, int port = 21, const char * user = nullptr, const char* pass = nullptr); bool ftp_dir(const char* server, const char* remote_dir, TString_array & list, diff --git a/src/include01/maskfld.h b/src/include01/maskfld.h index 322cc540c..e117c2fa8 100644 --- a/src/include01/maskfld.h +++ b/src/include01/maskfld.h @@ -136,7 +136,7 @@ protected: bool pipeallowed : 1; bool user : 1; bool previous : 1; - + TField_Flags(); char update(const char* f, bool reset = false); } _flags; @@ -567,7 +567,7 @@ public: // @cmember Controlla se il campo ha un messaggio virtual bool has_message() const - { return _message != NULL; } + { return _message != nullptr; } // @cmember Setta l'handler del controllo virtual void set_handler(CONTROL_HANDLER handler) @@ -903,7 +903,7 @@ public: // @cmember Scrive il valore del campo direttamente sulla finestra del controllo virtual void set_window_data(const char* data); - // @cmember Setta il flag read-only + // @cmember Setta il flag read-only virtual void set_read_only(bool r); // @cmember Setta il flag autobrowse void set_autobrowse(bool on = true) { _autobrowse = on; } @@ -926,7 +926,7 @@ public: virtual bool has_check() const; // @cmember Controlla se il campo ha una ricerca virtual bool has_query_button() const - { return _browse != NULL || _flags.button; } + { return _browse != nullptr || _flags.button; } // @cmember Imposta la ricerca del campo virtual void set_query_button(TBrowse_button* ); diff --git a/src/include01/mediatypes.h b/src/include01/mediatypes.h index 13ef93b83..6363fdac8 100644 --- a/src/include01/mediatypes.h +++ b/src/include01/mediatypes.h @@ -1790,5 +1790,5 @@ typedef enum { media_zstd } http_media_types; -const char * http_content(http_media_types type); + const char * http_content(http_media_types type); #endif diff --git a/src/include01/msksheet.cpp b/src/include01/msksheet.cpp index 19f6ef778..9d6b302f4 100644 --- a/src/include01/msksheet.cpp +++ b/src/include01/msksheet.cpp @@ -6,6 +6,7 @@ extern "C" #include } +#include #include #include #include @@ -194,6 +195,10 @@ bool TRow_property::get(int col, COLOR & back, COLOR & fore) const // di una maschera // // @base public | TWindow + + // @cmember:(INTERNAL) costanti +enum { MAX_COL = 96 }; + class TSpreadsheet : public TControl { // @author:(INTERNAL) Guido @@ -202,8 +207,6 @@ class TSpreadsheet : public TControl friend class TSheet_field; // @access:(INTERNAL) Private Member - // @cmember:(INTERNAL) costanti - enum { MAX_COL=96 }; static int ROW_NUMBER_WIDTH; // @cmember:(INTERNAL) Array di TToken_strings contenenti le righe @@ -2961,10 +2964,10 @@ void TSpreadsheet::paste_rows() // Certified 100% TSheet_field::TSheet_field(TMask* m) - : TLoadable_field(m), _append(true), - _separator('|'), _enable_autoload(false), _sheetfile(NULL), - _linee_rec(NULL), _external_record(false), _userput(NULL),_userget(NULL), - _extended(false) + : TLoadable_field(m), _append(true), + _separator('|'), _enable_autoload(false), _sheetfile(NULL), + _linee_rec(NULL), _external_record(false), _userput(NULL), _userget(NULL), + _extended(false) { } @@ -3071,7 +3074,7 @@ bool TSheet_field::parse_item(TScanner& scanner) case 'I': _append = false; break; case '|': _separator = SAFE_PIPE_CHR; break; case 'L': _flags.read_only = true; break; - case 'D': _flags.enable_default = false; break; + case 'D': _flags.enable_default = false; break; default : break; } } @@ -3155,7 +3158,7 @@ void TSheet_field::create(WINDOW parent) { ((TSpreadsheet*)_ctl)->activate(false); } - + const TMask& s = sheet_mask(); for (short id = FIRST_FIELD; ; id++) { @@ -3661,14 +3664,14 @@ void TSheet_field::sort(ROWS_COMPARE_FUNCTION compare) const long last = items()-1; for (int i = 0; i < last; i++) - { + { for (int j = i+1; j <= last; j++) - { + { const int cmp = compare(*this, i, j); if (cmp > 0) swap_rows( i,j); } - } + } } int TSheet_field::set_line_number_width(int width ) @@ -4011,7 +4014,7 @@ void TSheet_field::check_row(int n, int mode, bool final) TMaskmode mask_mode = (TMaskmode) m.mode(); m.set_mode(mask().mode()); - for (int i = max - 1; i >= 0; i--) + for (int i = max - 1; i >= 0; i--) { TMask_field & f = m.fld(i); diff --git a/src/include01/multirec.h b/src/include01/multirec.h index f17787831..90f8663f1 100644 --- a/src/include01/multirec.h +++ b/src/include01/multirec.h @@ -106,7 +106,7 @@ public: // record e I/O virtual void dirty_fields() {} virtual void set_fields(TAuto_variable_rectype & rec) {} - virtual void reset_fields(TAuto_variable_rectype & rec) { rec.remove_field(); } + virtual void reset_fields(TAuto_variable_rectype & rec, bool all = true) { rec.remove_field(nullptr, all); } virtual TMultiple_rectype & operator =(const TMultiple_rectype & r) { return copy(r);} virtual TRectype & operator =(const TRectype & r); diff --git a/src/include01/netsock.cpp b/src/include01/netsock.cpp index cd848e388..5b2033b82 100644 --- a/src/include01/netsock.cpp +++ b/src/include01/netsock.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +52,6 @@ protected: SOCKET &_socket ; } ; -HIDDEN const char * __content_type[] = { "text/plain", "application/json" }; // // skstream // @@ -1040,7 +1040,7 @@ bool TSocketClient::HttpSoap(CONNID id, const char* cmd, const char * agent) if (agent && *agent) buf << "User-Agent: " << agent << "\r\n"; buf << "Host: " << hostname << "\n" - << "Content-Type: " << __content_type[0] << "; charset=utf-8\n" + << "Content-Type: " << http_content(media_txt) << "; charset=utf-8\n" << "Content-length: " << content.len() << "\n" << "SOAPAction: \"/\"\r\n\r\n" << content; @@ -1079,7 +1079,7 @@ bool TSocketClient::HttpSoap(CONNID id, const char* cmd, const char * agent) static const char* const eol = "\r\n"; -bool TSocketClient::HttpPost(CONNID id, const char* remote, TString & content, int timeout, int port, bool port_stmt, int type, const char * agent, const char* authorization) +bool TSocketClient::HttpPost(CONNID id, const char* remote, TString & content, int timeout, int port, bool port_stmt, http_media_types type, const char * agent, const char* authorization) { TSocket_connection* conn = (TSocket_connection*)GetConnection(id); skstream* cur_socket = conn->GetSocket(); @@ -1100,7 +1100,7 @@ bool TSocketClient::HttpPost(CONNID id, const char* remote, TString & content, i buf << "User-Agent: " << agent << eol; else buf << "User-Agent: Mozilla/4.0" << eol; - buf << "Content-Type: " << __content_type[type] << eol + buf << "Content-Type: " << http_content(type) << eol << "Content-Length: " << length + 2 << eol; if (authorization && *authorization) buf << "Authorization: " << authorization << eol; @@ -1147,7 +1147,7 @@ bool TSocketClient::HttpPost(CONNID id, const char* remote, TString & content, i return ok; } -bool TSocketClient::HttpPostFile(CONNID id, const char* remote, const char* local, int timeout, int port, bool port_stmt, int type, const char * agent, const char* authorization) +bool TSocketClient::HttpPostFile(CONNID id, const char* remote, const char* local, int timeout, int port, bool port_stmt, http_media_types type, const char * agent, const char* authorization) { TString content; @@ -1164,7 +1164,6 @@ bool TSocketClient::HttpPostFile(CONNID id, const char* remote, const char* loca break; } return HttpPost(id, remote, content, timeout, port, port_stmt, type, agent, authorization); - } bool TSocketClient::HttpPutFile(CONNID id, const char* remote, const char* local, const char * agent, const char* authorization) diff --git a/src/include01/netsock.h b/src/include01/netsock.h index dd0e374be..7af4a9cc1 100644 --- a/src/include01/netsock.h +++ b/src/include01/netsock.h @@ -5,6 +5,10 @@ #include "netutils.h" #endif +#ifndef __MEDIATYPES_H__ +#include "mediatypes.h" +#endif + class TSocketServer : public TLanServer { byte* m_pData; @@ -55,8 +59,8 @@ public: bool HttpGetFile(CONNID id, const char* remote, const char* local, const char * agent = nullptr, const char* authorization = nullptr); bool HttpGetDir(CONNID id, const char* remote, TString_array& list, const char * agent = nullptr, const char* authorization = nullptr); bool HttpSoap(CONNID id, const char* query, const char * agent = nullptr); - bool HttpPost(CONNID id, const char* remote, TString & content, int timeout, int port, bool port_stmt = true, int type = 0, const char * agent = nullptr, const char* authorization = nullptr); - bool HttpPostFile(CONNID id, const char* remote, const char* local, int timeout, int port, bool port_stmt = true, int type = 0, const char * agent = nullptr, const char* authorization = nullptr); + bool HttpPost(CONNID id, const char* remote, TString & content, int timeout, int port, bool port_stmt = true, http_media_types type = media_txt, const char * agent = nullptr, const char* authorization = nullptr); + bool HttpPostFile(CONNID id, const char* remote, const char* local, int timeout, int port, bool port_stmt = true, http_media_types type = media_txt, const char * agent = nullptr, const char* authorization = nullptr); bool HttpPutFile(CONNID id, const char* remote, const char* local, const char * agent = nullptr, const char* authorization = nullptr); bool FtpGetDir(CONNID id, const char* remote, TString_array& list, const char* user = nullptr, const char* pass = nullptr); bool FtpGetFile(CONNID id, const char* remote, const char* local, const char* user = nullptr, const char* pass = nullptr); diff --git a/src/include01/object.h b/src/include01/object.h index 6bb55bf0d..9ad463ff7 100644 --- a/src/include01/object.h +++ b/src/include01/object.h @@ -26,7 +26,7 @@ // @class TObject | Classe base per la definizione della gerarchia degli oggetti class TObject -// @author:(INTERNAL) Guido + // @author:(INTERNAL) Guido { // @access Public Member public: @@ -251,8 +251,8 @@ inline bool operator <=( // @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 + 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. @@ -261,6 +261,29 @@ inline bool operator !=( return res != 0 && res != UNDEFINED; } +class TShort :public TSortable + // @author:(INTERNAL) Bonazzi + // Short per utilizzarlo negli array +{ + int _s; + +protected: + // @cmember Permette di stampare l'oggetto + virtual void print_on(ostream& out) const { out << _s; } + TShort & copy(const TShort & i) { _s = i._s; return *this; } + +public: + virtual int compare(const TSortable& s) const override { return _s - ((TShort&)s)._s; } + virtual TObject* dup() const { return new TShort(*this); } + short val() const { return _s; } + operator short() const { return val(); } + TShort & operator ==(TShort& s) { return copy(s); } + TShort & operator ==(short s) { _s = s; return *this; } + + TShort(short s = 0) : _s(s) { } + ~TShort() = default; +}; + #ifdef __OBJECT_CPP #define extern #endif diff --git a/src/include01/real.cpp b/src/include01/real.cpp index a4efef84d..f44b782a3 100644 --- a/src/include01/real.cpp +++ b/src/include01/real.cpp @@ -38,6 +38,7 @@ const real VENTUNO(21.0); const real VENTIDUE(22.0); const real CINQUANTA(50.0); const real CENTO(100.0); +const real MILLE(1000.0); #include //#include diff --git a/src/include01/real.h b/src/include01/real.h index a1672716a..c630c8cec 100644 --- a/src/include01/real.h +++ b/src/include01/real.h @@ -47,6 +47,7 @@ extern const real VENTUNO; extern const real VENTIDUE; extern const real CINQUANTA; extern const real CENTO; +extern const real MILLE; #define UN_CENTESIMO PUNTO_ZERO_UNO #define REALE_ZERO(r) (abs(r) < UN_CENTESIMO) diff --git a/src/include01/recset.cpp b/src/include01/recset.cpp index c085f0743..418923554 100644 --- a/src/include01/recset.cpp +++ b/src/include01/recset.cpp @@ -1065,10 +1065,11 @@ bool list_custom_files(const char* ext, const char* classe, TString_array& files if (ok) { - get_xml_child(stringona, "description", desc); - TToken_string* riga = new TToken_string; + get_xml_child(stringona, "description", desc); + if (desc.blank()) + desc << "Report " << path.name_only(); if (type[0] == 'D') { riga->add(desc); @@ -1143,8 +1144,8 @@ protected: void parse_filter(TToken_string& filter); void parse_select(TToken_string& filter); void parse_region(TRectype& rec, bool final); - void parse_join_param(TRelation* rel, const TString& j, int to); - void parse_join(); + void parse_join_param(TRelation* rel, const TString& j, int to, bool connect = false); + void parse_join(bool connect = false); void parse_sortedjoin(); public: @@ -1339,8 +1340,7 @@ void TCursor_parser::parse_region(TRectype& rec, bool final) push(); } - -void TCursor_parser::parse_join_param(TRelation* rel, const TString& j, int to) +void TCursor_parser::parse_join_param(TRelation* rel, const TString& j, int to, bool connect) { int key = 1; const TString& tok = pop(); @@ -1372,16 +1372,17 @@ void TCursor_parser::parse_join_param(TRelation* rel, const TString& j, int to) yesnofatal_box("JOIN senza espressioni INTO"); const int logicnum = table2logic(j); + switch (logicnum) { case LF_TABGEN: case LF_TABCOM: case LF_TAB: case LF_TABMOD: - rel->add(j, exp, key, to, alias); // join table + rel->add(j, exp, key, to, alias, false, connect); // join table break; default: - rel->add(logicnum, exp, key, to, alias); // join file + rel->add(logicnum, exp, key, to, alias, false, connect); // join file break; } @@ -1394,7 +1395,7 @@ void TCursor_parser::parse_join_param(TRelation* rel, const TString& j, int to) add_column_info(tabname, rec); } -void TCursor_parser::parse_join() +void TCursor_parser::parse_join(bool connect) { const TString j = pop(); // File or table @@ -1407,8 +1408,7 @@ void TCursor_parser::parse_join() } else push(); - - parse_join_param(_relation, j, to); + parse_join_param(_relation, j, to, connect); } void TCursor_parser::parse_sortedjoin() @@ -1605,15 +1605,21 @@ TCursor_parser::TCursor_parser(istream& instr, TArray& col) { pop(); if (tok.starts_with("FR")) - parse_region(rec_start, false); else - if (tok.starts_with("TO")) - parse_region(rec_stop, true); else - if (tok.starts_with("JO")) - parse_join(); else - if (tok.starts_with("SO")) - parse_sortedjoin(); - else - break; + parse_region(rec_start, false); + else + if (tok.starts_with("TO")) + parse_region(rec_stop, true); + else + if (tok.starts_with("JO")) + parse_join(); + else + if (tok.starts_with("SO")) + parse_sortedjoin(); + else + if (tok.starts_with("RI")) + parse_join(true); + else + break; } push(); diff --git a/src/include01/recset.h b/src/include01/recset.h index 95f9071b7..52f699d2e 100644 --- a/src/include01/recset.h +++ b/src/include01/recset.h @@ -118,7 +118,8 @@ public: // Absolutely needed methods virtual const TVariant& get(unsigned int column) const pure; - virtual const TString_array& variables() const { return _varnames; } + virtual const TString_array& variables() const { return _varnames; } + virtual void clear_variables() { _varnames.destroy(); } virtual const TVariant& get_var(const char* name) const; virtual bool set_var(const char* name, const TVariant& var, bool create = false); virtual bool ask_variables(bool all); diff --git a/src/include01/relation.cpp b/src/include01/relation.cpp index 4d0d91d66..5e0c39fc4 100644 --- a/src/include01/relation.cpp +++ b/src/include01/relation.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,8 @@ class TRelationdef : public TObject TBit_array _forced; bool _first_match : 1; // primo match (ed esiste) bool _allow_lock : 1; // ?? - bool _write_enable : 1; + bool _write_enable : 1; + bool _right : 1; public: // TObject virtual void print_on(ostream& out) const; @@ -107,11 +109,11 @@ public: TRelationdef(const TRelation* rel, int file, byte key, int linkto, const char* relexprs, int alias, - bool allow_lock); + bool allow_lock, bool right = false); // Costruttore di copia TRelationdef(const TRelationdef& reldef); - virtual ~TRelationdef() {} + virtual ~TRelationdef() = default; }; TRelationdef & TRelationdef::copy(const TRelationdef & reldef) @@ -125,17 +127,18 @@ TRelationdef & TRelationdef::copy(const TRelationdef & reldef) _exprs = reldef._exprs; _first_match = reldef._first_match; _allow_lock = reldef._allow_lock; - _write_enable = reldef._write_enable; + _write_enable = reldef._write_enable; + _right = reldef._right; return *this; } TRelationdef::TRelationdef(const TRelation* rel, int idx_file, byte key, int idx_to, const char* relexprs, int alias, - bool allow_lock) + bool allow_lock, bool right) : _rel(rel), _num(idx_file), _numto(idx_to), _alias(alias), _key(key), _fields(4), _exprs(4), - _first_match(FALSE), _allow_lock(allow_lock), - _write_enable(FALSE) + _first_match(false), _allow_lock(allow_lock), + _write_enable(false), _right(right) { TToken_string rels(relexprs); int i = 0; @@ -151,7 +154,7 @@ TRelationdef::TRelationdef(const TRelation* rel, int idx_file, byte key, s = r.left(eq); // Parte a sinistra dell' = #ifdef DBG - const char* n = s; + TString n = s; const int p = s.find('['); if (p > 0) n = s.left(p); if (rel->file(_num).curr().exist(n) == FALSE) @@ -192,7 +195,10 @@ void TRelationdef::print_on(ostream& out) const { const TLocalisamfile& f = _rel->file(_num); - out << "JOIN "; + if (_right) + out << "CONNECT "; + else + out << "JOIN "; print_name(out, f); if (_numto > 0) @@ -266,7 +272,6 @@ void TRelationdef::print_on(TToken_string& out) const } } - const char* TRelationdef::evaluate_expr(int j, const TLocalisamfile& to) const { const TRectype& rec = to.curr(); @@ -340,7 +345,9 @@ TRelation::TRelation(const char* tabname) TRelation::TRelation(TLocalisamfile* l) : _files(4), _reldefs(4), _errors(NOERR) -{ _files.add(l); } +{ + _files.add(l); +} TRelation::TRelation(const TRelation & rel) { @@ -560,8 +567,9 @@ bool TRelation::add( int key, // @parm Chiave del file int linkto, // @parm Posizione alla quale aggiungere il file int alias, // @parm Alias da dare al file da aggiungere - bool allow_lock) // @parm Indica se fare il lock sul file oppure ignorarli - // @parm int | logicnum | Numero logico del file da aggiungere + bool allow_lock, // @parm Indica se fare il lock sul file oppure ignorarli + bool right) // @parm Indica se fare una connessione con la cache + // @parm int | logicnum | Numero logico del file da aggiungere // @parm const char* | tabname | Nome della tabella da aggiungere // @syntax bool add(TLocalisamfile* f, const char* relexprs, int key, int linkto, int alias, bool allow_lock); @@ -584,30 +592,28 @@ bool TRelation::add( CHECK(relexprs && *relexprs, "Mancano le espressioni di collegamento"); - TRelationdef* r = new TRelationdef(this, idx, key, idxto, - relexprs, alias, allow_lock); + TRelationdef* r = new TRelationdef(this, idx, key, idxto, relexprs, alias, + allow_lock, right); _reldefs.add(r); - - return TRUE; + return true; } - bool TRelation::add(int logicnum, const char* relexprs, int key, - int linkto, int alias, bool allow_lock) + int linkto, int alias, bool allow_lock, bool right) { TLocalisamfile* f = new TLocalisamfile(logicnum); - return add(f, relexprs, key, linkto, alias, allow_lock); + return add(f, relexprs, key, linkto, alias, allow_lock, right); } bool TRelation::add(const char* tabname, const char* relexprs, int key, - int linkto, int alias, bool allow_lock) + int linkto, int alias, bool allow_lock, bool right) { - TLocalisamfile* t = NULL; + TLocalisamfile* t = nullptr; if (*tabname == '&') t = new TModule_table(tabname); else t = new TTable(tabname); - return add(t, relexprs, key, linkto, alias, allow_lock); + return add(t, relexprs, key, linkto, alias, allow_lock, right); } // @doc EXTERNAL @@ -694,35 +700,47 @@ int TRelation::position_rels( const int ultimo = first < 0 && (-first) < _reldefs.items() ? -first : _reldefs.items(); // workhorse: position files for each active relation - for (int i = primo; i < ultimo; i++) - { - TRelationdef& rd = reldef(i); + for (int i = primo; i < ultimo; i++) + { + TRelationdef& rd = reldef(i); - if (primo > 0 && rd.link() < primo) - continue; // Inutile spostare file collegati a record precedenti + if (primo > 0 && rd.link() < primo) + continue; // Inutile spostare file collegati a record precedenti - TLocalisamfile& from = file(rd.num()); - TLocalisamfile& to = file(rd.link()); - from.zero(); // Azzera il record corrente (tutti se TSortedfile) - if (to.curr().empty()) - continue; + TLocalisamfile& from = file(rd.num()); + TLocalisamfile& to = file(rd.link()); + from.zero(); // Azzera il record corrente (tutti se TSortedfile) + if (to.curr().empty()) + continue; - from.setkey(rd._key); + from.setkey(rd._key); - // build record - TRectype& furr = from.curr(); - for (int j = 0; j < rd._fields.items(); j++) // for each field - { - expr = rd.evaluate_expr(j, to); - const TFieldref& s = (const TFieldref&) rd._fields[j]; - s.write(expr, furr); - } // for each field + // build record + TRectype& furr = from.curr(); + for (int j = 0; j < rd._fields.items(); j++) // for each field + { + expr = rd.evaluate_expr(j, to); + const TFieldref& s = (const TFieldref&)rd._fields[j]; + s.write(expr, furr); + } // for each field - const TReclock lck = rd._allow_lock ? lockop : _nolock; - from.read(_isgteq, lck); + const TReclock lck = rd._allow_lock ? lockop : _nolock; + bool eq = false; - // record read : if not found, zero current record - bool eq = !from.bad(); + if (rd._right) + { + const TToken_string key = furr.build_token_key(rd._key); + + furr = cache().get(furr.num(), key, rd._key); + // record read : if not found, zero current record + eq = furr.full(); + } + else + { + from.read(_isgteq, lck); + // record read : if not found, zero current record + eq = !from.bad(); + } for (int kk = 0; eq && kk < rd._fields.items(); kk++) { TFieldref& fl = (TFieldref&)rd._fields[kk]; @@ -1124,7 +1142,8 @@ bool TCursor::has_simple_filter() const { const RecDes& recd = curr().rec_des(); // Descrizione del record della testata const KeyDes& kd = recd.Ky[_nkey-1]; // Elenco dei campi della chiave del cursore - for (int i = _fexpr->numvar()-1; yes && i >= 0; i--) + + for (int i = _fexpr->numvar()-1; yes && i >= 0; i--) { const char * vn = _fexpr->varname(i); TFieldref f(vn, 0); @@ -2915,7 +2934,7 @@ void TRelation_description::read_rel() TFilename descfname; descfname << DESCDIR << "/d"; const char* tn = tt.get(0); // Codice del file o tabella const int which_file = name2log(tn); // Numero logico del file - + if (tn[0] == '%' || tn[0] == '$') descfname << (tn+1); else @@ -2929,7 +2948,7 @@ void TRelation_description::read_rel() TTrec trec; trec.get(which_file); TToken_string ttmp(64); TString dfld(256); - + for (int f = 0; f < trec.fields(); f++) { ttmp = trec.fielddef(f); @@ -2940,7 +2959,7 @@ void TRelation_description::read_rel() if (!dfld.blank() && dfld[0] != '#') { ttmp.add(dfld, 4); - // contiene: nome campo, tipo, lunghezza, decimali, descrizione + // contiene: nome campo, tipo, lunghezza, decimali, descrizione rdesc->add(ttmp); } } @@ -3201,7 +3220,7 @@ const char* TRelation_description::get_field_description(const char* field) TRelation_description::TRelation_description(TRelation& r) : _rel(&r), _cur_file(0), _cur_field(0), _menu(FALSE), - _cfile(80), _cfield(80) + _cfile(80), _cfield(80) { read_rel(); if (_files.items() > 0) diff --git a/src/include01/relation.h b/src/include01/relation.h index 6a8a973d1..73665ce53 100644 --- a/src/include01/relation.h +++ b/src/include01/relation.h @@ -115,11 +115,11 @@ public:// TObject bool next_match(int logicnum, const char* fieldlist = NULL, int nkey = 0); // @cmember Aggiunge una nuovo file alla relazione partendo dal descrittore del file - bool add(TLocalisamfile* f, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = FALSE); + bool add(TLocalisamfile* f, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = false, bool right = false); // @cmember Aggiunge una nuovo file alla relazione partendo dal numero logico del file - bool add(int logicnum, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = FALSE); + bool add(int logicnum, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = false, bool right = false); // @cmember Aggiunge una nuovo file alla relazione partendo dal nome della tabella - bool add(const char* tabname, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = FALSE); + bool add(const char* tabname, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = false, bool right = false); // @cmember Sostituisce nella relazione il file di indice index void replace(TLocalisamfile* f, int index = 0,const char * relexprs="",int key=1); // @cmember Sostituisce nella relazione il file di ID lognum diff --git a/src/include01/reprint.cpp b/src/include01/reprint.cpp index cee5c3992..8c888dc83 100644 --- a/src/include01/reprint.cpp +++ b/src/include01/reprint.cpp @@ -1337,7 +1337,7 @@ bool TBook::print_page(TWindow& win, size_t page) RCT rct_riga; win.log2dev(rect_riga, rct_riga); const int default_10row_height = rct_riga.bottom - rct_riga.top; - const streampos pos = ((const TFilepos &)_index[page]).pos(); + const streampos pos = (const TFilepos &)_index[page]; ifstream ifs(_file); ifs.seekg(pos); @@ -2156,7 +2156,7 @@ void TBook::split_file(int colonne) { if (!pi.setstatus(page)) break; - const streampos pos = ((const TFilepos &)_index[page]).pos(); + const streampos pos = (const TFilepos &)_index[page]; for (int c = 0; c < colonne; c++) { const TRectangle rct_page(c*_page_size.x, 0, _page_size.x, _page_size.y); diff --git a/src/include01/sheet.cpp b/src/include01/sheet.cpp index a862db9a2..31288cee3 100644 --- a/src/include01/sheet.cpp +++ b/src/include01/sheet.cpp @@ -1012,7 +1012,7 @@ TSheet::TSheet(short x, short y, short dx, short dy, const char* title, const char* head, byte buttons, short sht_y, WINDOW parent) : TMask(title, 1, dx, dy, x, y, parent), - _sheet(nullptr), _select_row(-1), _parked(-1) + _sheet(nullptr), _select_row(-1), _parked(-1), _head(head) { create_bar(1); // Crea toolbar in alto @@ -1565,7 +1565,7 @@ bool TArray_sheet::destroy(int i) enable_row(-1); reset_parked(); return _data.destroy(i, true); -} +} // @doc EXTERNAL @@ -1635,7 +1635,7 @@ TCursor_sheet::TCursor_sheet(TCursor* cursor, const char* fields, const char* title, const char* head, byte buttons, short sht_y, WINDOW parent) : TSheet(sht_y ? 3 : 0, sht_y ? 3 : 0, sht_y ? -3 : 0, sht_y ? -3 : 0, - title, head, buttons, sht_y, parent), _cursor(cursor) + title, head, buttons, sht_y, parent), _cursor(cursor), _sorted(false) { TToken_string fldlst(fields); int campo = 0; @@ -1680,8 +1680,11 @@ long TCursor_sheet::get_items() const void TCursor_sheet::get_row(long row, TToken_string& l) { - *_cursor = (TRecnotype)row; - l.cut(0); + if (_nrecs.items() > 0 && _nrecs.objptr(row) != nullptr) + *_cursor = ((TORecnotype &)_nrecs[row]).val(); + else + *_cursor = (TRecnotype)row; + l.cut(0); const int last = _fields.last(); for (int i = 0; i <= last; i++) { @@ -2055,7 +2058,7 @@ long TBrowse_sheet::handler( case 4: on_key(K_CTRL + 'E'); return 0L; - default: + default: break; } break; diff --git a/src/include01/sheet.h b/src/include01/sheet.h index d3c30c2d3..14ac7ff55 100644 --- a/src/include01/sheet.h +++ b/src/include01/sheet.h @@ -1,12 +1,21 @@ #ifndef __SHEET_H #define __SHEET_H +#ifndef __ISAM_H +#include +#endif + #ifndef __MASK_H #include #endif +class TCursor_sheet; + // @doc INTERNAL +//typedef (*SHEET_ROWS_COMPARE_FUNCTION)(const TCursor_sheet &, const TToken_string&); +typedef int(*SHEET_ROWS_COMPARE_FUNCTION)(TCursor_sheet & s, int r1, int r2); + // @class TSheet | Classe per la definizione e la gestione degli sheet per le ricerche // // @base public | TScroll_window @@ -18,6 +27,7 @@ class TSheet : public TMask { friend class TSheet_control; TSheet_control* _sheet; // Spreadsheet contenuto + TToken_string _head; TToken_string _park; // Ultima riga richiesta long _select_row; // Riga da selezionare @@ -117,6 +127,12 @@ public: // @cmember Forza l'aggiornamento di una o tutte le righe visibili void force_update(int r = -1); + int columns() const { return _head.items(); } + // @cmember Setta il titolo della colonna + void set_column_header(const int col, const TString& header) { _head.add(header, col); } + // @cmember Getta il titolo della colonna + const char* get_column_header(const int col) { return _head.get(col); } + // @cmember Costruttore TSheet(short x, short y, short dx, short dy, const char* title, const char* head, byte buttons = 0, short sht_y = 0, WINDOW parent = NULL_WIN); @@ -148,7 +164,7 @@ protected: // @cmember Ritorna il numero degli elementi dello sheet virtual long get_items() const { return _data.items(); } - // @access Public Member + // @access Public Member public: // @cmember Costruttore TArray_sheet(short x, short y, short dx, short dy, const char* caption, @@ -165,6 +181,7 @@ public: long insert(const TToken_string& s, long n); // @cmember Azzera l'array dello sheet bool destroy(int i = -1); + }; @@ -181,6 +198,8 @@ class TCursor_sheet : public TSheet { // @cmember:(INTERNAL) Array di TArray _fields; + bool _sorted; + TArray _nrecs; // @cmember:(INTERNAL) Cursore da cui prelevare i dati TCursor* _cursor; @@ -192,7 +211,7 @@ protected: // TSheet // @cmember Ritorna il numero dei records del cursore virtual long get_items() const; - + // @cmember Ritorna la riga n virtual void get_row(long n, TToken_string& row); @@ -203,7 +222,7 @@ protected: // TSheet bool filter_dialog(); bool update_dialog(); - // @access Public Member + // @access Public Member public: // TSheet // @cmember Lancia la finestra con lo sheet @@ -217,8 +236,8 @@ public: { return _cursor; } const TArray& fields_array() const { return _fields; } - - // @cmember Costruttore + + // @cmember Costruttore TCursor_sheet(TCursor* cursor, const char* fields, const char* title, const char* head, byte buttons = 0, short sht_y = 0, WINDOW parent = NULL_WIN); // @cmember Distruttore diff --git a/src/include01/strings.cpp b/src/include01/strings.cpp index b2fddcdd0..ea433b943 100644 --- a/src/include01/strings.cpp +++ b/src/include01/strings.cpp @@ -5,6 +5,9 @@ #include #include + +#define _MAX_DRIVE_PROTO _MAX_DIR+6 + // @doc EXTERNAL // @func Ritorna il nome dell'utente attuale @@ -1183,7 +1186,8 @@ void TFilename::ext(const char* e) *this << e; } */ - char v[_MAX_DRIVE], d[_MAX_DIR], n[_MAX_FNAME], p[_MAX_PATH]; + char v[_MAX_DRIVE_PROTO], d[_MAX_DIR], n[_MAX_FNAME], p[_MAX_PATH]; + xvt_fsys_parse_pathname(_str, v, d, n, nullptr, nullptr); xvt_fsys_build_pathname(p, v, d, n, e, nullptr); set(p); @@ -1249,7 +1253,7 @@ const char* TFilename::path() const */ if (full()) { - char v[_MAX_DRIVE], d[_MAX_DIR]; + char v[_MAX_DRIVE_PROTO], d[_MAX_DIR]; v[0] = '\0'; xvt_fsys_parse_pathname(_str, find(":") > 0 ? v : nullptr, d, nullptr, nullptr, nullptr); @@ -1440,6 +1444,8 @@ TFilename& TFilename::temp( bool TFilename::is_absolute_path() const { const char* s = _str; + if (is_remote(_str)) + return true; if (isalpha(*s) && s[1] == ':') s += 2; return is_slash(*s); @@ -1465,7 +1471,7 @@ bool TFilename::exist() const bool TFilename::fremove() const { - return xvt_fsys_remove_file(_str) != false; + return full() ? xvt_fsys_remove_file(_str) != false : true; } bool TFilename::frename(const char* src_path, const char* dst_path) diff --git a/src/include01/utility.cpp b/src/include01/utility.cpp index 5d0c77b2b..9708e0a6f 100644 --- a/src/include01/utility.cpp +++ b/src/include01/utility.cpp @@ -110,14 +110,17 @@ bool fcopy( if (xvt_str_same(orig, dest)) return true; // Or FALSE? - FILE* i = NULL; fopen_s(&i, orig, rflag); - if (i == NULL) + FILE* i = nullptr; fopen_s(&i, orig, rflag); + + if (i == nullptr) return error_box(FR("Impossibile leggere il file '%s'\nda copiare in '%s'\nErrore %d"), orig, dest, errno); if (!append) xvt_fsys_remove_file(dest); - FILE* o = NULL; fopen_s(&o, dest, wflag); - if (o == NULL) + + FILE* o = nullptr; fopen_s(&o, dest, wflag); + + if (o == nullptr) { fclose(i); if (append) @@ -187,19 +190,28 @@ bool fmove( bool fexist( const char* file) // @parm Nome del file di cui controllare l'esistenza { - return file && *file && xvt_fsys_file_exists(file) != 0; + return file && *file && (is_remote(file) || xvt_fsys_file_exists(file) != 0); } bool dexist( const char* file) // @parm Nome del direttorio di cui controllare l'esistenza { - return file && *file && xvt_fsys_dir_exists(file) != 0; + return file && *file && (is_remote(file) || xvt_fsys_dir_exists(file) != 0); } -bool is_dir( - const char* file) // @parm ritorna se file è un direttorio di cui controllare l'esistenza +bool is_dir(const char* file) // @parm ritorna se file è un direttorio di cui controllare l'esistenza { - return file && *file && xvt_fsys_file_attr(file, XVT_FILE_ATTR_DIRECTORY) != 0; + return file && *file && (is_remote(file) || xvt_fsys_file_attr(file, XVT_FILE_ATTR_DIRECTORY) != 0); +} + +bool is_ftp(const char* file) // @parm ritorna se file è un direttorio di cui controllare l'esistenza +{ + return file && *file && strncmp(file, "ftp:", 4) == 0; +} + +bool is_http(const char* file) // @parm ritorna se file è un direttorio di cui controllare l'esistenza +{ + return file && *file && (strncmp(file, "http:", 5) == 0 || strncmp(file, "https:", 6) == 0); } long fsize(const char* name) @@ -277,7 +289,7 @@ TDate mldate(const char* file) // @flag FALSE | Se l'operazione non e' riuscita bool make_dir(const char* dir) // @parm Nome della directory da creare { - return xvt_fsys_mkdir(dir) != 0; + return !is_remote(dir) && xvt_fsys_mkdir(dir) != 0; } // @doc EXTERNAL @@ -1161,4 +1173,4 @@ int xslt_transform(const TString& infile, const TString& stylefile, const TStrin if (fexist(outfile)) remove_file(outfile); return xvt_xslt_transform(infile, stylefile, outfile); -} \ No newline at end of file +} diff --git a/src/include01/utility.h b/src/include01/utility.h index 7400d874c..61a4095ed 100644 --- a/src/include01/utility.h +++ b/src/include01/utility.h @@ -61,6 +61,9 @@ bool fexist(const char* file); long fsize(const char* file); bool dexist(const char* file); bool is_dir(const char* file); +bool is_ftp(const char* file); +bool is_http(const char* file); +inline bool is_remote(const char* file) { return is_ftp(file) || is_http(file); } void log_message(const char* fmt, ...); const time_t atime(const char* file); // access time diff --git a/src/include01/xml.cpp b/src/include01/xml.cpp index 0b6545013..450224679 100644 --- a/src/include01/xml.cpp +++ b/src/include01/xml.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -126,73 +126,73 @@ HIDDEN void findbadseq(TString &str, istream& inf) if (str.starts_with("Agrave")) { str = str.smid(5); - str.insert("À"); + str.insert("À"); } else if (str.starts_with("Egrave")) { str = str.smid(5); - str.insert("È"); + str.insert("È"); } else if (str.starts_with("Eacuto")) { str = str.smid(5); - str.insert("É"); + str.insert("É"); } else if (str.starts_with("Igrave")) { str = str.smid(5); - str.insert("ÃŒ"); + str.insert("Ì"); } else if (str.starts_with("Ograve")) { str = str.smid(5); - str.insert("Ã’"); + str.insert("Ò"); } else if (str.starts_with("Ugrave")) { str = str.smid(5); - str.insert("Ù"); + str.insert("Ù"); } else if (str.starts_with("agrave")) { str = str.smid(5); - str.insert("à"); + str.insert("à"); } else if (str.starts_with("egrave")) { str = str.smid(5); - str.insert("è"); + str.insert("è"); } else if (str.starts_with("eacuto")) { str = str.smid(5); - str.insert("é"); + str.insert("é"); } else if (str.starts_with("igrave")) { str = str.smid(5); - str.insert("ì"); + str.insert("ì"); } else if (str.starts_with("ograve")) { str = str.smid(5); - str.insert("ò"); + str.insert("ò"); } else if (str.starts_with("ugrave")) { str = str.smid(5); - str.insert("ù"); + str.insert("ù"); } else if (str.starts_with("amp")) @@ -248,40 +248,40 @@ const TString& EscapeSequence(char cStart, istream& inf) str =" "; else if (str == "Agrave") - str ="À"; + str ="À"; else if (str == "Egrave") - str ="È"; + str ="È"; else if (str == "Eacuto") - str ="É"; + str ="É"; else if (str == "Igrave") - str ="ÃŒ"; + str ="Ì"; else if (str == "Ograve") - str ="Ã’"; + str ="Ò"; else if (str == "Ugrave") - str ="Ù"; + str ="Ù"; else if (str == "agrave") - str ="à"; + str ="à"; else if (str == "egrave") - str ="è"; + str ="è"; else if (str == "eacuto") - str ="é"; + str ="é"; else if (str == "igrave") - str ="ì"; + str ="ì"; else if (str == "ograve") - str ="ò"; + str ="ò"; else if (str == "ugrave") - str ="ù"; + str ="ù"; else if (str == "amp") str = "&"; @@ -343,40 +343,40 @@ void WriteXmlString(ostream& outf, const char* str) if (!cdata && c == '&') outf << "&"; else - if (!cdata && c == 'À') + if (!cdata && c == 'À') outf << "À"; else - if (!cdata && c == 'È') + if (!cdata && c == 'È') outf << "È"; else - if (!cdata && c == 'É') + if (!cdata && c == 'É') outf << "&Eacuto;"; else - if (!cdata && c == 'ÃŒ') + if (!cdata && c == 'Ì') outf << "Ì"; else - if (!cdata && c == 'Ã’') + if (!cdata && c == 'Ò') outf << "Ò"; else - if (!cdata && c == 'Ù') + if (!cdata && c == 'Ù') outf << "Ù"; else - if (!cdata && c == 'à') + if (!cdata && c == 'à') outf << "à"; else - if (!cdata && c == 'è') + if (!cdata && c == 'è') outf << "è"; else - if (!cdata && c == 'é') + if (!cdata && c == 'é') outf << "&eacuto;"; else - if (!cdata && c == 'ì') + if (!cdata && c == 'ì') outf << "ì"; else - if (!cdata && c == 'ò') + if (!cdata && c == 'ò') outf << "Ò"; else - if (!cdata && c == 'ù') + if (!cdata && c == 'ù') outf << "ù"; else if (!cdata && c == '\'') @@ -545,7 +545,7 @@ bool TXmlItem::GetWord(istream& inf, TString& str) const const bool bIsString = cFirstChar == '"' || cFirstChar == '\''; if (!bIsString) { - if (strchr("<=/>", cFirstChar) != NULL) + if (strchr("<=/>", cFirstChar) != nullptr) return true; // Simboli terminali if (cFirstChar == '&' && !_noescape) str = EscapeSequence(cFirstChar, inf); @@ -564,8 +564,15 @@ bool TXmlItem::GetWord(istream& inf, TString& str) const c = ' '; str << char(c); } - if (c == cFirstChar) - break; + if (c == cFirstChar || c == '<') + { + if (c == '<') + { + str.rtrim(1); + inf.putback(c); + } + break; + } } else { @@ -962,6 +969,8 @@ bool TXmlItem::GetEnclosedDate(const char* strAttr, TDate & d) const if (GetEnclosedText(strAttr, s)) { s.strip_spaces(); + while (s.len() > 8 && s.len() != 10) + s.rtrim(1); d = TDate(s); return true; } @@ -1454,20 +1463,22 @@ TXmlItem::TXmlItem(const TFilename & name, const char * strXmlHeader, const char : m_strXmlHeader(nullptr), m_strTag(15), m_strText(nullptr), m_Attributes(nullptr), m_Children(nullptr), _noescape(noescape) { + ifstream i(name); + const int size = fsize(name) + 512; + char * Buffer = new char[size]; + + i.rdbuf()->pubsetbuf(Buffer, size); SetXmlHeader(strXmlHeader); if (binary) - { - ifstream i(name); + { char c = i.get(); int count = 0; while (count++ < 120 && c != '<') c = i.get(); i.putback(c); - Read(i, strSkipTags); } - else - Read(name, strSkipTags); + Read(i, strSkipTags); } TXmlItem::~TXmlItem() @@ -1588,4 +1599,4 @@ const char * decode_xml(const char * filename, const char * key) o << line; } return get_tmp_string() = tmpfilename; -} \ No newline at end of file +}