<commit_before>#include <QRegExp>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QSettings>
#include <QSqlField>
#include "identity.h"
#include "kernel.h"
#include "oshelper.h"
#include "connectorinterface.h"
#include "mastercatalog.h"
#include "ilwisobjectconnector.h"
#include "catalogexplorer.h"
#include "catalogconnector.h"
#include "abstractfactory.h"
#include "connectorfactory.h"
#include "ilwiscontext.h"
#include "catalog.h"
#include "symboltable.h"
#include "operationExpression.h"

Ilwis::MasterCatalog *Ilwis::MasterCatalog::_masterCatalog = 0;

using namespace Ilwis;

MasterCatalog* Ilwis::mastercatalog() {
    if (Ilwis::MasterCatalog::_masterCatalog == 0) {
        Ilwis::MasterCatalog::_masterCatalog = new Ilwis::MasterCatalog();
        Ilwis::MasterCatalog::_masterCatalog->prepare();

    }
    return Ilwis::MasterCatalog::_masterCatalog;
}

MasterCatalog::MasterCatalog()
{
}

MasterCatalog::~MasterCatalog()
{
    _lookup.clear();
    _knownHashes.clear();
    _catalogs.clear();
}

bool MasterCatalog::prepare()
{
    QSettings settings("52n","ilwis4");

    //TODO: this piece code must move to a more appropriate place; at this moment it
    // is not guaranteed that the catalogconnectors are already known due to the order of the plugins
    // as they are loaded.
//    QString local = settings.value("localfilesystem",QVariant(sUNDEF)).toString();

    return true;
}

bool MasterCatalog::addContainer(const QUrl &inlocation)
{
    if ( !inlocation.isValid()) // it is valid to try this with an empty url; just wont do anything
        return true;

    QString original = inlocation.toString().trimmed();
    if ( Resource::isRoot(original))
        return true;

    QString loc = original;
    if ( loc[loc.size() - 1] == '/' ){
        loc = loc.left(loc.size() - 1);
        int count = loc.count("/");
        if ( loc.indexOf(":///") != -1){
            if ( count == 3)
                loc = original;
        }else if ( loc.indexOf("://") != -1){
            if ( count == 2){
                loc= original;
            }
        }
    }

    if ( loc.indexOf("ilwis://tables") == 0||
         loc.indexOf("ilwis://factory") == 0 ||
         loc.indexOf("ilwis://system") == 0 ||
         loc.indexOf("ilwis://operations") == 0 ||
         loc == "file://" ||
         loc == "file:/" ||
         loc == "ilwis:/" ||
         loc.isEmpty())
        return true;
    QUrl location(loc);
    if ( _catalogs.find(location) != _catalogs.end())
        return true;

    ICatalog catalog(loc);
    if ( !catalog.isValid()){
        return false;
    }

    addItems({catalog->source()});
    _catalogs.insert(location);
    return true;
}

ESPIlwisObject MasterCatalog::get(const QUrl &resource, IlwisTypes type) const
{
    quint64 id = url2id(resource, type);
    return get(id);
}

ESPIlwisObject MasterCatalog::get(quint64 id) const
{
    if ( id != i64UNDEF) {
        auto iter = _lookup.find(id);
        if ( iter != _lookup.end())
            return iter.value();
    }
    return ESPIlwisObject();
}

bool MasterCatalog::contains(const QUrl& url, IlwisTypes type) const{
    auto hash = Ilwis::qHash2(url, type);
    auto  iter = _knownHashes.find(hash);
    if ( iter != _knownHashes.end()) {
        auto id = url2id(url, type);
        if ( id != i64UNDEF)
            return true;
    }
    return false;
}

bool MasterCatalog::usesContainers(const QUrl &url) const
{
    return _containerExceptions.find(url.scheme()) == _containerExceptions.end();
}

void MasterCatalog::addContainerException(const QString &scheme)
{
    _containerExceptions.insert(scheme);
}

bool MasterCatalog::removeItems(const QList<Resource> &items){
    for(const Resource &resource : items) {
        auto iter = _knownHashes.find(Ilwis::qHash(resource));
        if ( iter != _knownHashes.end()) {
            _knownHashes.erase(iter);
        }
        QString stmt = QString("DELETE FROM mastercatalog WHERE resource = %1" ).arg(resource.id());
        QSqlQuery db(kernel()->database());
        if(!db.exec(stmt)) {
            kernel()->issues()->logSql(db.lastError());
            return false;
        }
        stmt = QString("DELETE FROM catalogitemproperties WHERE resource = %1").arg(resource.id());
        if(!db.exec(stmt)) {
            kernel()->issues()->logSql(db.lastError());
            return false;
        }
    }

    return true;
}

bool MasterCatalog::addItems(const std::vector<Resource>& items)
{
    if( items.size() == 0) // nothing to do; not wrong perse
            return true;

    QSqlQuery queryItem(kernel()->database()), queryProperties(kernel()->database());

    bool ok = queryItem.prepare("INSERT INTO mastercatalog VALUES(\
                  :itemid,:name,:code,:container,:resource,:rawresource,:urlquery,:type,:extendedtype, :size,:dimensions \
                  )" );
    if (!ok) {
        kernel()->issues()->logSql(queryItem.lastError());
        return false;

    }

    ok = queryProperties.prepare("INSERT INTO catalogitemproperties VALUES(\
                   :propertyvalue,:propertyname,:itemid\
                 )" );
    if (!ok) {
        kernel()->issues()->logSql(queryItem.lastError());
        return false;
    }

    for(const Resource &resource : items) {
        if (!resource.isValid())
           continue;
        if ( mastercatalog()->contains(resource.url(), resource.ilwisType()))
          continue;

        _knownHashes.insert(Ilwis::qHash(resource));
        resource.store(queryItem, queryProperties);
    }

    return true;

}

quint64 MasterCatalog::url2id(const QUrl &url, IlwisTypes tp, bool casesensitive) const
{
    QString query = QString("select itemid,type from mastercatalog where resource = '%1'").arg(url.toString());
    if (!casesensitive)
       query = QString("select itemid,type from mastercatalog where lower(resource) = '%1'").arg(url.toString().toLower()) ;
    auto results = kernel()->database().exec(query);
    while ( results.next()) {
        auto rec = results.record();
        auto iid = rec.value(0).toLongLong();
        auto itype = rec.value(1).toLongLong();
        if ( (itype & tp) || tp == itUNKNOWN)
            return iid;
    }

    return i64UNDEF;

}

Resource MasterCatalog::id2Resource(quint64 iid) const {
    auto query = QString("select * from mastercatalog where itemid = %1").arg(iid);
    auto results = kernel()->database().exec(query);
    if ( results.next()) {
        auto rec = results.record();
        return Resource(rec);
    }
    return Resource();
}

quint64 MasterCatalog::name2id(const QString &name, IlwisTypes tp) const
{
    quint64 id = IlwisObject::internalname2id(name);
    if ( id == i64UNDEF){
        Resource resource = name2Resource(name,tp);
        id =  resource.id();
    }
    return id;
}

IlwisTypes MasterCatalog::id2type(quint64 iid) const {
    QString query = QString("select type from mastercatalog where itemid = %1").arg(iid);
    QSqlQuery results = kernel()->database().exec(query);
    if ( results.next()) {
        return results.value(0).toLongLong();
    }
    return itUNKNOWN;
}

Resource MasterCatalog::name2Resource(const QString &name, IlwisTypes tp) const
{
    if ( tp == itUNKNOWN) { // no definitive type given we, try to find based on name/type combination. will work mostely but not guaranteed. this is anyway a last resort method
        std::vector<IlwisTypes> types { itRASTER, itFEATURE, itTABLE, itGEOREF, itCOORDSYSTEM, itDOMAIN};
        for(IlwisTypes type: types) {
            Resource resource = name2Resource(name, type);
            if (resource.isValid())
                return resource;
        }

        return Resource();
    }
    auto resolvedName = name2url(name, tp);
    if (!resolvedName.isValid())
        return Resource();

    resolvedName = OSHelper::neutralizeFileName(resolvedName.toString());
    auto query = QString("select * from mastercatalog where resource = '%1' and (type & %2) != 0").arg(resolvedName.toString()).arg(tp);
    auto results = kernel()->database().exec(query);
    if ( results.next()) {
        auto rec = results.record();
        return Resource(rec);

    } else {
        query = QString("select propertyvalue from catalogitemproperties,mastercatalog \
                        where mastercatalog.resource='%1' and mastercatalog.itemid=catalogitemproperties.itemid\
                and (mastercatalog.extendedtype & %2) != 0").arg(resolvedName.toString()).arg(tp);
        auto viaExtType = kernel()->database().exec(query);
        bool isExternalRef = true;
        while ( viaExtType.next()){ // external reference finding
            isExternalRef = false;
            bool ok;
            auto propertyid = viaExtType.value(0).toLongLong(&ok);
            if (!ok) {
                kernel()->issues()->log(TR("Invalid catalog property, mastercatalog corrupted?"),IssueObject::itWarning);
            }
            auto type = id2type(propertyid);
            if ( type & tp)
                return id2Resource(propertyid);
        }
        if ( !isExternalRef) { // it was not an external reference but an internal one; if it was external it will never come here
            // this is a new resource which only existed as reference but now gets real, so add it to the catalog
            Resource resource(QUrl(resolvedName), tp);
            const_cast<MasterCatalog *>(this)->addItems({resource});
            return resource;
        }
    }
    return Resource();
}

