Patch level : 2.0 nopatch

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Aggiunti files per supporto ODBC via XML


git-svn-id: svn://10.65.10.50/trunk@11403 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2003-09-11 07:26:47 +00:00
parent b64e39b06b
commit feb69c6dff
9 changed files with 1257 additions and 998 deletions

View File

@ -14,13 +14,13 @@
*/
#ifdef CB6
#define XVT_INCL_NATIVE
#include <xvt.h>
#define S4OFF_REPORT
#ifdef CB6
#if XVT_OS == XVT_OS_WIN32
#define S4DLL
#define S4WIN32
@ -336,7 +336,7 @@ int DB_eof(int handle)
}
/*-------------------------------------------------------------------------
torna 1 se tof, 0 altrimenti
torna 1 se bof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_bof(int handle)
{
@ -1181,7 +1181,12 @@ int DB_memowrite( const int handle, const char * fieldname, const char * data )
return ret;
}
#else // CB6
#endif
#ifdef CB5
#define XVT_INCL_NATIVE
#include <xvt.h>
#if XVT_OS == XVT_OS_WIN32
#define S4DLL
@ -2441,4 +2446,4 @@ int DB_memowrite( const int handle, const char * fieldname, const char * data )
return ret;
}
#endif // CB6
#endif // CB5

View File

@ -796,8 +796,8 @@ void TControl::coord2rct(WINDOW win, short x, short y, short dx, short dy, RCT &
RCT max_rct; xvt_vobj_get_client_rect(win, &max_rct);
xi_pu_to_fu(itf, (XinPoint *)&max_rct, 2);
const int& MAXX = max_rct.right;
const int& MAXY = max_rct.bottom;
const int MAXX = max_rct.right;
const int MAXY = max_rct.bottom;
int width = XI_FU_MULTIPLE;
if (dx > 0)

View File

@ -2854,7 +2854,7 @@ void TRectype::write_memo(TIsam_handle file, const TRecnotype recno)
}
}
CHECK( recno > 0, "Maiale! Non fare le GO con _recno < 0 " );
CHECKD(recno >= 0, "Maiale! Non fare le GO con _recno < 0: ", recno);
TCodeb_handle cb_handle = prefix().get_handle(file);
DB_go( cb_handle, recno);
for( int i = _memo_data->last( ); i > 0; i = _memo_data->pred( i ) )
@ -3310,7 +3310,6 @@ void TRectype::zero(const char* fieldname)
}
void TRectype::zero(char c)
{
memset(_rec, c, len());
recall();
@ -3406,8 +3405,13 @@ void TRectype::renum_key(const char* field, const char* val)
// Certified 99%
TRectype& TRectype::operator =(const char* rec)
{
memcpy(_rec, rec, _length);
setempty(FALSE);
if (rec && * rec)
{
memcpy(_rec, rec, _length);
setempty(FALSE);
}
else
zero();
return *this;
}

652
include/odbc.cpp Executable file
View File

@ -0,0 +1,652 @@
#ifndef CB6
#include <xvt.h>
#include <codeb.h>
#include <config.h>
#include <diction.h>
#include <extcdecl.h>
#include <lffiles.h>
#include <netsock.h>
#include <prefix.h>
#include <xml.h>
#include <strstrea.h>
class TDB_table : public TObject
{
TString _study, _firm, _name;
int _logicnum;
int _mode, _index;
int _rec_len;
long _rec_count;
TString _query;
TString _query_name;
long _recno; // 0 = bof; 1 = first record; 2 second record
TXmlItem _record;
TString _record_buf, _key_buf;
protected:
void build_soap_method(const char* strMethod, TXmlItem& method) const;
int fill_record(const TXmlItem* res);
public:
virtual bool ok() const { return rec_len() > 0; }
int select_tag(int t);
int tag() const { return _index; }
int rec_len() const;
long rec_count() const;
bool bof() const { return _recno <= 0; }
bool eof() const { return _recno > rec_count(); }
char* get_record();
char* get_key();
long recno() const { return _recno; }
int go_to(long recno);
int skip_to(long recno, long offset);
int seek(const char* key);
TDB_table(const char* file, int mode, int index);
};
class TDB_manager : public TSocketClient
{
TString _server;
TArray _table;
int _error;
protected:
public:
TCodeb_handle open(const char* name, int mode, int index);
int close(TCodeb_handle h);
TDB_table& table(TCodeb_handle h) const;
int set_error(int e) { return _error = e; }
int get_error() const { return _error; }
TXmlItem* call_soap(const TXmlItem& method, TXmlItem& answer);
TDB_manager();
~TDB_manager();
};
static TDB_manager* _db = NULL;
///////////////////////////////////////////////////////////
// TDB_table
///////////////////////////////////////////////////////////
void TDB_table::build_soap_method(const char* strMethod, TXmlItem& method) const
{
CHECKS(strMethod[0] == 'm' && strMethod[1] == ':', "Missing m: in SOAP method", strMethod);
method.Destroy();
method.SetTag(strMethod);
method.AddSoapString("Study", _study);
method.AddSoapString("Firm", _firm);
method.AddSoapString("Table", _name);
method.AddSoapInt("Index", _index);
}
long TDB_table::rec_count() const
{
if (_rec_count <= 0)
{
TXmlItem method, answer;
build_soap_method("m:TableRows", method);
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
{
TString16 str;
res->GetEnclosedText(str);
(long&)_rec_count = atol(str);
}
}
return _rec_count;
}
int TDB_table::fill_record(const TXmlItem* res)
{
if (res != NULL)
{
const TXmlItem* rec = res->FindFirst("Record");
_recno = atol(rec->GetAttr("RecNo"));
if (_recno > _rec_count)
_rec_count = _recno;
const RecDes& rd = prefix().get_recdes(_logicnum);
TString16 name;
TString value;
for (int i = 0; i < rec->GetChildren(); i++)
{
const TXmlItem& fld = *rec->GetChild(i);
name = fld.GetAttr("Name"); name.upper();
const int index = findfld(&rd, name);
if (index != FIELDERR)
{
fld.GetEnclosedText(value);
switch (rd.Fd[index].TypeF)
{
case _boolfld:
value = value[0] == '1' ? "Y" : "N"; break;
case _intfld:
case _longfld:
case _intzerofld:
case _longzerofld:
value.right_just(rd.Fd[index].Len); break;
case _memofld:
value.cut(0); break;
default:
break;
}
_record_buf.overwrite(value, rd.Fd[index].RecOff);
}
}
return NOERR;
}
_recno = _rec_count*4+1; // EOF
return _db->set_error(5);
}
int TDB_table::go_to(long recno)
{
if (recno == _recno)
return NOERR;
TXmlItem method;
build_soap_method("m:GetRecord", method);
method.AddSoapInt("RecNo", recno);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
}
int TDB_table::skip_to(long recno, long offset)
{
TXmlItem method;
build_soap_method("m:SkipRecord", method);
method.AddSoapInt("RecNo", recno);
method.AddSoapInt("Offset", offset);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
}
char* TDB_table::get_record()
{
return _record_buf.get_buffer();
}
char* TDB_table::get_key()
{
_key_buf.cut(0);
if (_logicnum > 0 && _index > 0 && _recno > 0 && _recno <= rec_count())
{
const TXmlItem* rec = _record.FindFirst("Record");
if (rec != NULL)
{
const RecDes& rd = prefix().get_recdes(_logicnum);
const KeyDes& kd = rd.Ky[_index-1]; // Elenco dei campi della chiave
TString str;
for (int i = 0; i < kd.NkFields; i++)
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = rd.Fd[nf];
for (int i = 0; i < rec->GetChildren(); i++)
{
const TXmlItem& fld = *rec->GetChild(i);
if (fld.GetAttr("Name").compare(rf.Name, -1, true) == 0)
{
fld.GetEnclosedText(str);
switch (rf.TypeF)
{
case _intfld:
case _longfld:
case _intzerofld:
case _longzerofld:
str.right_just(rf.Len); break;
default:
str.rpad(rf.Len); break;
}
_key_buf << str;
break;
}
}
}
}
}
return _key_buf.get_buffer();
}
int TDB_table::seek(const char* key)
{
/*
TXmlItem method;
build_soap_method("m:SeekRecord", method);
method.AddSoapString("Key", key);
const TXmlItem* res = _db->call_soap(method, _record);
return fill_record(res);
*/
return skip_to(0, 0);
}
int TDB_table::rec_len() const
{
if (_rec_len <= 0)
{
TXmlItem method, answer;
build_soap_method("m:GetRecordLength", method);
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
{
TString16 str;
if (res->GetEnclosedText(str))
(int&)_rec_len = atoi(str)+1; // Add deleted flag (1 byte)
}
}
return _rec_len;
}
int TDB_table::select_tag(int t)
{
int err = NOERR;
if (t != _index)
{
_index = t;
if (ok())
{
TXmlItem method, answer;
build_soap_method("m:CreateIndex", method);
const RecDes& rd = prefix().get_recdes(_logicnum);
const KeyDes& kd = rd.Ky[_index-1]; // Elenco dei campi della chiave
for (int i = 0; i < kd.NkFields; i++)
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = rd.Fd[nf];
TXmlItem& fld = method.AddChild("Field");
fld.SetAttr("Name", rf.Name);
if (kd.FieldSeq[i] >= MaxFields)
fld.SetAttr("Upper", "1");
}
TString16 str;
const TXmlItem* res = _db->call_soap(method, answer);
if (res != NULL)
res->GetEnclosedText(str);
if (str != "1")
err = _db->set_error(883); // ???
}
}
return err;
}
TDB_table::TDB_table(const char* file, int mode, int index)
: _mode(mode), _index(index), _recno(-1), _rec_count(-1), _rec_len(-1), _logicnum(0)
{
TToken_string tok(file, '/' );
const int dot = tok.rfind('.');
if (dot > 0) tok.cut(dot);
tok.replace('\\', '/');
tok.upper();
const int items = tok.items();
tok.get(items-1, _name);
tok.get(items-2, _firm);
tok.get(items-3, _study);
FileDes filedes;
memset(&filedes, 0, sizeof(filedes));
for (int i = LF_USER; i < 100; i++)
{
CGetFile(i, &filedes, _nolock, _nordir);
if (_name.compare(filedes.SysName+1, -1, true) == 0)
{
_logicnum = i;
break;
}
}
}
///////////////////////////////////////////////////////////
// TDB_manager
///////////////////////////////////////////////////////////
TCodeb_handle TDB_manager::open(const char* name, int mode, int index)
{
TCodeb_handle h = -1; // Inizializzo handle non valido
// Crea tabella
TDB_table* t = new TDB_table(name, mode, index);
if (t->ok())
{
// Cerca primo handle disponibile
for (h = 0; _table.objptr(h) != NULL; h++);
_table.add(t, h);
}
else
delete t;
return h;
}
int TDB_manager::close(TCodeb_handle h)
{
const int err = _table.destroy(h) ? 0 : 2;
return err;
}
TDB_table& TDB_manager::table(TCodeb_handle h) const
{
TDB_table* t = (TDB_table*)_table.objptr(h);
CHECKD(t != NULL, "Invalid TABLE handle ", h);
return *t;
}
TXmlItem* TDB_manager::call_soap(const TXmlItem& method, TXmlItem& answer)
{
TXmlItem* result = NULL;
CONNID conn = 0;
for (int i = 0; conn == 0 && i < 5; i++)
conn = QueryConnection("", _server);
if (conn != 0)
{
TString str(8192);
method.AsString(str);
if (HttpSoap(conn, str))
{
size_t size;
char* buf = (char*)GetBuffer(size);
istrstream inf(buf, size);
if (answer.Read(inf))
{
str = method.GetTag();
str << "Result";
result = answer.FindFirst(str);
}
}
else
error_box(FR("Impossible eseguire '%s' sul soap server '%s'"),
(const char*)method.GetTag(), (const char*)_server);
RemoveConnection(conn);
}
else
error_box(FR("Impossible connettersi al soap server '%s'"), (const char*)_server);
return result;
}
TDB_manager::TDB_manager()
{
TConfig ini(CONFIG_INSTALL, "Server");
_server = ini.get("DataBase", NULL, -1, "127.0.0.1:3885");
}
TDB_manager::~TDB_manager()
{ }
///////////////////////////////////////////////////////////
// codeb.h implementation
///////////////////////////////////////////////////////////
void DB_init(void)
{
DB_exit();
_db = new TDB_manager();
}
void DB_exit(void)
{
if (_db != NULL)
{
delete _db;
_db = NULL;
}
}
TCodeb_handle DB_open(const char *filename, int mode, int index)
{
return _db->open(filename, mode, index);
}
int DB_close(TCodeb_handle handle)
{
return _db->close(handle);
}
char* DB_getrecord(int handle)
{
return _db->table(handle).get_record();
}
int DB_reclen(int handle)
{
return _db->table(handle).rec_len();
}
int DB_keylen(int handle)
{
return 0;
}
long DB_recno(int handle)
{
return _db->table(handle).recno();
}
long int DB_reccount(int handle)
{
return _db->table(handle).rec_count();
}
int DB_tagselect(int handle,int index_no)
{
return _db->table(handle).select_tag(index_no);
}
int DB_tagget(int handle)
{
return _db->table(handle).tag();
}
int DB_first(int handle)
{
return _db->table(handle).skip_to(0, 0);
}
int DB_last(int handle)
{
return _db->table(handle).skip_to(-1, 0);
}
int DB_next(int handle)
{
return DB_skip(handle, +1);
}
int DB_prev(int handle)
{
return DB_skip(handle, -1);
}
int DB_skip(int handle,long offset)
{
TDB_table& tab = _db->table(handle);
return tab.skip_to(tab.recno(), offset);
}
int DB_lock(int handle)
{
return 0;
}
int DB_unlock(int handle)
{
return 0;
}
int DB_seek(int handle,char *key)
{
return _db->table(handle).seek(key);
}
int DB_eof(int handle)
{
return _db->table(handle).eof();
}
int DB_bof(int handle)
{
return _db->table(handle).bof();
}
int DB_go(int handle,long recno)
{
return _db->table(handle).go_to(recno);
}
int DB_delete(int handle)
{
return 0;
}
int DB_recall(int handle)
{
return 0;
}
int DB_delkey(int handle, char* key, long recno)
{
return 0;
}
int DB_flush(int handle)
{
return 0;
}
int DB_rewrite(int handle)
{
return 0;
}
bool DB_has_memo(int handle)
{
return false;
}
int DB_add(int handle)
{
return 0;
}
int DB_lockfile(int handle)
{
return 0;
}
int DB_packfile(short vis, const char * filename, long eod)
{
return 0;
}
int DB_packmemo(short vis, const char * filename)
{
return 0;
}
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask )
{
return 0;
}
int DB_build(const char * filename, RecDes *r)
{
return 0;
}
int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys)
{
return 0;
}
int DB_get_error(void)
{
return _db->get_error();
}
void DB_zero_error(void)
{
_db->set_error(0);
}
int DB_index_seek(int handle, char* from)
{
return DB_seek(handle, from);
}
long DB_index_recno(int handle)
{
return DB_recno(handle);
}
long DB_index_next(int handle)
{
return DB_next(handle);
}
char* DB_index_getkey(int handle)
{
return _db->table(handle).get_key();
}
int DB_index_go(int handle, const char * key, long recno)
{
return DB_go(handle, recno);
}
char* DB_memoptr(const int handle, const char * fieldname )
{
return 0;
}
int DB_memowrite(const int handle, const char * fieldname, const char * data )
{
return 0;
}
int DB_index_eof(int handle)
{
return DB_eof(handle);
}
int DB_lock_rec(int handle,long nrec)
{
return 0;
}
int DB_file_locked(int handle)
{
return 0;
}
int DB_rec_locked(int handle,long nrec)
{
return 0;
}
long DB_getconf()
{
return 0;
}
long DB_changed(int handle)
{
return 0;
}
#endif

