/*************************************************************************** cfg.cpp - description ------------------- begin : Sun Mar 10 2002 copyright : (C) 2002 by Vladimir Shutoff email : vovan@shutoff.ru ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sockfactory.h" #include "socket.h" #include "log.h" #include "misc.h" // sprintf #include #include #ifdef WIN32 #include #else #include #include #include #include #include #include #include #endif #include #include #include #include #include #include #ifdef _DEBUG # include #endif #ifdef USE_KDE #include #include #include #include "kdeisversion.h" #endif namespace SIM { void save_state() { EventSaveState e; e.process(); } // ______________________________________________________________________________________ #ifdef WIN32 EXPORT bool makedir(const QString &p) { QDir path; if(p.endsWith("/") || p.endsWith("\\")) { QFileInfo fi(p + "dummy.txt"); path = fi.dir(true); } else { QFileInfo fi(p); path = fi.dir(true); } if(path.exists()) return true; QString r = QDir::convertSeparators(path.absPath()); SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; ZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; if(QApplication::winVersion()&Qt::WV_NT_based){ InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); sa.lpSecurityDescriptor = &sd; } CreateDirectoryW((LPCWSTR)p.ucs2(), &sa); DWORD dwAttr = GetFileAttributesW((LPCWSTR)p.ucs2()); if (dwAttr & FILE_ATTRIBUTE_READONLY) SetFileAttributesW((LPCWSTR)p.ucs2(), dwAttr & ~FILE_ATTRIBUTE_READONLY); return true; } #else EXPORT bool makedir(const QString &p) { QDir path; if(p.endsWith("/") || p.endsWith("\\")) { QFileInfo fi(p + "dummy.txt"); path = fi.dir(true); } else { QFileInfo fi(p); path = fi.dir(true); } if(path.exists()) return true; QString r = QDir::convertSeparators(path.absPath()); struct stat st; if (stat(QFile::encodeName(r).data(), &st) != 0){ int idx = r.findRev('/'); if(idx == -1) return false; if (makedir(r.left(idx))){ if (mkdir(QFile::encodeName(r).data(), 0700)){ log(L_ERROR, "Can't create %s: %s", QFile::encodeName(r).data(), strerror(errno)); return false; } } return false; } if ((st.st_mode & S_IFMT) != S_IFDIR){ log(L_ERROR, "%s no directory", p.local8Bit().data()); return false; } return true; } #endif EXPORT QString app_file(const QString &f) { QString app_file_name; QString fname = f; #if defined( WIN32 ) || defined( __OS2__ ) if ((fname[1] == ':') || (fname.left(2) == "\\\\")) return f; WCHAR buff[MAX_PATH]; #ifdef __OS2__ PPIB pib; PTIB tib; DosGetInfoBlocks(&tib, &pib); DosQueryModuleName(pib->pib_hmte, sizeof(buff), buff); #else GetModuleFileNameW(NULL, buff, MAX_PATH); #endif QString b = QString::fromUcs2((unsigned short*)buff); int idx = b.findRev('\\'); if(idx != -1) b = b.left(idx+1); app_file_name = b; if (app_file_name.length() && (app_file_name.right(1) != "\\") && (app_file_name.right(1) != "/")) app_file_name += '\\'; #else if (fname[0] == '/') return f; #ifdef USE_KDE if (qApp){ QStringList lst = KGlobal::dirs()->findDirs("data", "sim"); for (QStringList::Iterator it = lst.begin(); it != lst.end(); ++it){ QFile fi(*it + f); if (fi.exists()){ app_file_name = QDir::convertSeparators(fi.name()); return app_file_name; } } } #endif #ifndef __OS2__ app_file_name = PREFIX "/share/apps/sim/"; #endif #endif app_file_name += f; return QDir::convertSeparators(app_file_name); } // ______________________________________________________________________________________ EXPORT QString user_file(const QString &f) { QString res = f; EventHomeDir e(f); if (e.process()) return e.homeDir(); return app_file(f); } // ______________________________________________________________________________________ char fromHex(char c) { if ((c >= '0') && (c <= '9')) return (char)(c - '0'); if ((c >= 'A') && (c <= 'F')) return (char)(c + 10 - 'A'); if ((c >= 'a') && (c <= 'f')) return (char)(c + 10 - 'a'); return (char)0; } static unsigned char toHex(unsigned char c) { c &= 0x0F; if (c < 10) return (unsigned char)(c + '0'); return (unsigned char)(c - 10 + 'a'); } QString quoteChars(const QString &from, const char *chars, bool bQuoteSlash) { QString res; QString quote_chars; quote_chars = chars; if (bQuoteSlash) { quote_chars += '\\'; } for (int i = 0; i < (int) (from.length ()); i++) { QChar c = from[i]; if (quote_chars.contains (c)) { res += '\\'; } res += c; } return res; } EXPORT QString getToken(QString &from, char c, bool bUnEscape) { QString res; int i; for (i = 0; i < (int)from.length(); i++){ if (from[i] == c) break; if (from[i] == '\\'){ i++; if (i >= (int)from.length()) break; if (!bUnEscape) res += '\\'; } res += from[i]; } if (i < (int)from.length()){ from = from.mid(i + 1); }else{ from = QString::null; } return res; } EXPORT QCString getToken(QCString &from, char c, bool bUnEscape) { QCString res; int i; for (i = 0; i < (int)from.length(); i++){ if (from[i] == c) break; if (from[i] == '\\'){ i++; if (i >= (int)from.length()) break; if (!bUnEscape) res += '\\'; } res += from[i]; } if (i < (int)from.length()){ from = from.mid(i + 1); }else{ from = QCString(); } return res; } // _______________________________________________________________________________________ bool set_ip(Data *p, unsigned long value, const QString &host) { IP *ip = p->ip(); if (value == 0){ if (ip == NULL) return false; delete ip; p->clear(); return true; } if (ip == NULL) ip = new IP; p->setIP(ip); if (ip->ip() == value){ if (host.isEmpty()) ip->resolve(); return false; } ip->set(value, host); return true; } unsigned long get_ip(const Data &p) { const IP *ip = p.ip(); if (ip) return ip->ip(); return 0; } QString get_host(const Data &p) { const IP *ip = p.ip(); return ip ? ip->host() : QString::null; } // _______________________________________________________________________________________ EXPORT const QString &get_str(const Data &d, unsigned index) { const Data::STRING_MAP &sm = d.strMap(); Data::STRING_MAP::const_iterator it = sm.find(index); if(it != sm.end()) return it.data(); return QString::null; } EXPORT void set_str(Data *d, unsigned index, const QString &value) { Data::STRING_MAP &sm = d->strMap(); sm.replace(index, value); } // _______________________________________________________________________________________ EXPORT void free_data(const DataDef *def, void *d) { Data *data = (Data*)d; for (; def->name; def++){ unsigned type = def->type; for (unsigned i = 0; i < def->n_values; i++, data++){ switch (type){ case DATA_OBJECT: delete data->object(); data->clear(); break; case DATA_IP: delete data->ip(); data->clear(); break; case DATA_STRUCT: free_data((DataDef*)(def->def_value), data); i += (def->n_values - 1); data += (def->n_values - 1); break; default: data->clear(); break; } } } } void init_data(const DataDef *d, Data *data) { for (const DataDef *def = d; def->name; def++){ for (unsigned i = 0; i < def->n_values; i++, data++){ data->clear(); data->setName(def->name); data->setType(def->type); switch (def->type){ case DATA_STRING: // when all our sources are utf-8, use QString::fromUtf8() here! data->str() = def->def_value ? QString(def->def_value) : QString::null; break; case DATA_CSTRING: // when all our sources are utf-8, use QString::fromUtf8() here! data->cstr() = def->def_value ? QCString(def->def_value) : ""; break; case DATA_STRLIST: { // this breaks on non latin1 defaults! QStringList sl = QStringList::split(',',def->def_value); Data::STRING_MAP sm; for(unsigned i = 0; i < sl.count(); i++) { sm.insert(i, sm[(int)i]); } data->strMap() = sm; } case DATA_UTF: if (def->def_value){ data->str() = i18n(def->def_value); } break; case DATA_ULONG: data->asULong() = (unsigned long)(def->def_value); break; case DATA_LONG: data->asLong() = (long)(def->def_value); break; case DATA_BOOL: data->asBool() = (def->def_value != NULL); break; case DATA_OBJECT: data->setObject(NULL); break; case DATA_IP: data->setIP(NULL); break; case DATA_BINARY: data->asBinary() = QByteArray(); break; case DATA_STRUCT: init_data((DataDef*)(def->def_value), data); data += (def->n_values - 1); i += (def->n_values - 1); break; default: break; } } } } const DataDef *find_key(const DataDef *def, const char *name, unsigned &offs) { for (; def->name; def++){ if (!strcmp(def->name, name)) return def; if (def->type == DATA_STRUCT){ unsigned save_offs = offs; const DataDef *res = find_key((DataDef*)(def->def_value), name, offs); if (res) return res; offs = save_offs; } offs += def->n_values; } return NULL; } static QCString quoteInternal(const QCString &str) { QCString res("\""); if (!str.isEmpty()){ for (unsigned i = 0; i < str.length(); i++){ unsigned char p = str[(int)i]; switch (p){ case '\\': res += "\\\\"; break; case '\r': break; case '\n': res += "\\n"; break; case '\"': { res += "\\x"; res += toHex((unsigned char)(p >> 4)); res += toHex(p); break; } default: if (p >= ' '){ res += p; }else if (p){ res += "\\x"; res += toHex((unsigned char)(p >> 4)); res += toHex(p); } } } } res += '\"'; return res; } static bool unquoteInternal(QCString &val, QCString &str) { int idx1 = val.find('\"'); if(idx1 == -1) return false; idx1++; int idx2 = val.findRev('\"'); if(idx2 == -1) return false; str = val.mid(idx1, idx2 - idx1); val = val.mid(idx2 + 1); // now unquote idx1 = 0; while((idx1 = str.find('\\', idx1)) != -1) { char c = str[idx1 + 1]; switch(c) { case '\\': str = str.left(idx1) + '\\' + str.mid(idx1 + 2); break; case 'n': str = str.left(idx1) + '\n' + str.mid(idx1 + 2); break; case 'x': { char c1 = str[idx1 + 2]; char c2 = c1 ? str[idx1 + 3] : 0; if(!c1 || !c2) return false; c = (fromHex(c1) << 4) | (fromHex(c2)); str = str.left(idx1) + c + str.mid(idx1 + 4); break; } default: break; } idx1++; } return true; } EXPORT void load_data(const DataDef *d, void *_data, Buffer *cfg) { Data *data = (Data*)_data; init_data(d, data); if (cfg == NULL) return; unsigned read_pos = cfg->readPos(); for (;;){ QCString line = cfg->getLine(); if (line.isEmpty()) break; int idx = line.find('='); if(idx == -1) continue; QCString name = line.left( idx ); QCString val = line.mid( idx + 1 ); if(name.isEmpty() || val.isEmpty()) continue; unsigned offs = 0; const DataDef *def = find_key(d, name, offs); if (def == NULL) continue; Data *ld = data + offs; ld->setType(def->type); switch (def->type){ case DATA_IP: { int idx = val.find(','); QCString ip, url; if(idx == -1) { ip = val; } else { ip = val.left(idx); url = val.mid(idx + 1); } set_ip(ld, inet_addr(ip), url); break; } case DATA_UTFLIST: case DATA_STRLIST: { // ,""(u) QCString v; int idx1 = val.find(','); if(idx1 == -1) break; unsigned i = val.left(idx1).toUInt(); if (i == 0) break; val = val.mid(idx1 + 1); if(!unquoteInternal(val, v)) { set_str(ld, i, QString::null); break; } if (!val.isEmpty() && val[0] == 'u'){ set_str(ld, i, QString::fromUtf8(v)); }else{ set_str(ld, i, QString::fromLocal8Bit(v)); } break; } case DATA_UTF: case DATA_STRING: case DATA_CSTRING: { // ""(u),""(u),""(u),""(u),... for (unsigned i = 0; i < def->n_values; ld++, i++){ QCString v; if(!unquoteInternal(val, v)) break; if(def->type == DATA_CSTRING) { ld->cstr() = v; } else { if (!val.isEmpty() && val[0] == 'u') ld->str() = QString::fromUtf8(v); else ld->str() = QString::fromLocal8Bit(v); } idx = val.find(','); if (idx == -1) break; val = val.mid(idx + 1); } break; } case DATA_LONG: case DATA_ULONG: { QStringList sl = QStringList::split(',',val,true); for (unsigned i = 0; i < def->n_values && i < sl.count(); i++, ld++){ QString s = sl[i]; if(s.isEmpty()) continue; if(def->type == DATA_LONG) ld->setLong(s.toLong()); else ld->setULong(s.toULong()); } break; } case DATA_BOOL: { QStringList sl = QStringList::split(',',val,true); for (unsigned i = 0; i < def->n_values && i < sl.count(); i++, ld++){ QString s = sl[i]; if(s.isEmpty()) continue; ld->setBool(s.lower() != "false" && s != "0"); } break; } case DATA_BINARY: { // ok here since they're only latin1 chars QStringList sl = QStringList::split(',', val, true); for (unsigned i = 0; i < def->n_values && i < sl.count(); i++, ld++){ QString s = sl[i]; if(s.isEmpty()) continue; int size = s.length() / 2; QByteArray ba(size); for(int cnt = 0; cnt < size; cnt++) { ba.data()[cnt] = (char)s.mid(cnt * 2, 2).toShort(NULL, 16); } ld->setBinary(ba); } break; } case DATA_UNKNOWN: case DATA_STRUCT: case DATA_OBJECT: default: break; } } cfg->setReadPos(read_pos); } EXPORT QCString save_data(const DataDef *def, void *_data) { Data *data = (Data*)_data; QCString res; for (; def->name; def++){ QCString value; bool bSave = false; if (def->type == DATA_STRUCT){ QCString s = save_data((DataDef*)(def->def_value), data); if (s.length()){ if (res.length()) res += '\n'; res += s; } }else if (*def->name){ Data *ld = data; switch (def->type){ case DATA_IP:{ IP *p = ld->ip(); if (p && p->ip()){ struct in_addr inaddr; inaddr.s_addr = p->ip(); value = inet_ntoa(inaddr); QString host = p->host(); if (!host.isEmpty()){ value += ','; value += host; } bSave = true; } break; } case DATA_UTFLIST: case DATA_STRLIST:{ const Data::STRING_MAP &p = ld->strMap(); if (p.count()){ for (Data::STRING_MAP::ConstIterator it = p.begin(); it != p.end(); ++it){ if(it.data().isEmpty()) continue; if (res.length()) res += '\n'; res += def->name; res += '='; res += QString::number(it.key()); res += ','; QString s = it.data(); QCString ls = s.local8Bit(); if (QString::fromLocal8Bit(ls) == s){ res += quoteInternal(ls); }else{ res += quoteInternal(s.utf8()); res += 'u'; } } } break; } case DATA_STRING:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ QString &str = ld->str(); if (value.length()) value += ','; if (def->def_value){ if (str != QString::fromAscii(def->def_value)){ bSave = true; } }else{ if (str.length()){ bSave = true; } } if (bSave){ QCString ls = str.local8Bit(); if (QString::fromLocal8Bit(ls) == str){ value += quoteInternal(ls); }else{ value += quoteInternal(str.utf8()); value += 'u'; } } } break; } case DATA_UTF:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ QString &str = ld->str(); if (value.length()) value += ','; if (def->def_value){ if (str != i18n(def->def_value)) bSave = true; }else{ if (str.length()) bSave = true; } if (bSave){ QCString ls = str.local8Bit(); if (QString::fromLocal8Bit(ls) == str){ value += quoteInternal(ls); }else{ value += quoteInternal(str.utf8()); value += 'u'; } } } break; } case DATA_CSTRING:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ QCString &str = ld->cstr(); if (value.length()) value += ','; if (def->def_value){ if (str != def->def_value){ bSave = true; } }else{ if (str.length()){ bSave = true; } } if (bSave) value += quoteInternal(str); } break; } case DATA_BOOL:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ bool p = ld->toBool(); if (value.length()) value += ','; if (p != (def->def_value != 0)){ if (p){ value += "true"; }else{ value += "false"; } bSave = true; } } break; } case DATA_LONG:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ long p = ld->toLong(); if (value.length()) value += ','; if (p != (long)(def->def_value)){ QString s; s.sprintf("%li", p); value += s; bSave = true; } } break; } case DATA_ULONG:{ for (unsigned i = 0; i < def->n_values; i++, ld++){ unsigned long p = ld->toULong(); if (value.length()) value += ','; if (p != (unsigned long)(def->def_value)){ QString s; s.sprintf("%lu", p); value += s; bSave = true; } } break; } case DATA_BINARY: { for (unsigned i = 0; i < def->n_values; i++) { QByteArray &ba = ld->asBinary(); for(unsigned i = 0; i < ba.size(); i++) { unsigned char c = ba.data()[i]; QString s; s.sprintf("%02X", c); value += s.latin1(); // ok here since they're only latin1 chars } if(!bSave) bSave = (ba.size() != 0); } break; } case DATA_UNKNOWN: case DATA_STRUCT: case DATA_OBJECT: default: break; } if (bSave){ if (res.length()) res += '\n'; res += def->name; res += '='; res += value; } } data += def->n_values; } return res; } // ______________________________________________________________________________________ #ifdef WIN32 #ifndef SM_CYSMCAPTION #define SM_CYSMCAPTION 51 #endif #endif EXPORT void saveGeometry(QWidget *w, Geometry geo) { if (w == NULL) return; QPoint pos = w->pos(); QSize size = w->size(); geo[LEFT].asLong() = pos.x(); geo[TOP].asLong() = pos.y(); geo[WIDTH].asLong() = size.width(); geo[HEIGHT].asLong() = size.height(); #ifdef WIN32 if (GetWindowLongA(w->winId(), GWL_EXSTYLE) & WS_EX_TOOLWINDOW){ int dc = GetSystemMetrics(SM_CYCAPTION); int ds = GetSystemMetrics(SM_CYSMCAPTION); geo[1].asLong() += dc - ds; geo[3].asLong() -= (dc - ds) * 2; } #endif #ifdef USE_KDE #if KDE_IS_VERSION(3,2,0) KWin::WindowInfo info = KWin::windowInfo(w->winId()); geo[4].asLong() = info.desktop(); if (info.onAllDesktops()) geo[4].asLong() = -1; #else KWin::Info info = KWin::info(w->winId()); geo[4].asLong() = info.desktop; if (info.onAllDesktops) geo[4].asLong() = -1; #endif #endif } EXPORT void restoreGeometry(QWidget *w, Geometry geo, bool bPos, bool bSize) { if (w == NULL) return; QRect rc = screenGeometry(); if (geo[WIDTH].toLong() > rc.width()) geo[WIDTH].asLong() = rc.width(); if (geo[HEIGHT].toLong() > rc.height()) geo[HEIGHT].asLong() = rc.height(); if (geo[LEFT].toLong() + geo[WIDTH].toLong() > rc.right()) geo[LEFT].asLong() = rc.right() - geo[WIDTH].asLong(); if (geo[TOP].toLong() + geo[HEIGHT].toLong() > rc.bottom()) geo[TOP].asLong() = rc.bottom() - geo[HEIGHT].asLong(); if (geo[LEFT].toLong() < rc.left()) geo[LEFT].asLong() = rc.left(); if (geo[TOP].toLong() < rc.top()) geo[TOP].asLong() = rc.top(); if (bPos) w->move(geo[LEFT].toLong(), geo[TOP].toLong()); if (bSize) w->resize(geo[WIDTH].asLong(), geo[HEIGHT].asLong()); #ifdef USE_KDE if (geo[4].toLong() == -1){ KWin::setOnAllDesktops(w->winId(), true); }else{ KWin::setOnAllDesktops(w->winId(), false); KWin::setOnDesktop(w->winId(), geo[4].toLong()); } #endif } const long SAVE_STATE = -1; EXPORT void saveToolbar(QToolBar *bar, Data state[7]) { for(int i = 0; i < 7; i++) state[i].clear(); if (bar == NULL) return; QMainWindow *main = NULL; for (QWidget *w = bar->parentWidget(); w; w = w->parentWidget()){ if (w->inherits("QMainWindow")){ main = static_cast(w); break; } } if (main == NULL) return; QMainWindow::ToolBarDock dock; int index; bool nl; int extraOffset; main->getLocation(bar, dock, index, nl, extraOffset); state[0].asLong() = SAVE_STATE; state[1].asLong() = (long)dock; state[2].asLong() = index; state[3].asLong() = nl ? 1 : 0; state[4].asLong() = extraOffset; if (dock == QMainWindow::TornOff){ QPoint pos = bar->geometry().topLeft(); state[5].asLong() = pos.x(); state[6].asLong() = pos.y(); } } EXPORT void restoreToolbar(QToolBar *bar, Data state[7]) { if (bar == NULL) return; if (state[0].asLong() != SAVE_STATE){ if (state[1].asLong() == 0) state[1].asLong() = (unsigned)(QMainWindow::Top); state[2].asLong() = 0; state[3].asLong() = 0; state[4].asLong() = SAVE_STATE; state[5].asLong() = 0; state[6].asLong() = 0; } QMainWindow *main = NULL; for (QWidget *w = bar->parentWidget(); w; w = w->parentWidget()){ if (w->inherits("QMainWindow")){ main = static_cast(w); break; } } if (main == NULL) return; QMainWindow::ToolBarDock dock = (QMainWindow::ToolBarDock)state[1].asLong(); main->moveToolBar(bar, dock, state[2].asLong() != 0, state[3].asLong() != 0, state[4].asLong()); if (dock == QMainWindow::TornOff) bar->move(state[5].asLong(), state[6].asLong()); } // ---------------------------- // class Data // ---------------------------- class EXPORT DataPrivate { public: unsigned long m_dataAsValue; bool m_dataAsBool; QString *m_dataAsQString; Data::STRING_MAP *m_dataAsQStringMap; QObject *m_dataAsObject; IP *m_dataAsIP; QByteArray *m_dataAsBinary; QCString *m_dataAsQCString; DataPrivate() : m_dataAsValue(0), m_dataAsBool(false), m_dataAsQString(NULL), m_dataAsQStringMap(NULL), m_dataAsObject(NULL), m_dataAsIP(NULL), m_dataAsBinary(NULL), m_dataAsQCString(NULL) {} static unsigned long myStaticDummyULong; static bool myStaticDummyBool; static QString myStaticDummyQString; static Data::STRING_MAP myStaticDummyQStringMap; static QByteArray myStaticDummyQByteArray; static QCString myStaticDummyQCString; }; unsigned long DataPrivate::myStaticDummyULong = ~0U; bool DataPrivate::myStaticDummyBool = false; QString DataPrivate::myStaticDummyQString = QString("Wrong datatype!"); Data::STRING_MAP DataPrivate::myStaticDummyQStringMap = Data::STRING_MAP(); QByteArray DataPrivate::myStaticDummyQByteArray = QByteArray(); QCString DataPrivate::myStaticDummyQCString = QCString("Wrong datatype!"); Data::Data() : m_type(DATA_UNKNOWN), m_name("unknown"), data(NULL) { clear(); } Data::Data(const Data &d) : data(NULL) { *this = d; } Data &Data::operator =(const Data &d) { clear(); m_name = d.m_name; m_type = d.m_type; switch(m_type) { case DATA_STRING: this->str() = d.str(); break; case DATA_LONG: case DATA_ULONG: data->m_dataAsValue = d.data->m_dataAsValue; break; case DATA_BOOL: data->m_dataAsBool = d.data->m_dataAsBool; break; case DATA_STRMAP: this->strMap() = d.strMap(); break; case DATA_IP: data->m_dataAsIP = d.data->m_dataAsIP; break; case DATA_OBJECT: data->m_dataAsObject = d.data->m_dataAsObject; break; case DATA_BINARY: this->asBinary() = d.toBinary(); break; case DATA_CSTRING: this->cstr() = d.cstr(); break; case DATA_UNKNOWN: case DATA_STRUCT: default: break; } return *this; } void Data::clear(bool bNew) { if(data) { delete data->m_dataAsQString; delete data->m_dataAsQStringMap; delete data->m_dataAsBinary; delete data->m_dataAsQCString; delete data; } data = bNew ? new DataPrivate : NULL; } const QString &Data::str() const { if(!checkType(DATA_STRING)) return DataPrivate::myStaticDummyQString; if(!data->m_dataAsQString) data->m_dataAsQString = new QString(); return *data->m_dataAsQString; } QString &Data::str() { if(!checkType(DATA_STRING)) return DataPrivate::myStaticDummyQString; if(!data->m_dataAsQString) data->m_dataAsQString = new QString(); return *data->m_dataAsQString; } bool Data::setStr(const QString &s) { if(!checkType(DATA_STRING)) return false; if(data->m_dataAsQString && s == *data->m_dataAsQString) return false; if(!data->m_dataAsQString) data->m_dataAsQString = new QString(s); else *data->m_dataAsQString = s; return true; } const Data::STRING_MAP &Data::strMap() const { if(!checkType(DATA_STRMAP)) return DataPrivate::myStaticDummyQStringMap; if(!data->m_dataAsQStringMap) data->m_dataAsQStringMap = new STRING_MAP(); return *data->m_dataAsQStringMap; } Data::STRING_MAP &Data::strMap() { if(!checkType(DATA_STRMAP)) return DataPrivate::myStaticDummyQStringMap; if(!data->m_dataAsQStringMap) data->m_dataAsQStringMap = new STRING_MAP(); return *data->m_dataAsQStringMap; } bool Data::setStrMap(const STRING_MAP &s) { if(!checkType(DATA_STRMAP)) return false; if(!data->m_dataAsQStringMap) data->m_dataAsQStringMap = new STRING_MAP(s); else *data->m_dataAsQStringMap = s; return true; } long Data::toLong() const { if(!checkType(DATA_LONG)) return (long)DataPrivate::myStaticDummyULong; return (long)data->m_dataAsValue; } long &Data::asLong() { if(!checkType(DATA_LONG)) return (long&)DataPrivate::myStaticDummyULong; return (long&)data->m_dataAsValue; } bool Data::setLong(long d) { if(!checkType(DATA_LONG)) return false; if(d == (long)data->m_dataAsValue) return false; data->m_dataAsValue = (unsigned long)d; return true; } unsigned long Data::toULong() const { if(!checkType(DATA_ULONG)) return DataPrivate::myStaticDummyULong; return data->m_dataAsValue; } unsigned long &Data::asULong() { if(!checkType(DATA_ULONG)) return DataPrivate::myStaticDummyULong; return data->m_dataAsValue; } bool Data::setULong(unsigned long d) { if(!checkType(DATA_ULONG)) return false; if(d == data->m_dataAsValue) return false; data->m_dataAsValue = d; return true; } bool Data::toBool() const { if(!checkType(DATA_BOOL)) return DataPrivate::myStaticDummyBool; return data->m_dataAsBool; } bool &Data::asBool() { if(!checkType(DATA_BOOL)) return DataPrivate::myStaticDummyBool; return data->m_dataAsBool; } bool Data::setBool(bool d) { if(!checkType(DATA_BOOL)) return false; if(d == data->m_dataAsBool) return false; data->m_dataAsBool = d; return true; } const QObject* Data::object() const { if(!checkType(DATA_OBJECT)) return NULL; return data->m_dataAsObject; } QObject* Data::object() { if(!checkType(DATA_OBJECT)) return NULL; return data->m_dataAsObject; } bool Data::setObject(const QObject *d) { if(!checkType(DATA_OBJECT)) return false; if(d == data->m_dataAsObject) return false; data->m_dataAsObject = const_cast(d); return true; } const QByteArray &Data::toBinary() const { if(!checkType(DATA_BINARY)) return DataPrivate::myStaticDummyQByteArray; if(!data->m_dataAsBinary) data->m_dataAsBinary = new QByteArray(); return *data->m_dataAsBinary; } QByteArray &Data::asBinary() { if(!checkType(DATA_BINARY)) return DataPrivate::myStaticDummyQByteArray; if(!data->m_dataAsBinary) data->m_dataAsBinary = new QByteArray(); return *data->m_dataAsBinary; } bool Data::setBinary(const QByteArray &d) { if(!checkType(DATA_BINARY)) return false; if(data->m_dataAsBinary && d == *data->m_dataAsBinary) return false; if(!data->m_dataAsBinary) data->m_dataAsBinary = new QByteArray(d); else *data->m_dataAsBinary = d; return true; } const IP* Data::ip() const { if(!checkType(DATA_IP)) return NULL; return data->m_dataAsIP; } IP* Data::ip() { if(!checkType(DATA_IP)) return NULL; return data->m_dataAsIP; } bool Data::setIP(const IP *d) { if(!checkType(DATA_IP)) return false; if(d == data->m_dataAsIP) return false; data->m_dataAsIP = const_cast(d); return true; } const QCString &Data::cstr() const { if(!checkType(DATA_CSTRING)) return DataPrivate::myStaticDummyQCString; if(!data->m_dataAsQCString) data->m_dataAsQCString = new QCString(); return *data->m_dataAsQCString; } QCString &Data::cstr() { if(!checkType(DATA_CSTRING)) return DataPrivate::myStaticDummyQCString; if(!data->m_dataAsQCString) data->m_dataAsQCString = new QCString(); return *data->m_dataAsQCString; } bool Data::setCStr(const QCString &s) { if(!checkType(DATA_CSTRING)) return false; if(data->m_dataAsQCString && s == *data->m_dataAsQCString) return false; if(!data->m_dataAsQCString) data->m_dataAsQCString = new QCString(s); else *data->m_dataAsQCString = s; return true; } static const char *dataType2Name(DataType type) { switch(type) { case DATA_UNKNOWN: return "uninitialized"; case DATA_UTF: case DATA_STRING: return "string"; case DATA_LONG: return "long"; case DATA_ULONG: return "ulong"; case DATA_BOOL: return "bool"; case DATA_UTFLIST: case DATA_STRMAP: return "stringmap"; case DATA_IP: return "ip"; case DATA_STRUCT: return "struct"; case DATA_OBJECT: return "object"; case DATA_BINARY: return "binary"; case DATA_CSTRING: return "cstr"; } return "unknown"; } bool Data::checkType(DataType type) const { DataType myType = m_type; if(myType == DATA_UTFLIST) myType = DATA_STRLIST; if(myType == DATA_UTF) myType = DATA_STRING; if(myType != type) { QString errString = QString("Using wrong data type %1 instead %2 for %3!") .arg(dataType2Name(type)) .arg(dataType2Name(m_type)) .arg(m_name.isEmpty() ? "??" : m_name); log(L_ERROR, errString); #ifdef _DEBUG QMessageBox::information(0, "Debug error", errString, QMessageBox::Ok); #endif return false; } return true; } void Data::setName(const QString &name) { if(!name.isEmpty() && (m_name.isEmpty() || m_name == "unknown")) m_name = name; } const QString &Data::name() const { return m_name; } void Data::setType(DataType type) { m_type = type; } DataType Data::type() const { return m_type; } } // namespace SIM