QUrl MasterCatalog::name2url(const QString &name, IlwisTypes tp) const{
    if ( name.contains(QRegExp("\\\\|/"))) { // is there already path info; then assume it is already a unique resource
        bool ok = OSHelper::isAbsolute(name); // name might be a partial path
        if ( ok && !OSHelper::isFileName(name))
    // translate name to url; we have the following cases
    // * already is a path, no big deal; just make an url of it
    // * is a code; construct a path leading to the internal connector as all codes are handled there
    // * no, path, no code. So it must be in the current working catalog.
    // * backup case. we try it by name. may fail as names are not necessarily unique. system is robust enough to handle fail cases

            return name;
        if ( ok){
            return QUrl::fromLocalFile(name).toString();
        }else {
            QString resolvedName =  context()->workingCatalog()->source().url().toString() + "/" + name;
            return resolvedName;
        }

    }
    if ( name.indexOf("code=wkt:")==0) { // second case -- handle most codes cases
        auto code = name.right(name.size() - 5);
        auto wkt = code.mid(4);
        auto table = "projection";
        if ( tp & itELLIPSOID )
            table = "ellipsoid";
        else if ( tp & itGEODETICDATUM)
            table = "datum";
        //auto query = QString("select code from %1 where wkt='%2'").arg(table, wkt);
        auto query = QString("select code from %1 where wkt like '%%2%'").arg(table, wkt);
        auto codes = kernel()->database().exec(query);
        if ( codes.next()) {
            QString res = QString("ilwis://tables/%1?code=%2").arg(table,codes.value(0).toString());
            return res;
        }else {
            kernel()->issues()->log(TR(ERR_FIND_SYSTEM_OBJECT_1).arg(wkt));
            return QUrl();
        }
    } else if ( name.indexOf("code=epsg:")== 0 ) {
        auto code = name.right(name.size() - 5);
        return QString("ilwis://tables/projectedcsy?code=%1").arg(code);

    } else if ( name.left(6) == "code=proj4:") {
        auto code = name.right(name.size() - 5);
        return QString("ilwis://projection/code=%1").arg(code);
    } else if ( name.left(12) == "code=domain:") {
        return QString("ilwis://internalcatalog/%1").arg(name);
    }else if ( name.left(12) == "code=georef:") {
        QString shortname = name.mid(name.indexOf(":") + 1);
        return QString("ilwis://internalcatalog/%1").arg(shortname);
    }else if ( name.left(9) == "code=csy:") {
        QString shortname = name.mid(name.indexOf(":") + 1);
        return QString("ilwis://internalcatalog/%1").arg(shortname);
    }
    if ( context()->workingCatalog().isValid()) { // thirde case -- use the working catalog to extend the path
        auto resolvedName = context()->workingCatalog()->resolve(name, tp);
        if ( resolvedName != sUNDEF)
            return resolvedName;
    }
    auto code = name;
    if ( code.indexOf("code=") == 0)
        code = code.mid(5);

    // fourth case -- try name
    auto query = QString("select resource,type from mastercatalog where name = '%1' or code='%1'").arg(code);
    auto results = kernel()->database().exec(query);
    while ( results.next()) {
        auto rec = results.record();
        auto type = rec.value(1).toLongLong();
        if ( type & tp)
            return rec.value(0).toString();
    }
    return QUrl();

}

bool MasterCatalog::isRegistered(quint64 id) const
{
    return _lookup.contains(id);
}

bool MasterCatalog::unregister(quint64 id)
{
    QHash<quint64,ESPIlwisObject>::const_iterator iter = _lookup.find(id);
    if ( iter != _lookup.end()) {
        _lookup.remove(id);
    }

    return true;

}

std::vector<Resource> MasterCatalog::select(const QUrl &resource, const QString &selection) const
{
    QString rest = selection == "" ? "" : QString("and (%1)").arg(selection);
    QString query = QString("select * from mastercatalog where container = '%1' %2").arg(resource.toString(), rest);
    QSqlQuery results = kernel()->database().exec(query);
    std::vector<Resource> items;
    while( results.next()) {
        QSqlRecord rec = results.record();
        items.push_back(Resource(rec));
    }
    return items;

}

void MasterCatalog::registerObject(ESPIlwisObject &data)
{
    if ( data.get() == 0) {
        QHash<quint64,ESPIlwisObject>::iterator iter = _lookup.find(data->id());
        data = iter.value();
    } else {
        if ( !data->isAnonymous())
            addItems({data->source()});
        _lookup[data->id()] = data;

    }
}

#ifdef QT_DEBUG

void MasterCatalog::dumpLookup() const
{
    for(auto pr : _lookup) {
        qDebug() << pr->name();
    }
}

quint32 MasterCatalog::usecount(quint64 id)
{
    auto iter = _lookup.find(id);
    if ( iter != _lookup.end()) {
        return iter.value().use_count();
    }
    return 0;
}

#endif
<commit_msg>added guard<commit_after>#include <QRegExp>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QSettings>
#include <QSqlField>
#include "identity.h"
#include "kernel.h"
#include "oshelper.h"
#include "connectorinterface.h"
#include "mastercatalog.h"
#include "ilwisobjectconnector.h"
#include "catalogexplorer.h"
#include "catalogconnector.h"
#include "abstractfactory.h"
#include "connectorfactory.h"
#include "ilwiscontext.h"
#include "catalog.h"
#include "symboltable.h"
#include "operationExpression.h"

Ilwis::MasterCatalog *Ilwis::MasterCatalog::_masterCatalog = 0;

using namespace Ilwis;

MasterCatalog* Ilwis::mastercatalog() {
    if (Ilwis::MasterCatalog::_masterCatalog == 0) {
        Ilwis::MasterCatalog::_masterCatalog = new Ilwis::MasterCatalog();
        Ilwis::MasterCatalog::_masterCatalog->prepare();

    }
    return Ilwis::MasterCatalog::_masterCatalog;
}

MasterCatalog::MasterCatalog()
{
}

MasterCatalog::~MasterCatalog()
{
    _lookup.clear();
    _knownHashes.clear();
    _catalogs.clear();
}

bool MasterCatalog::prepare()
{
    QSettings settings("52n","ilwis4");

    //TODO: this piece code must move to a more appropriate place; at this moment it
    // is not guaranteed that the catalogconnectors are already known due to the order of the plugins
    // as they are loaded.
//    QString local = settings.value("localfilesystem",QVariant(sUNDEF)).toString();

    return true;
}

bool MasterCatalog::addContainer(const QUrl &inlocation)
{
    if ( !inlocation.isValid()) // it is valid to try this with an empty url; just wont do anything
        return true;

    QString original = inlocation.toString().trimmed();
    if ( Resource::isRoot(original))
        return true;

    QString loc = original;
    if ( loc[loc.size() - 1] == '/' ){
        loc = loc.left(loc.size() - 1);
        int count = loc.count("/");
        if ( loc.indexOf(":///") != -1){
            if ( count == 3)
                loc = original;
        }else if ( loc.indexOf("://") != -1){
            if ( count == 2){
                loc= original;
            }
        }
    }

    if ( loc.indexOf("ilwis://tables") == 0||
         loc.indexOf("ilwis://factory") == 0 ||
         loc.indexOf("ilwis://system") == 0 ||
         loc.indexOf("ilwis://operations") == 0 ||
         loc == "file://" ||
         loc == "file:/" ||
         loc == "ilwis:/" ||
         loc.isEmpty())
        return true;
    QUrl location(loc);
    if ( _catalogs.find(location) != _catalogs.end())
        return true;

    ICatalog catalog(loc);
    if ( !catalog.isValid()){
        return false;
    }

    addItems({catalog->source()});
    _catalogs.insert(location);
    return true;
}

ESPIlwisObject MasterCatalog::get(const QUrl &resource, IlwisTypes type) const
{
    quint64 id = url2id(resource, type);
    return get(id);
}

ESPIlwisObject MasterCatalog::get(quint64 id) const
{
    if ( id != i64UNDEF) {
        auto iter = _lookup.find(id);
        if ( iter != _lookup.end())
            return iter.value();
    }
    return ESPIlwisObject();
}

bool MasterCatalog::contains(const QUrl& url, IlwisTypes type) const{
    auto hash = Ilwis::qHash2(url, type);
    auto  iter = _knownHashes.find(hash);
    if ( iter != _knownHashes.end()) {
        auto id = url2id(url, type);
        if ( id != i64UNDEF)
            return true;
    }
    return false;
}

bool MasterCatalog::usesContainers(const QUrl &url) const
{
    return _containerExceptions.find(url.scheme()) == _containerExceptions.end();
}

void MasterCatalog::addContainerException(const QString &scheme)
{
    _containerExceptions.insert(scheme);
}

bool MasterCatalog::removeItems(const QList<Resource> &items){
    for(const Resource &resource : items) {
        auto iter = _knownHashes.find(Ilwis::qHash(resource));
        if ( iter != _knownHashes.end()) {
            _knownHashes.erase(iter);
        }
        QString stmt = QString("DELETE FROM mastercatalog WHERE resource = %1" ).arg(resource.id());
        QSqlQuery db(kernel()->database());
        if(!db.exec(stmt)) {
            kernel()->issues()->logSql(db.lastError());
            return false;
        }
        stmt = QString("DELETE FROM catalogitemproperties WHERE resource = %1").arg(resource.id());
        if(!db.exec(stmt)) {
            kernel()->issues()->logSql(db.lastError());
            return false;
        }
    }

    return true;
}