View File

@ -1,566 +0,0 @@
#include <wx/wx.h>
#include <wx/db.h>
#include <wx/mstream.h>
#include <codeb.h>
///////////////////////////////////////////////////////////
// TDataBase
///////////////////////////////////////////////////////////
class TDataBase
{
wxDbConnectInf m_ci;
wxDb* m_db;
public:
bool Open(const wxString& dsn, const wxString& user,
const wxString& password, const wxString& path);
bool IsOpen() const;
void Close();
wxDb& DataBase() { return *m_db; }
TDataBase();
virtual ~TDataBase();
};
bool TDataBase::Open(const wxString& dsn, const wxString& user,
const wxString& password, const wxString& path)
{
Close();
m_ci.SetDsn(dsn);
m_ci.SetUserID(user);
m_ci.SetPassword(password);
m_ci.SetDefaultDir(path);
if (m_ci.AllocHenv())
{
m_db = ::wxDbGetConnection(&m_ci, false); // Forward only?
if (m_db == NULL)
m_ci.FreeHenv();
}
return IsOpen();
}
void TDataBase::Close()
{
if (m_db)
{
m_db->SetSqlLogging(sqlLogOFF);
::wxDbFreeConnection(m_db);
m_db = NULL;
m_ci.FreeHenv();
}
}
bool TDataBase::IsOpen() const
{
return m_db != NULL;
}
TDataBase::TDataBase(), m_db(NULL)
{
m_ci.Henv = 0;
DeleteContents(true);
}
TDataBase::~TDataBase()
{
Close();
}
///////////////////////////////////////////////////////////
// TDataBaseList
///////////////////////////////////////////////////////////
class TDataBaseList : public wxHashTable
{
wxString m_strUser, m_strPassword;
protected:
wxString& User();
wxString& Password();
public:
TDataBase& db(const wxString& path);
TDataBaseList() : wxHashTable(wxKEY_STRING) { }
};
static DataBaseList theDataBaseList;
wxString& TDataBaseList::User()
{
if (m_strUser.IsEmpty())
{
// TBI Read user and password
}
return m_strUser;
}
wxString& TDataBaseList::Password()
{
if (m_strPassword.Isempty())
User(); // Initialize both User and Password
return m_strPassword;
}
wxString& TDataBaseList::Dsn(const wxString& dbpath)
{
wxString study;
long firm = -1;
for (int i = dbpath.GetLength()-1; i >= 0; i--)
if (dbpath[i] == '\\' || dbpath[i] == '/')
{
firm = atol(dbpath.Mid(i+1));
break;
}
for (int j = i-1; j >= 0; j--)
if (dbpath[j] == '\\' || dbpath[j] == '/')
{
study = dbpath.Mid(j+1, i-j);
break;
}
wxString dsn = study;
if (firm > 0)
dsn << firm;
return dsn;
}
TDataBase& TDataBaseList::db(const wxString& dbpath)
{
wxString dsn = Dsn(dbpath);
TDataBase* d = (TDataBase*)Get(dsn);
if (d == NULL)
{
d = new TDataBase;
Put(dsn, d);
bool ok = d->Open(dsn, User(), Password(), dbpath);
if (!ok)
{
wxString msg = wxString::Format("L'utente %s non è abilitato all'uso del database %s\n"
"corrispondente agli archivi in %s",
User(), dsn, dbpath);
wxMessageBox(msg, "Errore");
exit(0);
}
}
return *d;
}
/*--------------------------------------------------------------------------
inizializzazione di CodeBase e delle variabili necessarie
questa funzione deve essere chiamata SOLO una volta all'interno
di ciascun eseguibile
--------------------------------------------------------------------------*/
void DB_init(void)
{
}
/*--------------------------------------------------------------------------
reset di CodeBase
questa funzione dovrebbe essere chiamata prima di uscire da un eseguibile
per una questione di correttezza formale. Non usandola comunque non acca-
de niente di drammatico
--------------------------------------------------------------------------*/
void DB_exit(void)
{
::wxDbCloseConnections();
}
/*-------------------------------------------------------------------------
apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura
esclusiva. Il parametro index consente se == 0 l'apertura senza indici.
Ritorna l'handle del file aperto oppure -1 in caso di errore
--------------------------------------------------------------------------*/
int DB_open(const char *filename,int mode,int index)
{
return -1;
}
/*-------------------------------------------------------------------------
chiusura del database inviduato da handle
torna -1 se il database non puo essere chiuso, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_close(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
torna il puntatore al buffer del record del database individuato da
handle. In caso di errore torna (char *) 0
--------------------------------------------------------------------------*/
char *DB_getrecord(int handle)
{
return NULL;
}
/*-------------------------------------------------------------------------
torna la lunghezza del record
--------------------------------------------------------------------------*/
int DB_reclen(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna la lunghezza della chiave corrente
--------------------------------------------------------------------------*/
int DB_keylen(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
torna il numero del record attuale
--------------------------------------------------------------------------*/
long int DB_recno(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna il numero complessivo dei records presenti nell'archivio
--------------------------------------------------------------------------*/
long int DB_reccount(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
seleziona un indice sul database specificato
torna -1 se errore, altrimenti 0
--------------------------------------------------------------------------*/
int DB_tagselect(int handle,int index_no)
{
return -1;
}
/*-------------------------------------------------------------------------
torna il numero dell'indice selezionato
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_tagget(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
si posiziona sul primo record
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_first(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
si posiziona sull'ultimorecord
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_last(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip avanti di un record
--------------------------------------------------------------------------*/
int DB_next(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip indietro di un record
--------------------------------------------------------------------------*/
int DB_prev(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip di n records
--------------------------------------------------------------------------*/
int DB_skip(int handle,long int recno)
{
return -1;
}
/*-------------------------------------------------------------------------
locka il record attuale
--------------------------------------------------------------------------*/
int DB_lock(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
slocka il record attuale
--------------------------------------------------------------------------*/
int DB_unlock(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
cerca la chiave, torna r4after se not found ma si e' posizionato sul record
successivo, se torna r4eof e' su eof
--------------------------------------------------------------------------*/
int DB_seek(int handle,char *key)
{
return -1;
}
/*-------------------------------------------------------------------------
torna 1 se eof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_eof(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna 1 se tof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_bof(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
legge un record per numero record
--------------------------------------------------------------------------*/
int DB_go(int handle,long recno)
{
return -1;
}
/*-------------------------------------------------------------------------
cancella il record attuale. Non cancella le chiavi.
--------------------------------------------------------------------------*/
int DB_delete(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
ripristina il record attuale
--------------------------------------------------------------------------*/
int DB_recall(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
--------------------------------------------------------------------------*/
int DB_flush(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
riscrive il record attuale
--------------------------------------------------------------------------*/
int DB_rewrite(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
appende il record attuale
--------------------------------------------------------------------------*/
int DB_add(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
Blocca in modo esclusivo il file dati ed indice
--------------------------------------------------------------------------*/
int DB_lockfile(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
Compatta il file dati
--------------------------------------------------------------------------*/
int DB_packfile(short vis, const char * filename, long eod)
{
return 0;
}
/*-------------------------------------------------------------------------
Compatta il file memo
--------------------------------------------------------------------------*/
int DB_packmemo(short vis, const char * filename)
{
return 0;
}
/*-------------------------------------------------------------------------
Elimina i record duplicati
--------------------------------------------------------------------------*/
int DB_clean_file(int handle, char * filename, char * ff, RecDes * r, short vis)
{
return -1;
}
/*-------------------------------------------------------------------------
Compatta gli indici
--------------------------------------------------------------------------*/
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask)
{
return 0;
}
/*-------------------------------------------------------------------------
costruisce il file filename
--------------------------------------------------------------------------*/
int DB_build(const char * filename, RecDes *r)
{
return -1;
}
/*-------------------------------------------------------------------------
reperisce il tracciato record e la stringa di definizione delle chiavi
Stringa di definizione chiavi:
expression1|unique1$expression2|unique2$expression3|unique3
--------------------------------------------------------------------------*/
int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys)
{
return -1;
}
/*-------------------------------------------------------------------------
ritorna l'ultimo errore
--------------------------------------------------------------------------*/
int DB_get_error(void)
{
return 0;
}
/*-------------------------------------------------------------------------
Azzera la viarabile globale d'errore
--------------------------------------------------------------------------*/
void DB_zero_error(void)
{
}
/*-------------------------------------------------------------------------
Si posiziona sull'indice attivo alla chiave indicata, restituisce
la prima chiave che trova >= a from. (TCursor)
--------------------------------------------------------------------------*/
int DB_index_seek(int handle, char* from)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna il numero di record corrispondente alla chiave corrente
--------------------------------------------------------------------------*/
long DB_index_recno(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Si posiziona sulla chiave successiva dell'indice corrente
--------------------------------------------------------------------------*/
long DB_index_next(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Restituisce la chiave corrente
--------------------------------------------------------------------------*/
char* DB_index_getkey(int handle)
{
return NULL;
}
/*-------------------------------------------------------------------------
Restituisce vero se l'indice e' alla fine
--------------------------------------------------------------------------*/
int DB_index_eof(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Blocca il record indicato
--------------------------------------------------------------------------*/
int DB_lock_rec(int handle,long nrec)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna vero(non zero) se il file dati od indice sono stati bloccati
in modo esclusivo dalla presente applicazione, non da altri programmi!!!
--------------------------------------------------------------------------*/
int DB_file_locked(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna vero se il record nrec e' bloccato dalla presente applicazione,
non da altri programmi!!!
--------------------------------------------------------------------------*/
int DB_rec_locked(int handle,long nrec)
{
return 0;
}
/*-------------------------------------------------------------------------
restituisce la configurazione della libreria
--------------------------------------------------------------------------*/
long DB_getconf()
{
return 0;
}
/*-------------------------------------------------------------------------
Restituisce il numero di versione scritto sull'header dell'indice
--------------------------------------------------------------------------*/
long DB_changed(int handle)
{
return 0;
}
char* DB_memoptr( const int handle, const char * fieldname )
{
return NULL;
}
int DB_memowrite( const int handle, const char * fieldname, const char * data )
{
return NULL;
}

View File

@ -1,419 +0,0 @@
#include <codeb.h>
#define MAXLEN 137 /* Lunghezza massima chiave */
/*--------------------------------------------------------------------------
inizializzazione di CodeBase e delle variabili necessarie
questa funzione deve essere chiamata SOLO una volta all'interno
di ciascun eseguibile
--------------------------------------------------------------------------*/
void DB_init(void)
{
}
/*--------------------------------------------------------------------------
reset di CodeBase
questa funzione dovrebbe essere chiamata prima di uscire da un eseguibile
per una questione di correttezza formale. Non usandola comunque non acca-
de niente di drammatico
--------------------------------------------------------------------------*/
void DB_exit(void)
{
}
/*-------------------------------------------------------------------------
apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura
esclusiva. Il parametro index consente se == 0 l'apertura senza indici.
Ritorna l'handle del file aperto oppure -1 in caso di errore
--------------------------------------------------------------------------*/
int DB_open(const char *filename,int mode,int index)
{
return -1;
}
/*-------------------------------------------------------------------------
chiusura del database inviduato da handle
torna -1 se il database non puo essere chiuso, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_close(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
torna il puntatore al buffer del record del database individuato da
handle. In caso di errore torna (char *) 0
--------------------------------------------------------------------------*/
char *DB_getrecord(int handle)
{
return NULL;
}
/*-------------------------------------------------------------------------
torna la lunghezza del record
--------------------------------------------------------------------------*/
int DB_reclen(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna la lunghezza della chiave corrente
--------------------------------------------------------------------------*/
int DB_keylen(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
torna il numero del record attuale
--------------------------------------------------------------------------*/
long int DB_recno(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna il numero complessivo dei records presenti nell'archivio
--------------------------------------------------------------------------*/
long int DB_reccount(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
seleziona un indice sul database specificato
torna -1 se errore, altrimenti 0
--------------------------------------------------------------------------*/
int DB_tagselect(int handle,int index_no)
{
return -1;
}
/*-------------------------------------------------------------------------
torna il numero dell'indice selezionato
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_tagget(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
si posiziona sul primo record
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_first(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
si posiziona sull'ultimorecord
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_last(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip avanti di un record
--------------------------------------------------------------------------*/
int DB_next(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip indietro di un record
--------------------------------------------------------------------------*/
int DB_prev(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
skip di n records
--------------------------------------------------------------------------*/
int DB_skip(int handle,long int recno)
{
return -1;
}
/*-------------------------------------------------------------------------
locka il record attuale
--------------------------------------------------------------------------*/
int DB_lock(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
slocka il record attuale
--------------------------------------------------------------------------*/
int DB_unlock(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
cerca la chiave, torna r4after se not found ma si e' posizionato sul record
successivo, se torna r4eof e' su eof
--------------------------------------------------------------------------*/
int DB_seek(int handle,char *key)
{
return r4eof;
}
/*-------------------------------------------------------------------------
torna 1 se eof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_eof(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
torna 1 se tof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_bof(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
legge un record per numero record
--------------------------------------------------------------------------*/
int DB_go(int handle,long recno)
{
return -1;
}
/*-------------------------------------------------------------------------
cancella il record attuale. Non cancella le chiavi.
--------------------------------------------------------------------------*/
int DB_delete(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
ripristina il record attuale
--------------------------------------------------------------------------*/
int DB_recall(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
--------------------------------------------------------------------------*/
int DB_flush(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
riscrive il record attuale
--------------------------------------------------------------------------*/
int DB_rewrite(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
appende il record attuale
--------------------------------------------------------------------------*/
int DB_add(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
Blocca in modo esclusivo il file dati ed indice
--------------------------------------------------------------------------*/
int DB_lockfile(int handle)
{
return -1;
}
/*-------------------------------------------------------------------------
Compatta il file dati
--------------------------------------------------------------------------*/
int DB_packfile(short vis, const char * filename, long eod)
{
return 0;
}
/*-------------------------------------------------------------------------
Compatta il file memo
--------------------------------------------------------------------------*/
int DB_packmemo(short vis, const char * filename)
{
return 0;
}
/*-------------------------------------------------------------------------
Elimina i record duplicati
--------------------------------------------------------------------------*/
int DB_clean_file(int handle, char * filename, char * ff, RecDes * r, short vis)
{
return -1;
}
/*-------------------------------------------------------------------------
Compatta gli indici
--------------------------------------------------------------------------*/
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask)
{
return 0;
}
/*-------------------------------------------------------------------------
costruisce il file filename
--------------------------------------------------------------------------*/
int DB_build(const char * filename, RecDes *r)
{
return -1;
}
/*-------------------------------------------------------------------------
reperisce il tracciato record e la stringa di definizione delle chiavi
Stringa di definizione chiavi:
expression1|unique1$expression2|unique2$expression3|unique3
--------------------------------------------------------------------------*/
int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys)
{
return -1
}
/*-------------------------------------------------------------------------
ritorna l'ultimo errore
--------------------------------------------------------------------------*/
int DB_get_error(void)
{
return 0
}
/*-------------------------------------------------------------------------
Azzera la viarabile globale d'errore
--------------------------------------------------------------------------*/
void DB_zero_error(void)
{
}
/*-------------------------------------------------------------------------
Si posiziona sull'indice attivo alla chiave indicata, restituisce
la prima chiave che trova >= a from. (TCursor)
--------------------------------------------------------------------------*/
int DB_index_seek(int handle, char* from)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna il numero di record corrispondente alla chiave corrente
--------------------------------------------------------------------------*/
long DB_index_recno(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Si posiziona sulla chiave successiva dell'indice corrente
--------------------------------------------------------------------------*/
long DB_index_next(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Restituisce la chiave corrente
--------------------------------------------------------------------------*/
char* DB_index_getkey(int handle)
{
return NULL;
}
/*-------------------------------------------------------------------------
Restituisce vero se l'indice e' alla fine
--------------------------------------------------------------------------*/
int DB_index_eof(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Blocca il record indicato
--------------------------------------------------------------------------*/
int DB_lock_rec(int handle,long nrec)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna vero(non zero) se il file dati od indice sono stati bloccati
in modo esclusivo dalla presente applicazione, non da altri programmi!!!
--------------------------------------------------------------------------*/
int DB_file_locked(int handle)
{
return 0;
}
/*-------------------------------------------------------------------------
Ritorna vero se il record nrec e' bloccato dalla presente applicazione,
non da altri programmi!!!
--------------------------------------------------------------------------*/
int DB_rec_locked(int handle,long nrec)
{
return 0;
}
/*-------------------------------------------------------------------------
restituisce la configurazione della libreria
--------------------------------------------------------------------------*/
long DB_getconf()
{
return 0;
}
/*-------------------------------------------------------------------------
Restituisce il numero di versione scritto sull'header dell'indice
--------------------------------------------------------------------------*/
long DB_changed(int handle)
{
return 0;
}
char* DB_memoptr( const int handle, const char * fieldname )
{
return NULL;
}
int DB_memowrite( const int handle, const char * fieldname, const char * data )
{
return NULL;
}

View File

@ -1022,7 +1022,7 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
if (DB_reccount(fhnd) == 0)
return 0;
TRecnotype oldrecno=0,ap = 0;
TRecnotype oldrecno= RECORD_NON_FISICO,ap = 0;
int pagecnt = 0;
FILE* indf = NULL;
@ -1031,7 +1031,7 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
if (junk < 0) junk=get_error(junk);
if (junk == _iseof) return 0;
DB_index_recno(fhnd);
// DB_index_recno(fhnd); // A cosa cavolo serve?
_pos=-1;
const bool filtered = has_filter();

498
include/xml.cpp Executable file
View File

@ -0,0 +1,498 @@
#include "real.h"
#include "xml.h"
#include <fstream.h>
#include <strstrea.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 (real::is_real(*this))
{
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::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(15), 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;
}

85
include/xml.h Executable file
View File

@ -0,0 +1,85 @@
#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;
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