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:
parent
b64e39b06b
commit
feb69c6dff
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
652
include/odbc.cpp
Executable 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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
498
include/xml.cpp
Executable 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
85
include/xml.h
Executable 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user