bool MasterCatalog::addItems(const std::vector<Resource>& items)
{
    if( items.size() == 0) // nothing to do; not wrong perse
            return true;

    QSqlQuery queryItem(kernel()->database()), queryProperties(kernel()->database());

    bool ok = queryItem.prepare("INSERT INTO mastercatalog VALUES(\
                  :itemid,:name,:code,:container,:resource,:rawresource,:urlquery,:type,:extendedtype, :size,:dimensions \
                  )" );
    if (!ok) {
        kernel()->issues()->logSql(queryItem.lastError());
        return false;

    }

    ok = queryProperties.prepare("INSERT INTO catalogitemproperties VALUES(\
                   :propertyvalue,:propertyname,:itemid\
                 )" );
    if (!ok) {
        kernel()->issues()->logSql(queryItem.lastError());
        return false;
    }

    for(const Resource &resource : items) {
        if (!resource.isValid())
           continue;
        if ( mastercatalog()->contains(resource.url(), resource.ilwisType()))
          continue;

        _knownHashes.insert(Ilwis::qHash(resource));
        resource.store(queryItem, queryProperties);
    }

    return true;

}

quint64 MasterCatalog::url2id(const QUrl &url, IlwisTypes tp, bool casesensitive) const
{
    QString query = QString("select itemid,type from mastercatalog where resource = '%1'").arg(url.toString());
    if (!casesensitive)
       query = QString("select itemid,type from mastercatalog where lower(resource) = '%1'").arg(url.toString().toLower()) ;
    auto results = kernel()->database().exec(query);
    while ( results.next()) {
        auto rec = results.record();
        auto iid = rec.value(0).toLongLong();
        auto itype = rec.value(1).toLongLong();
        if ( (itype & tp) || tp == itUNKNOWN)
            return iid;
    }

    return i64UNDEF;

}

Resource MasterCatalog::id2Resource(quint64 iid) const {
    auto query = QString("select * from mastercatalog where itemid = %1").arg(iid);
    auto results = kernel()->database().exec(query);
    if ( results.next()) {
        auto rec = results.record();
        return Resource(rec);
    }
    return Resource();
}

quint64 MasterCatalog::name2id(const QString &name, IlwisTypes tp) const
{
    quint64 id = IlwisObject::internalname2id(name);
    if ( id == i64UNDEF){
        Resource resource = name2Resource(name,tp);
        id =  resource.id();
    }
    return id;
}

IlwisTypes MasterCatalog::id2type(quint64 iid) const {
    QString query = QString("select type from mastercatalog where itemid = %1").arg(iid);
    QSqlQuery results = kernel()->database().exec(query);
    if ( results.next()) {
        return results.value(0).toLongLong();
    }
    return itUNKNOWN;
}

Resource MasterCatalog::name2Resource(const QString &name, IlwisTypes tp) const
{
    if ( name == sUNDEF)
        return Resource();

    if ( tp == itUNKNOWN) { // no definitive type given we, try to find based on name/type combination. will work mostely but not guaranteed. this is anyway a last resort method
        std::vector<IlwisTypes> types { itRASTER, itFEATURE, itTABLE, itGEOREF, itCOORDSYSTEM, itDOMAIN};
        for(IlwisTypes type: types) {
            Resource resource = name2Resource(name, type);
            if (resource.isValid())
                return resource;
        }

        return Resource();
    }
    auto resolvedName = name2url(name, tp);
    if (!resolvedName.isValid())
        return Resource();

    resolvedName = OSHelper::neutralizeFileName(resolvedName.toString());
    auto query = QString("select * from mastercatalog where resource = '%1' and (type & %2) != 0").arg(resolvedName.toString()).arg(tp);
    auto results = kernel()->database().exec(query);
    if ( results.next()) {
        auto rec = results.record();
        return Resource(rec);

    } else {
        query = QString("select propertyvalue from catalogitemproperties,mastercatalog \
                        where mastercatalog.resource='%1' and mastercatalog.itemid=catalogitemproperties.itemid\
                and (mastercatalog.extendedtype & %2) != 0").arg(resolvedName.toString()).arg(tp);
        auto viaExtType = kernel()->database().exec(query);
        bool isExternalRef = true;
        while ( viaExtType.next()){ // external reference finding
            isExternalRef = false;
            bool ok;
            auto propertyid = viaExtType.value(0).toLongLong(&ok);
            if (!ok) {
                kernel()->issues()->log(TR("Invalid catalog property, mastercatalog corrupted?"),IssueObject::itWarning);
            }
            auto type = id2type(propertyid);
            if ( type & tp)
                return id2Resource(propertyid);
        }
        if ( !isExternalRef) { // it was not an external reference but an internal one; if it was external it will never come here
            // this is a new resource which only existed as reference but now gets real, so add it to the catalog
            Resource resource(QUrl(resolvedName), tp);
            const_cast<MasterCatalog *>(this)->addItems({resource});
            return resource;
        }
    }
    return Resource();
}

QUrl MasterCatalog::name2url(const QString &name, IlwisTypes tp) const{
    if ( name.contains(QRegExp("\\\\|/"))) { // is there already path info; then assume it is already a unique resource
        bool ok = OSHelper::isAbsolute(name); // name might be a partial path
        if ( ok && !OSHelper::isFileName(name))
    // translate name to url; we have the following cases
    // * already is a path, no big deal; just make an url of it
    // * is a code; construct a path leading to the internal connector as all codes are handled there
    // * no, path, no code. So it must be in the current working catalog.
    // * backup case. we try it by name. may fail as names are not necessarily unique. system is robust enough to handle fail cases

            return name;
        if ( ok){
            return QUrl::fromLocalFile(name).toString();
        }else {
            QString resolvedName =  context()->workingCatalog()->source().url().toString() + "/" + name;
            return resolvedName;
        }

    }
    if ( name.indexOf("code=wkt:")==0) { // second case -- handle most codes cases
        auto code = name.right(name.size() - 5);
        auto wkt = code.mid(4);
        auto table = "projection";
        if ( tp & itELLIPSOID )
            table = "ellipsoid";
        else if ( tp & itGEODETICDATUM)
            table = "datum";
        //auto query = QString("select code from %1 where wkt='%2'").arg(table, wkt);
        auto query = QString("select code from %1 where wkt like '%%2%'").arg(table, wkt);
        auto codes = kernel()->database().exec(query);
        if ( codes.next()) {
            QString res = QString("ilwis://tables/%1?code=%2").arg(table,codes.value(0).toString());
            return res;
        }else {
            kernel()->issues()->log(TR(ERR_FIND_SYSTEM_OBJECT_1).arg(wkt));
            return QUrl();
        }
    } else if ( name.indexOf("code=epsg:")== 0 ) {
        auto code = name.right(name.size() - 5);
        return QString("ilwis://tables/projectedcsy?code=%1").arg(code);

    } else if ( name.left(6) == "code=proj4:") {
        auto code = name.right(name.size() - 5);
        return QString("ilwis://projection/code=%1").arg(code);
    } else if ( name.left(12) == "code=domain:") {
        return QString("ilwis://internalcatalog/%1").arg(name);
    }else if ( name.left(12) == "code=georef:") {
        QString shortname = name.mid(name.indexOf(":") + 1);
        return QString("ilwis://internalcatalog/%1").arg(shortname);
    }else if ( name.left(9) == "code=csy:") {
        QString shortname = name.mid(name.indexOf(":") + 1);
        return QString("ilwis://internalcatalog/%1").arg(shortname);
    }
    if ( context()->workingCatalog().isValid()) { // thirde case -- use the working catalog to extend the path
        auto resolvedName = context()->workingCatalog()->resolve(name, tp);
        if ( resolvedName != sUNDEF)
            return resolvedName;
    }
    auto code = name;
    if ( code.indexOf("code=") == 0)
        code = code.mid(5);

    // fourth case -- try name
    auto query = QString("select resource,type from mastercatalog where name = '%1' or code='%1'").arg(code);
    auto results = kernel()->database().exec(query);
    while ( results.next()) {
        auto rec = results.record();
        auto type = rec.value(1).toLongLong();
        if ( type & tp)
            return rec.value(0).toString();
    }
    return QUrl();

}

bool MasterCatalog::isRegistered(quint64 id) const
{
    return _lookup.contains(id);
}

bool MasterCatalog::unregister(quint64 id)
{
    QHash<quint64,ESPIlwisObject>::const_iterator iter = _lookup.find(id);
    if ( iter != _lookup.end()) {
        _lookup.remove(id);
    }

    return true;

}

std::vector<Resource> MasterCatalog::select(const QUrl &resource, const QString &selection) const
{
    QString rest = selection == "" ? "" : QString("and (%1)").arg(selection);
    QString query = QString("select * from mastercatalog where container = '%1' %2").arg(resource.toString(), rest);
    QSqlQuery results = kernel()->database().exec(query);
    std::vector<Resource> items;
    while( results.next()) {
        QSqlRecord rec = results.record();
        items.push_back(Resource(rec));
    }
    return items;

}

void MasterCatalog::registerObject(ESPIlwisObject &data)
{
    if ( data.get() == 0) {
        QHash<quint64,ESPIlwisObject>::iterator iter = _lookup.find(data->id());
        data = iter.value();
    } else {
        if ( !data->isAnonymous())
            addItems({data->source()});
        _lookup[data->id()] = data;

    }
}

#ifdef QT_DEBUG

void MasterCatalog::dumpLookup() const
{
    for(auto pr : _lookup) {
        qDebug() << pr->name();
    }
}

quint32 MasterCatalog::usecount(quint64 id)
{
    auto iter = _lookup.find(id);
    if ( iter != _lookup.end()) {
        return iter.value().use_count();
    }
    return 0;
}

#endif
<|endoftext|>


<commit_before>#include <nek/utility/addressof.hpp>
#include <gtest/gtest.h>

TEST(addressof_test, enable_apply_address_operator_type)
{
  int val = 0;
  int* val_ptr = nek::addressof(val);
  EXPECT_EQ(&val, val_ptr);
}

struct address_operator_overrided_class
{
public:
  void* operator&() const
  {
    return nullptr;
  }

  bool is_same_address(address_operator_overrided_class* right) const
  {
    return this == right;
  }
};

TEST(addressof_test, disable_apply_address_operator_type)
{
  address_operator_overrided_class ad;
  ASSERT_EQ(nullptr, &ad);
  address_operator_overrided_class* ad_ptr = nek::addressof(ad);
  EXPECT_NE(nullptr, ad_ptr);
  EXPECT_TRUE(ad.is_same_address(ad_ptr));
}<commit_msg>fix test class's namespace<commit_after>#include <nek/utility/addressof.hpp>
#include <gtest/gtest.h>

TEST(addressof_test, enable_apply_address_operator_type)
{
  int val = 0;
  int* val_ptr = nek::addressof(val);
  EXPECT_EQ(&val, val_ptr);
}
namespace
{
  struct address_operator_overrided_class
  {
  public:
    void* operator&() const
    {
      return nullptr;
    }

    bool is_same_address(address_operator_overrided_class* right) const
    {
      return this == right;
    }
  };
}

TEST(addressof_test, disable_apply_address_operator_type)
{
  address_operator_overrided_class ad;
  ASSERT_EQ(nullptr, &ad);
  address_operator_overrided_class* ad_ptr = nek::addressof(ad);
  EXPECT_NE(nullptr, ad_ptr);
  EXPECT_TRUE(ad.is_same_address(ad_ptr));
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xrmmerge.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 15:52:07 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// global includes
#include <tools/string.hxx>

//
// XRMResParser
//

class XRMResParser
{
private:
    ByteString sGID;
    ByteString sLID;

    BOOL bError;
    BOOL bText;

    bool sLocalized;

    ByteString sCurrentOpenTag;
    ByteString sCurrentCloseTag;
    ByteString sCurrentText;
    std::vector<ByteString> aLanguages;

protected:
    ByteString GetAttribute( const ByteString &rToken, const ByteString &rAttribute );
    void Error( const ByteString &rError );

    virtual void Output( const ByteString& rOutput )=0;
    virtual void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    )=0;
    virtual void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    )=0;

    ByteString GetGID() { return sGID; }
    ByteString GetLID() { return sLID; }

    void ConvertStringToDBFormat( ByteString &rString );
    void ConvertStringToXMLFormat( ByteString &rString );

public:
    XRMResParser();
    virtual ~XRMResParser();

    int Execute( int nToken, char * pToken );

    void SetError( BOOL bErr = TRUE ) { bError = bErr; }
    BOOL GetError() { return bError; }
};

//
// class XRMResOutputParser
//

class XRMResOutputParser : public XRMResParser
{
private:
    std::vector<ByteString> aLanguages;
protected:
    SvFileStream *pOutputStream;
public:
    XRMResOutputParser ( const ByteString &rOutputFile );
    virtual ~XRMResOutputParser();
};

//
// XRMResExport
//

class XRMResExport : public XRMResOutputParser
{
private:
    ResData *pResData;
    ByteString sPrj;
    ByteString sPath;
    std::vector<ByteString> aLanguages;

protected:
    void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    );
    void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    );
    void Output( const ByteString& rOutput );

public:
    XRMResExport(
        const ByteString &rOutputFile,
        const ByteString &rProject,
        const ByteString &rFilePath
    );
    virtual ~XRMResExport();
};

//
// class XRMResMerge
//

class XRMResMerge : public XRMResOutputParser
{
private:
    MergeDataFile *pMergeDataFile;
    ByteString sFilename;
    ResData *pResData;
    std::vector<ByteString> aLanguages;

protected:
    void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    );
    void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    );
    void Output( const ByteString& rOutput );
public:
    XRMResMerge(
        const ByteString &rMergeSource,
        const ByteString &rOutputFile,
        ByteString &rFilename
    );
    virtual ~XRMResMerge();
};

<commit_msg>INTEGRATION: CWS changefileheader (1.6.72); FILE MERGED 2008/03/28 15:41:59 rt 1.6.72.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: xrmmerge.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// global includes
#include <tools/string.hxx>

//
// XRMResParser
//

class XRMResParser
{
private:
    ByteString sGID;
    ByteString sLID;

    BOOL bError;
    BOOL bText;

    bool sLocalized;

    ByteString sCurrentOpenTag;
    ByteString sCurrentCloseTag;
    ByteString sCurrentText;
    std::vector<ByteString> aLanguages;

protected:
    ByteString GetAttribute( const ByteString &rToken, const ByteString &rAttribute );
    void Error( const ByteString &rError );

    virtual void Output( const ByteString& rOutput )=0;
    virtual void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    )=0;
    virtual void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    )=0;

    ByteString GetGID() { return sGID; }
    ByteString GetLID() { return sLID; }

    void ConvertStringToDBFormat( ByteString &rString );
    void ConvertStringToXMLFormat( ByteString &rString );

public:
    XRMResParser();
    virtual ~XRMResParser();

    int Execute( int nToken, char * pToken );

    void SetError( BOOL bErr = TRUE ) { bError = bErr; }
    BOOL GetError() { return bError; }
};

//
// class XRMResOutputParser
//

class XRMResOutputParser : public XRMResParser
{
private:
    std::vector<ByteString> aLanguages;
protected:
    SvFileStream *pOutputStream;
public:
    XRMResOutputParser ( const ByteString &rOutputFile );
    virtual ~XRMResOutputParser();
};

//
// XRMResExport
//

class XRMResExport : public XRMResOutputParser
{
private:
    ResData *pResData;
    ByteString sPrj;
    ByteString sPath;
    std::vector<ByteString> aLanguages;

protected:
    void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    );
    void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    );
    void Output( const ByteString& rOutput );

public:
    XRMResExport(
        const ByteString &rOutputFile,
        const ByteString &rProject,
        const ByteString &rFilePath
    );
    virtual ~XRMResExport();
};

//
// class XRMResMerge
//

class XRMResMerge : public XRMResOutputParser
{
private:
    MergeDataFile *pMergeDataFile;
    ByteString sFilename;
    ResData *pResData;
    std::vector<ByteString> aLanguages;

protected:
    void WorkOnText(
        const ByteString &rOpenTag,
        ByteString &rText
    );
    void EndOfText(
        const ByteString &rOpenTag,
        const ByteString &rCloseTag
    );
    void Output( const ByteString& rOutput );
public:
    XRMResMerge(
        const ByteString &rMergeSource,
        const ByteString &rOutputFile,
        ByteString &rFilename
    );
    virtual ~XRMResMerge();
};

<|endoftext|>


<commit_before>#ifndef UTILS_MAPCSSUTILS_HPP_DEFINED
#define UTILS_MAPCSSUTILS_HPP_DEFINED

#include "Exceptions.hpp"
#include "entities/Element.hpp"
#include "index/StringTable.hpp"
#include "mapcss/Style.hpp"
#include "utils/GeoUtils.hpp"

#include <string>

namespace utymap { namespace utils {

    // Checks whether key exists.
    inline bool hasKey(const std::string& key,
                       utymap::index::StringTable& stringTable,
                       const utymap::mapcss::Style& style)
    {
        return style.has(stringTable.getId(key));
    }

    // Gets raw declaration value as string.
    inline std::shared_ptr<std::string> getString(const std::string& key,
                                                  utymap::index::StringTable& stringTable,
                                                  const utymap::mapcss::Style& style,
                                                  const std::string& defaultValue = "")
    {
        uint32_t keyId = stringTable.getId(key);
        return style.has(keyId)
            ? style.get(keyId)->value()
            : std::shared_ptr<std::string>(new std::string(defaultValue));
    }

    // Gets declaration value as double. Evaluates if necessary.
    inline double getDouble(const std::string& key,
                            const std::vector<utymap::entities::Tag>& tags,
                            utymap::index::StringTable& stringTable,
                            const utymap::mapcss::Style& style)
    {
        uint32_t keyId = stringTable.getId(key);
        return style.get(keyId)->evaluate(tags, stringTable);
    }

    // Gets declaration value as double without evaluation.
    inline double getDouble(const std::string& key,
                            utymap::index::StringTable& stringTable,
                            const utymap::mapcss::Style& style,
                            double defaultValue = 0)
    {
        uint32_t keyId = stringTable.getId(key);
        return style.has(keyId)
            ? std::stod(*style.get(keyId)->value())
            : defaultValue;
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(uint32_t keyId,
                               utymap::index::StringTable& stringTable,
                               const utymap::mapcss::Style& style,
                               double size,
                               const utymap::GeoCoordinate& coordinate)
    {
        auto declaration = style.get(keyId);
        auto rawValue = declaration->value();

        char dimen = (*rawValue)[rawValue->size() - 1];
        double value = std::stod(rawValue->substr(0, rawValue->size() - 1));

        // defined in meters: use raw value
        if (dimen == 'm' && coordinate.latitude != 90)
            return coordinate.isValid() ? GeoUtils::getOffset(coordinate, value) : value;

        // relative to size
        if (dimen == '%')
            return size * value * 0.01;

        throw utymap::MapCssException("Unknown width dimension.");
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(const std::string& key,
                               utymap::index::StringTable& stringTable,
                               const utymap::mapcss::Style& style,
                               double size,
                               double defaultValue,
                               const utymap::GeoCoordinate& coordinate = GeoCoordinate())
    {
        uint32_t keyId = stringTable.getId(key);
        if (!style.has(keyId))
            return defaultValue;

        return getDimension(keyId, stringTable, style, size, coordinate);
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(const std::string& key,
                               utymap::index::StringTable& stringTable,
                               const utymap::mapcss::Style& style,
                               double size,
                               const utymap::GeoCoordinate& coordinate = GeoCoordinate())
    {
        return getDimension(stringTable.getId(key), stringTable, style, size, coordinate);
    }
}}

#endif // UTILS_MAPCSSUTILS_HPP_DEFINED
<commit_msg>core: refactor MapCssUtils.getDimension<commit_after>#ifndef UTILS_MAPCSSUTILS_HPP_DEFINED
#define UTILS_MAPCSSUTILS_HPP_DEFINED

#include "Exceptions.hpp"
#include "entities/Element.hpp"
#include "index/StringTable.hpp"
#include "mapcss/Style.hpp"
#include "utils/GeoUtils.hpp"

#include <string>

namespace utymap { namespace utils {

    // Checks whether key exists.
    inline bool hasKey(const std::string& key,
                       utymap::index::StringTable& stringTable,
                       const utymap::mapcss::Style& style)
    {
        return style.has(stringTable.getId(key));
    }

    // Gets raw declaration value as string.
    inline std::shared_ptr<std::string> getString(const std::string& key,
                                                  utymap::index::StringTable& stringTable,
                                                  const utymap::mapcss::Style& style,
                                                  const std::string& defaultValue = "")
    {
        uint32_t keyId = stringTable.getId(key);
        return style.has(keyId)
            ? style.get(keyId)->value()
            : std::shared_ptr<std::string>(new std::string(defaultValue));
    }

    // Gets declaration value as double. Evaluates if necessary.
    inline double getDouble(const std::string& key,
                            const std::vector<utymap::entities::Tag>& tags,
                            utymap::index::StringTable& stringTable,
                            const utymap::mapcss::Style& style)
    {
        uint32_t keyId = stringTable.getId(key);
        return style.get(keyId)->evaluate(tags, stringTable);
    }

    // Gets declaration value as double without evaluation.
    inline double getDouble(const std::string& key,
                            utymap::index::StringTable& stringTable,
                            const utymap::mapcss::Style& style,
                            double defaultValue = 0)
    {
        uint32_t keyId = stringTable.getId(key);
        return style.has(keyId)
            ? std::stod(*style.get(keyId)->value())
            : defaultValue;
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(uint32_t keyId,
                               const utymap::mapcss::Style& style,
                               double size,
                               const utymap::GeoCoordinate& coordinate)
    {
        auto declaration = style.get(keyId);
        auto rawValue = declaration->value();

        char dimen = (*rawValue)[rawValue->size() - 1];
        double value = std::stod(rawValue->substr(0, rawValue->size() - 1));

        // defined in meters: use raw value
        if (dimen == 'm' && coordinate.latitude != 90)
            return coordinate.isValid() ? GeoUtils::getOffset(coordinate, value) : value;

        // relative to size
        if (dimen == '%')
            return size * value * 0.01;

        throw utymap::MapCssException("Unknown width dimension.");
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(const std::string& key,
                               utymap::index::StringTable& stringTable,
                               const utymap::mapcss::Style& style,
                               double size,
                               double defaultValue,
                               const utymap::GeoCoordinate& coordinate = GeoCoordinate())
    {
        uint32_t keyId = stringTable.getId(key);
        if (!style.has(keyId))
            return defaultValue;

        return getDimension(keyId, style, size, coordinate);
    }

    // Gets dimension value. Evaluation is not supported.
    inline double getDimension(const std::string& key,
                               utymap::index::StringTable& stringTable,
                               const utymap::mapcss::Style& style,
                               double size,
                               const utymap::GeoCoordinate& coordinate = GeoCoordinate())
    {
        return getDimension(stringTable.getId(key), style, size, coordinate);
    }
}}

#endif // UTILS_MAPCSSUTILS_HPP_DEFINED
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fragmenthandler.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2008-01-17 08:05:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef OOX_CORE_FRAGMENTHANDLER_HXX
#define OOX_CORE_FRAGMENTHANDLER_HXX

#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
#include <cppuhelper/implbase1.hxx>
#include "oox/core/recordcontext.hxx"
#include "oox/core/relations.hxx"
#include "oox/core/xmlfilterbase.hxx"

namespace oox {
namespace core {

class RecordParser;

// ============================================================================

class FragmentHandler : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastDocumentHandler >, public RecordContext
{
public:
    explicit            FragmentHandler( const XmlFilterRef& rxFilter, const ::rtl::OUString& rFragmentPath );
    explicit            FragmentHandler( const XmlFilterRef& rxFilter, const ::rtl::OUString& rFragmentPath, RelationsRef xRelations );

    /** Returns the filter instance. */
    inline const XmlFilterRef& getFilter() const { return mxFilter; }
    /** Returns the full fragment path containing these relations. */
    inline const Relations& getRelations() const { return *mxRelations; }
    /** Returns the full fragment path containing these relations. */
    inline const ::rtl::OUString& getFragmentPath() const { return maFragmentPath; }

    /** Returns the full fragment path for the passed relative target. */
    ::rtl::OUString     getFragmentPathFromTarget( const ::rtl::OUString& rTarget ) const;
    /** Returns the full fragment path for the passed relation identifier. */
    ::rtl::OUString     getFragmentPathFromRelId( const ::rtl::OUString& rRelId ) const;
    /** Returns the full fragment path for the passed type. */
    ::rtl::OUString     getFragmentPathFromType( const ::rtl::OUString& rType ) const;

    /** Sets the record parser used to import binary streams. */
    void                setRecordParser( RecordParser& rParser );

    /** Returns access to the record parser used to import binary streams.

        Needed for direct manipulation of the parser context stack via
        RecordParser::pushContext() and RecordParser::popContext().

        Must not be called while loading XML fragments.
     */
    RecordParser&       getRecordParser();

    // resolve ambiguity from base classes
    virtual void SAL_CALL acquire() throw() { ::cppu::OWeakObject::acquire(); }
    virtual void SAL_CALL release() throw() { ::cppu::OWeakObject::release(); }

    // com.sun.star.xml.sax.XFastDocumentHandler interface --------------------

    virtual void SAL_CALL startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& xLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

    // com.sun.star.xml.sax.XFastContextHandler interface ---------------------

    virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

private:
    XmlFilterRef        mxFilter;
    RelationsRef        mxRelations;
    ::rtl::OUString     maFragmentPath;
    ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator > mxLocator;
    RecordParser*       mpParser;           /// Pointer to record parser for binary import.
};

typedef ::rtl::Reference< FragmentHandler > FragmentHandlerRef;

// ============================================================================

} // namespace core
} // namespace oox

#endif // OOX_CORE_FRAGMENTHANDLER_HXX

<commit_msg>INTEGRATION: CWS xmlfilter03_DEV300 (1.2.4); FILE MERGED 2008/02/07 13:40:49 dr 1.2.4.5: add fragment base path to relations 2008/02/05 14:05:05 dr 1.2.4.4: oox::core::ContextHandler2 and oox::core::FragmentHandler2 for convenience 2008/02/04 13:31:15 dr 1.2.4.3: rework of fragment handler/context handler base classes 2008/02/01 09:53:54 dr 1.2.4.2: addShape() code cleanup, started xlsx drawing import 2008/01/24 14:56:40 dr 1.2.4.1: OOBIN additions, BIFF string handling<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fragmenthandler.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 17:34:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef OOX_CORE_FRAGMENTHANDLER_HXX
#define OOX_CORE_FRAGMENTHANDLER_HXX

#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
#include <cppuhelper/implbase1.hxx>
#include "oox/core/contexthandler.hxx"
#include "oox/core/relations.hxx"

namespace oox {
namespace core {

// ============================================================================

/** Base data of a fragment.

    This data is stored in a separate struct to make it accessible in every
    child context handler of the fragment.
 */
struct FragmentBaseData
{
    XmlFilterBase&      mrFilter;
    const ::rtl::OUString maFragmentPath;
    ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >
                        mxLocator;
    RelationsRef        mxRelations;

    explicit            FragmentBaseData(
                            XmlFilterBase& rFilter,
                            const ::rtl::OUString& rFragmentPath,
                            RelationsRef xRelations );
};

// ============================================================================

/** Describes record identifiers used to create contexts in a binary stream.

    If a record is used to start a new context, usually the record identifier
    increased by 1 is used to mark the end of this context, e.g. the Excel
    record SHEETDATA == 0x0091 starts the <sheetData> context, and the record
    SHEETDATA_END == 0x0092 ends this context. But some records are used to
    start a new context, though there is no identifier to end this context,
    e.g. the ROW or EXTROW records. These record identifiers can be marked by
    setting the mnEndRecId member of this struct to -1.
 */
struct RecordInfo
{
    sal_Int32           mnStartRecId;       /// Record identifier for context start.
    sal_Int32           mnEndRecId;         /// Record identifier for context end, -1 = no record.
};

// ============================================================================

typedef ::cppu::ImplInheritanceHelper1< ContextHandler, ::com::sun::star::xml::sax::XFastDocumentHandler > FragmentHandlerImplBase;

class FragmentHandler : public FragmentHandlerImplBase
{
public:
    explicit            FragmentHandler( XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath );
    virtual             ~FragmentHandler();

    /** Returns the com.sun.star.xml.sax.XFastContextHandler interface of this context. */
    inline ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler >
                        getFastContextHandler() { return static_cast< ContextHandler* >( this ); }

    // com.sun.star.xml.sax.XFastDocumentHandler interface --------------------

    virtual void SAL_CALL startDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endDocument() throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setDocumentLocator( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XLocator >& rxLocator ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

    // com.sun.star.xml.sax.XFastContextHandler interface ---------------------

    virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

    // binary records ---------------------------------------------------------

    virtual const RecordInfo* getRecordInfos() const;

protected:
    explicit            FragmentHandler( XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath, RelationsRef xRelations );
};

typedef ::rtl::Reference< FragmentHandler > FragmentHandlerRef;

// ============================================================================

} // namespace core
} // namespace oox

#endif

<|endoftext|>


<commit_before>// @(#)root/textinput:$Id$
// Author: Axel Naumann <axel@cern.ch>, 2011-05-21

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Getline.h"

#include <algorithm>
#include <string>
#include <sstream>
#include "textinput/TextInput.h"
#include "textinput/TextInputContext.h"
#include "textinput/History.h"
#include "textinput/TerminalDisplay.h"
#include "textinput/StreamReader.h"
#include "textinput/Callbacks.h"
#include "Getline_color.h"
#include "TApplication.h"

extern "C" {
   int (* Gl_in_key)(int ch) = 0;
   int (* Gl_beep_hook)() = 0;
}

using namespace textinput;

namespace {
   // TTabCom adapter.
   class ROOTTabCompletion: public TabCompletion {
   public:
      ROOTTabCompletion(): fLineBuf(new char[fgLineBufSize]) {}
      virtual ~ROOTTabCompletion() { delete []fLineBuf; }

      ROOTTabCompletion(const ROOTTabCompletion&) = delete;
      ROOTTabCompletion& operator=(const ROOTTabCompletion&) = delete;

      // Returns false on error
      bool Complete(Text& line /*in+out*/, size_t& cursor /*in+out*/,
                    EditorRange& r /*out*/,
                    std::vector<std::string>& displayCompletions /*out*/) {
         strlcpy(fLineBuf, line.GetText().c_str(), fgLineBufSize);
         int cursorInt = (int) cursor;
         std::stringstream sstr;
         size_t posFirstChange = gApplication->TabCompletionHook(fLineBuf, &cursorInt, sstr);
         if (posFirstChange == (size_t) -1) {
            // no change
            return true;
         }

         line = std::string(fLineBuf);
         std::string compLine;
         while (std::getline(sstr, compLine)) {
            displayCompletions.push_back(compLine);
         }
         std::sort(displayCompletions.begin(), displayCompletions.end());

         size_t lenLineBuf = strlen(fLineBuf);
         if (posFirstChange == (size_t) -2) {
            // redraw whole line, incl prompt
            r.fEdit.Extend(Range::AllWithPrompt());
            r.fDisplay.Extend(Range::AllWithPrompt());
         } else {
            if (!lenLineBuf) {
               r.fEdit.Extend(Range::AllText());
               r.fDisplay.Extend(Range::AllText());
            } else {
               r.fEdit.Extend(Range(posFirstChange, Range::End()));
               r.fDisplay.Extend(Range(posFirstChange, Range::End()));
            }
         }
         cursor = (size_t)cursorInt;
         line.GetColors().resize(lenLineBuf);
         return true;
      }
   private:
      static const size_t fgLineBufSize;
      char* fLineBuf;
   };
   const size_t ROOTTabCompletion::fgLineBufSize = 16*1024;

   class TClingTabCompletion: public TabCompletion {
   public:
      TClingTabCompletion() {}
      virtual ~TClingTabCompletion() {}

      TClingTabCompletion(const TClingTabCompletion&) = delete;
      TClingTabCompletion& operator=(const TClingTabCompletion&) = delete;

      // Returns false on error
      bool Complete(Text& line /*in+out*/, size_t& cursor /*in+out*/,
                    EditorRange& r /*out*/,
                    std::vector<std::string>& completions /*out*/) {
         gInterpreter->CodeComplete(line.GetText(), cursor, completions);
         return true;
      }
   };

   // Helper to define the lifetime of the TextInput singleton.
   class TextInputHolder {
   public:
      TextInputHolder():
         fTextInput(*(fReader = StreamReader::Create()),
                    *(fDisplay = TerminalDisplay::Create()),
                    fgHistoryFile.c_str()) {
         fTextInput.SetColorizer(&fCol);
         fTextInput.SetCompletion(&fTabComp);
         fTextInput.EnableAutoHistAdd(false);
         History* Hist = fTextInput.GetContext()->GetHistory();
         Hist->SetMaxDepth(fgSizeLines);
         Hist->SetPruneLength(fgSaveLines);
      }

      ~TextInputHolder() {
         // Delete allocated objects.
         delete fReader;
         delete fDisplay;
      }

      const char* TakeInput(bool force = false) {
         fTextInput.TakeInput(fInputLine, force);
         fInputLine += "\n"; // ROOT wants a trailing newline.
         return fInputLine.c_str();
      }

      void SetColors(const char* colorTab, const char* colorTabComp,
                     const char* colorBracket, const char* colorBadBracket,
                     const char* colorPrompt) {
         fCol.SetColors(colorTab, colorTabComp, colorBracket, colorBadBracket,
                        colorPrompt);
      }

      static void SetHistoryFile(const char* hist) {
         fgHistoryFile = hist;
      }
      static void SetHistSize(int size, int save) {
         fgSizeLines = size;
         fgSaveLines = save;
      }

      static TextInputHolder& getHolder() {
         // Controls initialization of static TextInput.
         static TextInputHolder sTIHolder;
         return sTIHolder;
      }

      static TextInput& get() {
         return getHolder().fTextInput;
      }

   private:
      TextInput fTextInput; // The singleton TextInput object.
      Display* fDisplay; // Default TerminalDisplay
      Reader* fReader; // Default StreamReader
      std::string fInputLine; // Taken from TextInput
      ROOT::TextInputColorizer fCol; // Colorizer
      ROOTTabCompletion fTabComp; // Tab completion handler / TTabCom adapter

      // Config values:
      static std::string fgHistoryFile;
      // # History file size, once HistSize is reached remove all but HistSave entries,
      // # set to 0 to turn off command recording.
      // # Can be overridden by environment variable ROOT_HIST=size[:save],
      // # the ":save" part is optional.
      // # Rint.HistSize:         500
      // # Set to -1 for sensible default (80% of HistSize), set to 0 to disable history.
      // # Rint.HistSave:         400
      static int fgSizeLines;
      static int fgSaveLines;
   };

   int TextInputHolder::fgSizeLines = 500;
   int TextInputHolder::fgSaveLines = -1;
   std::string TextInputHolder::fgHistoryFile;
}

/************************ extern "C" part *********************************/

extern "C" {
void
Gl_config(const char* which, int value) {
   if (strcmp(which, "noecho") == 0) {
      TextInputHolder::get().MaskInput(value);
   } else {
      // unsupported directive
      printf("Gl_config unsupported: %s ?\n", which);
   }
}

void
Gl_histadd(const char* buf) {
   TextInputHolder::get().AddHistoryLine(buf);
}

/* Wrapper around textinput.
 * Modes: -1 = init, 0 = line mode, 1 = one char at a time mode, 2 = cleanup, 3 = clear input line
 */
const char*
Getlinem(EGetLineMode mode, const char* prompt) {

   if (mode == kClear) {
      TextInputHolder::getHolder().TakeInput(true);
      return 0;
   }

   if (mode == kCleanUp) {
      TextInputHolder::get().ReleaseInputOutput();
      return 0;
   }

   if (mode == kOneChar) {
      // Check first display: if !TTY, read full line.
      const textinput::Display* disp
         = TextInputHolder::get().GetContext()->GetDisplays()[0];
      const textinput::TerminalDisplay* tdisp = 0;
      if (disp) tdisp = dynamic_cast<const textinput::TerminalDisplay*>(disp);
      if (tdisp && !tdisp->IsTTY()) {
         mode = kLine1;
      }
   }

   if (mode == kInit || mode == kLine1) {
      if (prompt) {
         TextInputHolder::get().SetPrompt(prompt);
      }
      // Trigger attach:
      TextInputHolder::get().Redraw();
      if (mode == kInit) {
         return 0;
      }
      TextInputHolder::get().SetBlockingUntilEOL();
   } else {
      // mode == kOneChar
      if (Gl_in_key) {
         // We really need to go key by key:
         TextInputHolder::get().SetMaxPendingCharsToRead(1);
      } else {
         // Can consume all pending characters
         TextInputHolder::get().SetReadingAllPendingChars();
      }
   }

   TextInput::EReadResult res = TextInputHolder::get().ReadInput();
   if (Gl_in_key) {
      (*Gl_in_key)(TextInputHolder::get().GetLastKey());
   }
   if (res == TextInput::kRRReadEOLDelimiter) {
      return TextInputHolder::getHolder().TakeInput();
   } else if (res == TextInput::kRREOF) {
      // ROOT expects "" and then Gl_eol() returning true
      return "";
   }

   return NULL;
}

const char*
Getline(const char* prompt) {
   // Get a line of user input, showing prompt.
   // Does not return after every character entered, but
   // only returns once the user has hit return.
   // For ROOT Getline.c backward compatibility reasons,
   // the returned value is volatile and will be overwritten
   // by the subsequent call to Getline() or Getlinem(),
   // so copy the string if it needs to stay around.
   // The returned value must not be deleted.
   // The returned string contains a trailing newline '\n'.

   return Getlinem(kLine1, prompt);
}

/******************* Simple C -> C++ forwards *********************************/

void
Gl_histsize(int size, int save) {
   TextInputHolder::SetHistSize(size, save);
}

void
Gl_histinit(const char* file) {
   // Has to be called before constructing TextInputHolder singleton.
   TextInputHolder::SetHistoryFile(file);
}

int
Gl_eof() {
   return TextInputHolder::get().GetReadState() == TextInput::kRREOF;
}

void
Gl_setColors(const char* colorTab, const char* colorTabComp, const char* colorBracket,
             const char* colorBadBracket, const char* colorPrompt) {
   // call to enhance.cxx to set colours
   TextInputHolder::getHolder().SetColors(colorTab, colorTabComp, colorBracket,
                                          colorBadBracket, colorPrompt);
}

/******************** Superseded interface *********************************/

void Gl_setwidth(int /*w*/) {
   // ignored, handled by displays themselves.
}

void Gl_windowchanged() {
   // ignored, handled by displays themselves.
}

} // extern "C"
<commit_msg>Comment out unused parameter<commit_after>// @(#)root/textinput:$Id$
// Author: Axel Naumann <axel@cern.ch>, 2011-05-21

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Getline.h"

#include <algorithm>
#include <string>
#include <sstream>
#include "textinput/TextInput.h"
#include "textinput/TextInputContext.h"
#include "textinput/History.h"
#include "textinput/TerminalDisplay.h"
#include "textinput/StreamReader.h"
#include "textinput/Callbacks.h"
#include "Getline_color.h"
#include "TApplication.h"

extern "C" {
   int (* Gl_in_key)(int ch) = 0;
   int (* Gl_beep_hook)() = 0;
}

using namespace textinput;

namespace {
   // TTabCom adapter.
   class ROOTTabCompletion: public TabCompletion {
   public:
      ROOTTabCompletion(): fLineBuf(new char[fgLineBufSize]) {}
      virtual ~ROOTTabCompletion() { delete []fLineBuf; }

      ROOTTabCompletion(const ROOTTabCompletion&) = delete;
      ROOTTabCompletion& operator=(const ROOTTabCompletion&) = delete;

      // Returns false on error
      bool Complete(Text& line /*in+out*/, size_t& cursor /*in+out*/,
                    EditorRange& r /*out*/,
                    std::vector<std::string>& displayCompletions /*out*/) {
         strlcpy(fLineBuf, line.GetText().c_str(), fgLineBufSize);
         int cursorInt = (int) cursor;
         std::stringstream sstr;
         size_t posFirstChange = gApplication->TabCompletionHook(fLineBuf, &cursorInt, sstr);
         if (posFirstChange == (size_t) -1) {
            // no change
            return true;
         }

         line = std::string(fLineBuf);
         std::string compLine;
         while (std::getline(sstr, compLine)) {
            displayCompletions.push_back(compLine);
         }
         std::sort(displayCompletions.begin(), displayCompletions.end());

         size_t lenLineBuf = strlen(fLineBuf);
         if (posFirstChange == (size_t) -2) {
            // redraw whole line, incl prompt
            r.fEdit.Extend(Range::AllWithPrompt());
            r.fDisplay.Extend(Range::AllWithPrompt());
         } else {
            if (!lenLineBuf) {
               r.fEdit.Extend(Range::AllText());
               r.fDisplay.Extend(Range::AllText());
            } else {
               r.fEdit.Extend(Range(posFirstChange, Range::End()));
               r.fDisplay.Extend(Range(posFirstChange, Range::End()));
            }
         }
         cursor = (size_t)cursorInt;
         line.GetColors().resize(lenLineBuf);
         return true;
      }
   private:
      static const size_t fgLineBufSize;
      char* fLineBuf;
   };
   const size_t ROOTTabCompletion::fgLineBufSize = 16*1024;

   class TClingTabCompletion: public TabCompletion {
   public:
      TClingTabCompletion() {}
      virtual ~TClingTabCompletion() {}

      TClingTabCompletion(const TClingTabCompletion&) = delete;
      TClingTabCompletion& operator=(const TClingTabCompletion&) = delete;

      // Returns false on error
      bool Complete(Text& line /*in+out*/, size_t& cursor /*in+out*/,
                    EditorRange& /* r */ /*out*/,
                    std::vector<std::string>& completions /*out*/) {
         gInterpreter->CodeComplete(line.GetText(), cursor, completions);
         return true;
      }
   };

   // Helper to define the lifetime of the TextInput singleton.
   class TextInputHolder {
   public:
      TextInputHolder():
         fTextInput(*(fReader = StreamReader::Create()),
                    *(fDisplay = TerminalDisplay::Create()),
                    fgHistoryFile.c_str()) {
         fTextInput.SetColorizer(&fCol);
         fTextInput.SetCompletion(&fTabComp);
         fTextInput.EnableAutoHistAdd(false);
         History* Hist = fTextInput.GetContext()->GetHistory();
         Hist->SetMaxDepth(fgSizeLines);
         Hist->SetPruneLength(fgSaveLines);
      }

      ~TextInputHolder() {
         // Delete allocated objects.
         delete fReader;
         delete fDisplay;
      }

      const char* TakeInput(bool force = false) {
         fTextInput.TakeInput(fInputLine, force);
         fInputLine += "\n"; // ROOT wants a trailing newline.
         return fInputLine.c_str();
      }

      void SetColors(const char* colorTab, const char* colorTabComp,
                     const char* colorBracket, const char* colorBadBracket,
                     const char* colorPrompt) {
         fCol.SetColors(colorTab, colorTabComp, colorBracket, colorBadBracket,
                        colorPrompt);
      }

      static void SetHistoryFile(const char* hist) {
         fgHistoryFile = hist;
      }
      static void SetHistSize(int size, int save) {
         fgSizeLines = size;
         fgSaveLines = save;
      }

      static TextInputHolder& getHolder() {
         // Controls initialization of static TextInput.
         static TextInputHolder sTIHolder;
         return sTIHolder;
      }

      static TextInput& get() {
         return getHolder().fTextInput;
      }

   private:
      TextInput fTextInput; // The singleton TextInput object.
      Display* fDisplay; // Default TerminalDisplay
      Reader* fReader; // Default StreamReader
      std::string fInputLine; // Taken from TextInput
      ROOT::TextInputColorizer fCol; // Colorizer
      ROOTTabCompletion fTabComp; // Tab completion handler / TTabCom adapter

      // Config values:
      static std::string fgHistoryFile;
      // # History file size, once HistSize is reached remove all but HistSave entries,
      // # set to 0 to turn off command recording.
      // # Can be overridden by environment variable ROOT_HIST=size[:save],
      // # the ":save" part is optional.
      // # Rint.HistSize:         500
      // # Set to -1 for sensible default (80% of HistSize), set to 0 to disable history.
      // # Rint.HistSave:         400
      static int fgSizeLines;
      static int fgSaveLines;
   };

   int TextInputHolder::fgSizeLines = 500;
   int TextInputHolder::fgSaveLines = -1;
   std::string TextInputHolder::fgHistoryFile;
}

/************************ extern "C" part *********************************/

extern "C" {
void
Gl_config(const char* which, int value) {
   if (strcmp(which, "noecho") == 0) {
      TextInputHolder::get().MaskInput(value);
   } else {
      // unsupported directive
      printf("Gl_config unsupported: %s ?\n", which);
   }
}

void
Gl_histadd(const char* buf) {
   TextInputHolder::get().AddHistoryLine(buf);
}

/* Wrapper around textinput.
 * Modes: -1 = init, 0 = line mode, 1 = one char at a time mode, 2 = cleanup, 3 = clear input line
 */
const char*
Getlinem(EGetLineMode mode, const char* prompt) {

   if (mode == kClear) {
      TextInputHolder::getHolder().TakeInput(true);
      return 0;
   }

   if (mode == kCleanUp) {
      TextInputHolder::get().ReleaseInputOutput();
      return 0;
   }

   if (mode == kOneChar) {
      // Check first display: if !TTY, read full line.
      const textinput::Display* disp
         = TextInputHolder::get().GetContext()->GetDisplays()[0];
      const textinput::TerminalDisplay* tdisp = 0;
      if (disp) tdisp = dynamic_cast<const textinput::TerminalDisplay*>(disp);
      if (tdisp && !tdisp->IsTTY()) {
         mode = kLine1;
      }
   }

   if (mode == kInit || mode == kLine1) {
      if (prompt) {
         TextInputHolder::get().SetPrompt(prompt);
      }
      // Trigger attach:
      TextInputHolder::get().Redraw();
      if (mode == kInit) {
         return 0;
      }
      TextInputHolder::get().SetBlockingUntilEOL();
   } else {
      // mode == kOneChar
      if (Gl_in_key) {
         // We really need to go key by key:
         TextInputHolder::get().SetMaxPendingCharsToRead(1);
      } else {
         // Can consume all pending characters
         TextInputHolder::get().SetReadingAllPendingChars();
      }
   }

   TextInput::EReadResult res = TextInputHolder::get().ReadInput();
   if (Gl_in_key) {
      (*Gl_in_key)(TextInputHolder::get().GetLastKey());
   }
   if (res == TextInput::kRRReadEOLDelimiter) {
      return TextInputHolder::getHolder().TakeInput();
   } else if (res == TextInput::kRREOF) {
      // ROOT expects "" and then Gl_eol() returning true
      return "";
   }

   return NULL;
}

const char*
Getline(const char* prompt) {
   // Get a line of user input, showing prompt.
   // Does not return after every character entered, but
   // only returns once the user has hit return.
   // For ROOT Getline.c backward compatibility reasons,
   // the returned value is volatile and will be overwritten
   // by the subsequent call to Getline() or Getlinem(),
   // so copy the string if it needs to stay around.
   // The returned value must not be deleted.
   // The returned string contains a trailing newline '\n'.

   return Getlinem(kLine1, prompt);
}

/******************* Simple C -> C++ forwards *********************************/

void
Gl_histsize(int size, int save) {
   TextInputHolder::SetHistSize(size, save);
}

void
Gl_histinit(const char* file) {
   // Has to be called before constructing TextInputHolder singleton.
   TextInputHolder::SetHistoryFile(file);
}

int
Gl_eof() {
   return TextInputHolder::get().GetReadState() == TextInput::kRREOF;
}

void
Gl_setColors(const char* colorTab, const char* colorTabComp, const char* colorBracket,
             const char* colorBadBracket, const char* colorPrompt) {
   // call to enhance.cxx to set colours
   TextInputHolder::getHolder().SetColors(colorTab, colorTabComp, colorBracket,
                                          colorBadBracket, colorPrompt);
}

/******************** Superseded interface *********************************/

void Gl_setwidth(int /*w*/) {
   // ignored, handled by displays themselves.
}

void Gl_windowchanged() {
   // ignored, handled by displays themselves.
}

} // extern "C"
<|endoftext|>


<commit_before>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>

#ifdef SPARROW_DEBUG
# define CHECK(cond, msg) do {\
    if (!(cond)) {\
      std::cerr\
        << "[" << __FILE__ << ":" << __LINE__ << "] "\
        << "CHECKING FAILED: " << __func__ << "() - " << (msg) << std::endl;\
      std::abort();\
    }\
  } while (false)
#else
# define CHECK(cond, msg) ((void)0)
#endif

#define UNREACHED() do {\
  std::cerr\
    << "[" << __FILE__ << ":" << __LINE__ << "] "\
    << "UNREACHED: " << __func__ << "()" << std::endl;\
  while (true) {}\
} while (false)

namespace sparrow {

using nil_t   = std::nullptr_t;
using byte_t  = std::uint8_t;
using ssz_t   = std::int32_t;
using sz_t    = std::size_t;
using i8_t    = std::int8_t;
using u8_t    = std::uint8_t;
using i16_t   = std::int16_t;
using u16_t   = std::uint16_t;
using i32_t   = std::int32_t;
using u32_t   = std::uint32_t;
using i64_t   = std::int64_t;
using u64_t   = std::uint64_t;
using str_t   = std::string;

class Copyable {
protected:
  Copyable(void) noexcept = default;
  ~Copyable(void) noexcept = default;
};

class UnCopyable {
  UnCopyable(const UnCopyable&) = delete;
  UnCopyable& operator=(const UnCopyable&) = delete;
};

namespace Xt {
  // Xtra utilities
  template <typename I, typename E>
  inline I as_int(E x) { return static_cast<I>(x); }

  template <typename E, typename I>
  inline E as_enum(I x) { return static_cast<E>(x); }

  template <typename T>
  inline u8_t as_u8(T x) { return static_cast<u8_t>(x); }

  template <typename T> inline void* as_address(T* x) {
    return reinterpret_cast<void*>(x);
  }

  template <typename T> inline const void* as_address(const T* x) {
    return reinterpret_cast<const void*>(x);
  }

  template <typename T> inline byte_t* as_bytes(T* x) {
    return reinterpret_cast<byte_t*>(x);
  }

  template <typename T> inline const byte_t* as_bytes(const T* x) {
    return reinterpret_cast<const byte_t*>(x);
  }

  template <typename Target, typename Source> inline Target* cast(Source* x) {
    return static_cast<Target*>(x);
  }

  template <typename Target, typename Source> inline Target* down(Source* x) {
    return dynamic_cast<Target*>(x);
  }
}

enum class ErrType {
  IO,
  MEMORY,
  LEXICAL,
  COMPILE,
  RUNTIME,
};

void error_report(ErrType type,
    const char* fname, int line, const char* func, const char* format, ...);

}

#define IO_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::IO, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define MEM_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::MEMORY, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define LEX_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::LEXICAL, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define COMPILE_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::COMPILE, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define RUNTIME_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::RUNTIME, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
<commit_msg>:bug: fix(uncopyable): fixed uncopyable constructor<commit_after>// Copyright (c) 2019 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#pragma once

#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>

#ifdef SPARROW_DEBUG
# define CHECK(cond, msg) do {\
    if (!(cond)) {\
      std::cerr\
        << "[" << __FILE__ << ":" << __LINE__ << "] "\
        << "CHECKING FAILED: " << __func__ << "() - " << (msg) << std::endl;\
      std::abort();\
    }\
  } while (false)
#else
# define CHECK(cond, msg) ((void)0)
#endif

#define UNREACHED() do {\
  std::cerr\
    << "[" << __FILE__ << ":" << __LINE__ << "] "\
    << "UNREACHED: " << __func__ << "()" << std::endl;\
  while (true) {}\
} while (false)

namespace sparrow {

using nil_t   = std::nullptr_t;
using byte_t  = std::uint8_t;
using ssz_t   = std::int32_t;
using sz_t    = std::size_t;
using i8_t    = std::int8_t;
using u8_t    = std::uint8_t;
using i16_t   = std::int16_t;
using u16_t   = std::uint16_t;
using i32_t   = std::int32_t;
using u32_t   = std::uint32_t;
using i64_t   = std::int64_t;
using u64_t   = std::uint64_t;
using str_t   = std::string;

class Copyable {
protected:
  Copyable(void) noexcept = default;
  ~Copyable(void) noexcept = default;
};

class UnCopyable {
  UnCopyable(const UnCopyable&) = delete;
  UnCopyable& operator=(const UnCopyable&) = delete;
protected:
  UnCopyable(void) noexcept = default;
  ~UnCopyable(void) noexcept = default;
};

namespace Xt {
  // Xtra utilities
  template <typename I, typename E>
  inline I as_int(E x) { return static_cast<I>(x); }

  template <typename E, typename I>
  inline E as_enum(I x) { return static_cast<E>(x); }

  template <typename T>
  inline u8_t as_u8(T x) { return static_cast<u8_t>(x); }

  template <typename T> inline void* as_address(T* x) {
    return reinterpret_cast<void*>(x);
  }

  template <typename T> inline const void* as_address(const T* x) {
    return reinterpret_cast<const void*>(x);
  }

  template <typename T> inline byte_t* as_bytes(T* x) {
    return reinterpret_cast<byte_t*>(x);
  }

  template <typename T> inline const byte_t* as_bytes(const T* x) {
    return reinterpret_cast<const byte_t*>(x);
  }

  template <typename Target, typename Source> inline Target* cast(Source* x) {
    return static_cast<Target*>(x);
  }

  template <typename Target, typename Source> inline Target* down(Source* x) {
    return dynamic_cast<Target*>(x);
  }
}

enum class ErrType {
  IO,
  MEMORY,
  LEXICAL,
  COMPILE,
  RUNTIME,
};

void error_report(ErrType type,
    const char* fname, int line, const char* func, const char* format, ...);

}

#define IO_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::IO, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define MEM_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::MEMORY, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define LEX_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::LEXICAL, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define COMPILE_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::COMPILE, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
#define RUNTIME_ERR(fmt, ...) sparrow::error_report(\
    sparrow::ErrType::RUNTIME, __FILE__, __LINE__, __func__, (fmt), ##__VA_ARGS__)
<|endoftext|>