<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2016 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "client_state.hh"
#include "auth/authorizer.hh"
#include "auth/authenticator.hh"
#include "auth/common.hh"
#include "auth/resource.hh"
#include "exceptions/exceptions.hh"
#include "validation.hh"
#include "db/system_keyspace.hh"
#include "db/schema_tables.hh"
#include "tracing/trace_keyspace_helper.hh"
#include "storage_service.hh"

void service::client_state::set_login(::shared_ptr<auth::authenticated_user> user) {
    if (user == nullptr) {
        throw std::invalid_argument("Must provide user");
    }
    _user = std::move(user);
    if (_is_request_copy) {
        _user_is_dirty = true;
    }
}

future<> service::client_state::check_user_exists() {
    if (auth::is_anonymous(*_user)) {
        return make_ready_future();
    }

    return _auth_service->underlying_role_manager().exists(*_user->name).then([user = _user](bool exists) mutable {
        if (!exists) {
            throw exceptions::authentication_exception(
                            sprint("User %s doesn't exist - create it with CREATE USER query first",
                                            *user->name));
        }
        return make_ready_future();
    });
}

void service::client_state::validate_login() const {
    if (!_user) {
        throw exceptions::unauthorized_exception("You have not logged in");
    }
}

void service::client_state::ensure_not_anonymous() const {
    validate_login();
    if (auth::is_anonymous(*_user)) {
        throw exceptions::unauthorized_exception("You have to be logged in and not anonymous to perform this request");
    }
}

void service::client_state::merge(const client_state& other) {
    if (other._dirty) {
        _keyspace = other._keyspace;
    }
    if (_user == nullptr) {
        _user = other._user;
    }
    if (_auth_state != other._auth_state) {
        _auth_state = other._auth_state;
    }
}

future<> service::client_state::has_all_keyspaces_access(
                auth::permission p) const {
    if (_is_internal) {
        return make_ready_future();
    }
    validate_login();

    return do_with(auth::resource(auth::resource_kind::data), [this, p](const auto& r) {
        return ensure_has_permission(p, r);
    });
}

future<> service::client_state::has_keyspace_access(const sstring& ks,
                auth::permission p) const {
    return do_with(ks, auth::make_data_resource(ks), [this, p](auto const& ks, auto const& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_column_family_access(const sstring& ks,
                const sstring& cf, auth::permission p) const {
    validation::validate_column_family(ks, cf);

    return do_with(ks, auth::make_data_resource(ks, cf), [this, p](const auto& ks, const auto& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_schema_access(const schema& s, auth::permission p) const {
    return do_with(
            s.ks_name(),
            auth::make_data_resource(s.ks_name(),s.cf_name()),
            [this, p](auto const& ks, auto const& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_access(const sstring& ks, auth::permission p, const auth::resource& resource) const {
    if (ks.empty()) {
        throw exceptions::invalid_request_exception("You have not set a keyspace for this session");
    }
    if (_is_internal) {
        return make_ready_future();
    }

    validate_login();

    static const auto alteration_permissions = auth::permission_set::of<
            auth::permission::CREATE, auth::permission::ALTER, auth::permission::DROP>();

    // we only care about schema modification.
    if (alteration_permissions.contains(p)) {
        // prevent system keyspace modification
        auto name = ks;
        std::transform(name.begin(), name.end(), name.begin(), ::tolower);
        if (is_system_keyspace(name)) {
            throw exceptions::unauthorized_exception(ks + " keyspace is not user-modifiable.");
        }

        // we want to disallow altering AUTH_KS and TRACING_KS.
        for (auto& n : { auth::meta::AUTH_KS, tracing::trace_keyspace_helper::KEYSPACE_NAME }) {
            if (name == n && p == auth::permission::DROP) {
                throw exceptions::unauthorized_exception(sprint("Cannot %s %s", auth::permissions::to_string(p), resource));
            }
        }
    }

    static thread_local std::set<auth::resource> readable_system_resources = [] {
        std::set<auth::resource> tmp;
        for (auto cf : { db::system_keyspace::LOCAL, db::system_keyspace::PEERS }) {
            tmp.insert(auth::make_data_resource(db::system_keyspace::NAME, cf));
        }
        for (auto cf : db::schema_tables::ALL) {
            tmp.insert(auth::make_data_resource(db::schema_tables::NAME, cf));
        }
        return tmp;
    }();

    if (p == auth::permission::SELECT && readable_system_resources.count(resource) != 0) {
        return make_ready_future();
    }
    if (alteration_permissions.contains(p)) {
        for (auto& s : { _auth_service->underlying_authorizer().protected_resources(),
                        _auth_service->underlying_authorizer().protected_resources() }) {
            if (s.count(resource)) {
                throw exceptions::unauthorized_exception(sprint("%s is protected", resource));
            }
        }
    }

    return ensure_has_permission(p, resource);
}

future<bool> service::client_state::check_has_permission(auth::permission p, const auth::resource& r) const {
    if (_is_internal) {
        return make_ready_future<bool>(true);
    }

    return do_with(r.parent(), [this, p, &r](const auto& parent_r) {
        return auth::get_permissions(*_auth_service, *_user, r).then([this, p, &parent_r](auth::permission_set set) {
            if (set.contains(p)) {
                return make_ready_future<bool>(true);
            }
            if (parent_r) {
                return check_has_permission(p, *parent_r);
            }
            return make_ready_future<bool>(false);
        });
    });
}

future<> service::client_state::ensure_has_permission(auth::permission p, const auth::resource& r) const {
    return check_has_permission(p, r).then([this, p, &r](bool ok) {
        if (!ok) {
            throw exceptions::unauthorized_exception(
                sprint(
                        "User %s has no %s permission on %s or any of its parents",
                        *_user,
                        auth::permissions::to_string(p),
                        r));
        }
    });
}

auth::service* service::client_state::local_auth_service_copy(const service::client_state& orig) const {
    if (orig._auth_service && _cpu_of_origin != orig._cpu_of_origin) {
        // if moved to a different shard - return a pointer to the local auth_service instance
        return &service::get_local_storage_service().get_local_auth_service();
    }
    return orig._auth_service;
}

::shared_ptr<auth::authenticated_user> service::client_state::local_user_copy(const service::client_state& orig) const {
    if (orig._user) {
        if (_cpu_of_origin != orig._cpu_of_origin) {
            // if we moved to another shard create a local copy of authenticated_user
            return ::make_shared<auth::authenticated_user>(*orig._user);
        } else {
            return orig._user;
        }
    }
    return nullptr;
}

service::client_state::client_state(service::client_state::request_copy_tag, const service::client_state& orig, api::timestamp_type ts)
        : _keyspace(orig._keyspace)
        , _cpu_of_origin(engine().cpu_id())
        , _user(local_user_copy(orig))
        , _auth_state(orig._auth_state)
        , _is_internal(orig._is_internal)
        , _is_thrift(orig._is_thrift)
        , _is_request_copy(true)
        , _remote_address(orig._remote_address)
        , _auth_service(local_auth_service_copy(orig))
        , _request_ts(ts)
{
    assert(!orig._trace_state_ptr);
}

future<> service::client_state::ensure_exists(const auth::resource& r) const {
    return _auth_service->exists(r).then([&r](bool exists) {
        if (!exists) {
            throw exceptions::invalid_request_exception(sprint("%s doesn't exist.", r));
        }

        return make_ready_future<>();
    });
}
<commit_msg>auth: Protect authenticator resources<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright (C) 2016 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "client_state.hh"
#include "auth/authorizer.hh"
#include "auth/authenticator.hh"
#include "auth/common.hh"
#include "auth/resource.hh"
#include "exceptions/exceptions.hh"
#include "validation.hh"
#include "db/system_keyspace.hh"
#include "db/schema_tables.hh"
#include "tracing/trace_keyspace_helper.hh"
#include "storage_service.hh"

void service::client_state::set_login(::shared_ptr<auth::authenticated_user> user) {
    if (user == nullptr) {
        throw std::invalid_argument("Must provide user");
    }
    _user = std::move(user);
    if (_is_request_copy) {
        _user_is_dirty = true;
    }
}

future<> service::client_state::check_user_exists() {
    if (auth::is_anonymous(*_user)) {
        return make_ready_future();
    }

    return _auth_service->underlying_role_manager().exists(*_user->name).then([user = _user](bool exists) mutable {
        if (!exists) {
            throw exceptions::authentication_exception(
                            sprint("User %s doesn't exist - create it with CREATE USER query first",
                                            *user->name));
        }
        return make_ready_future();
    });
}

void service::client_state::validate_login() const {
    if (!_user) {
        throw exceptions::unauthorized_exception("You have not logged in");
    }
}

void service::client_state::ensure_not_anonymous() const {
    validate_login();
    if (auth::is_anonymous(*_user)) {
        throw exceptions::unauthorized_exception("You have to be logged in and not anonymous to perform this request");
    }
}

void service::client_state::merge(const client_state& other) {
    if (other._dirty) {
        _keyspace = other._keyspace;
    }
    if (_user == nullptr) {
        _user = other._user;
    }
    if (_auth_state != other._auth_state) {
        _auth_state = other._auth_state;
    }
}

future<> service::client_state::has_all_keyspaces_access(
                auth::permission p) const {
    if (_is_internal) {
        return make_ready_future();
    }
    validate_login();

    return do_with(auth::resource(auth::resource_kind::data), [this, p](const auto& r) {
        return ensure_has_permission(p, r);
    });
}

future<> service::client_state::has_keyspace_access(const sstring& ks,
                auth::permission p) const {
    return do_with(ks, auth::make_data_resource(ks), [this, p](auto const& ks, auto const& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_column_family_access(const sstring& ks,
                const sstring& cf, auth::permission p) const {
    validation::validate_column_family(ks, cf);

    return do_with(ks, auth::make_data_resource(ks, cf), [this, p](const auto& ks, const auto& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_schema_access(const schema& s, auth::permission p) const {
    return do_with(
            s.ks_name(),
            auth::make_data_resource(s.ks_name(),s.cf_name()),
            [this, p](auto const& ks, auto const& r) {
        return has_access(ks, p, r);
    });
}

future<> service::client_state::has_access(const sstring& ks, auth::permission p, const auth::resource& resource) const {
    if (ks.empty()) {
        throw exceptions::invalid_request_exception("You have not set a keyspace for this session");
    }
    if (_is_internal) {
        return make_ready_future();
    }

    validate_login();

    static const auto alteration_permissions = auth::permission_set::of<
            auth::permission::CREATE, auth::permission::ALTER, auth::permission::DROP>();

    // we only care about schema modification.
    if (alteration_permissions.contains(p)) {
        // prevent system keyspace modification
        auto name = ks;
        std::transform(name.begin(), name.end(), name.begin(), ::tolower);
        if (is_system_keyspace(name)) {
            throw exceptions::unauthorized_exception(ks + " keyspace is not user-modifiable.");
        }

        // we want to disallow altering AUTH_KS and TRACING_KS.
        for (auto& n : { auth::meta::AUTH_KS, tracing::trace_keyspace_helper::KEYSPACE_NAME }) {
            if (name == n && p == auth::permission::DROP) {
                throw exceptions::unauthorized_exception(sprint("Cannot %s %s", auth::permissions::to_string(p), resource));
            }
        }
    }

    static thread_local std::set<auth::resource> readable_system_resources = [] {
        std::set<auth::resource> tmp;
        for (auto cf : { db::system_keyspace::LOCAL, db::system_keyspace::PEERS }) {
            tmp.insert(auth::make_data_resource(db::system_keyspace::NAME, cf));
        }
        for (auto cf : db::schema_tables::ALL) {
            tmp.insert(auth::make_data_resource(db::schema_tables::NAME, cf));
        }
        return tmp;
    }();

    if (p == auth::permission::SELECT && readable_system_resources.count(resource) != 0) {
        return make_ready_future();
    }
    if (alteration_permissions.contains(p)) {
        for (auto& s : { _auth_service->underlying_authorizer().protected_resources(),
                        _auth_service->underlying_authenticator().protected_resources() }) {
            if (s.count(resource)) {
                throw exceptions::unauthorized_exception(sprint("%s is protected", resource));
            }
        }
    }

    return ensure_has_permission(p, resource);
}

future<bool> service::client_state::check_has_permission(auth::permission p, const auth::resource& r) const {
    if (_is_internal) {
        return make_ready_future<bool>(true);
    }

    return do_with(r.parent(), [this, p, &r](const auto& parent_r) {
        return auth::get_permissions(*_auth_service, *_user, r).then([this, p, &parent_r](auth::permission_set set) {
            if (set.contains(p)) {
                return make_ready_future<bool>(true);
            }
            if (parent_r) {
                return check_has_permission(p, *parent_r);
            }
            return make_ready_future<bool>(false);
        });
    });
}

future<> service::client_state::ensure_has_permission(auth::permission p, const auth::resource& r) const {
    return check_has_permission(p, r).then([this, p, &r](bool ok) {
        if (!ok) {
            throw exceptions::unauthorized_exception(
                sprint(
                        "User %s has no %s permission on %s or any of its parents",
                        *_user,
                        auth::permissions::to_string(p),
                        r));
        }
    });
}

auth::service* service::client_state::local_auth_service_copy(const service::client_state& orig) const {
    if (orig._auth_service && _cpu_of_origin != orig._cpu_of_origin) {
        // if moved to a different shard - return a pointer to the local auth_service instance
        return &service::get_local_storage_service().get_local_auth_service();
    }
    return orig._auth_service;
}

::shared_ptr<auth::authenticated_user> service::client_state::local_user_copy(const service::client_state& orig) const {
    if (orig._user) {
        if (_cpu_of_origin != orig._cpu_of_origin) {
            // if we moved to another shard create a local copy of authenticated_user
            return ::make_shared<auth::authenticated_user>(*orig._user);
        } else {
            return orig._user;
        }
    }
    return nullptr;
}

service::client_state::client_state(service::client_state::request_copy_tag, const service::client_state& orig, api::timestamp_type ts)
        : _keyspace(orig._keyspace)
        , _cpu_of_origin(engine().cpu_id())
        , _user(local_user_copy(orig))
        , _auth_state(orig._auth_state)
        , _is_internal(orig._is_internal)
        , _is_thrift(orig._is_thrift)
        , _is_request_copy(true)
        , _remote_address(orig._remote_address)
        , _auth_service(local_auth_service_copy(orig))
        , _request_ts(ts)
{
    assert(!orig._trace_state_ptr);
}

future<> service::client_state::ensure_exists(const auth::resource& r) const {
    return _auth_service->exists(r).then([&r](bool exists) {
        if (!exists) {
            throw exceptions::invalid_request_exception(sprint("%s doesn't exist.", r));
        }

        return make_ready_future<>();
    });
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: numehelp.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 17:54:59 $
 *
 *  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 XMLOFF_NUMEHELP_HXX
#define XMLOFF_NUMEHELP_HXX

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_XMLOFF_DLLAPI_H
#include "xmloff/dllapi.h"
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATSSUPPLIER_HPP_
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#endif

#ifndef __SGI_STL_SET
#include <set>
#endif

class SvXMLExport;
namespace rtl
{
    class OUString;
}

struct XMLNumberFormat
{
    rtl::OUString   sCurrency;
    sal_Int32       nNumberFormat;
    sal_Int16       nType;
    sal_Bool        bIsStandard : 1;
    XMLNumberFormat() : nNumberFormat(0), nType(0) {}
    XMLNumberFormat(const rtl::OUString& sTempCurrency, sal_Int32 nTempFormat,
        sal_Int16 nTempType) : sCurrency(sTempCurrency), nNumberFormat(nTempFormat),
            nType(nTempType) {}
};

struct LessNumberFormat
{
    sal_Bool operator() (const XMLNumberFormat& rValue1, const XMLNumberFormat& rValue2) const
    {
        return rValue1.nNumberFormat < rValue2.nNumberFormat;
    }
};

typedef std::set<XMLNumberFormat, LessNumberFormat> XMLNumberFormatSet;

class XMLOFF_DLLPUBLIC XMLNumberFormatAttributesExportHelper
{
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > xNumberFormats;
    SvXMLExport*        pExport;
    const rtl::OUString sEmpty;
    const rtl::OUString sStandardFormat;
    const rtl::OUString sType;
    const rtl::OUString sAttrValueType;
    const rtl::OUString sAttrValue;
    const rtl::OUString sAttrDateValue;
    const rtl::OUString sAttrTimeValue;
    const rtl::OUString sAttrBooleanValue;
    const rtl::OUString sAttrStringValue;
    const rtl::OUString sAttrCurrency;
    const rtl::OUString msCurrencySymbol;
    const rtl::OUString msCurrencyAbbreviation;
    XMLNumberFormatSet  aNumberFormats;
public :
    XMLNumberFormatAttributesExportHelper(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier);
    XMLNumberFormatAttributesExportHelper(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier,
                                            SvXMLExport& rExport );
    ~XMLNumberFormatAttributesExportHelper();
    void SetExport(SvXMLExport* pExp) { this->pExport = pExp; }

    sal_Int16 GetCellType(const sal_Int32 nNumberFormat, rtl::OUString& sCurrency, sal_Bool& bIsStandard);
    static void WriteAttributes(SvXMLExport& rXMLExport,
                                const sal_Int16 nTypeKey,
                                const double& rValue,
                                const rtl::OUString& rCurrencySymbol,
                                sal_Bool bExportValue = sal_True);
    static sal_Bool GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& rCurrencySymbol,
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier);
    static sal_Int16 GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard,
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier);
    static void SetNumberFormatAttributes(SvXMLExport& rXMLExport,
                                          const sal_Int32 nNumberFormat,
                                          const double& rValue,
                                          sal_Bool bExportValue = sal_True);
    static void SetNumberFormatAttributes(SvXMLExport& rXMLExport,
                                          const rtl::OUString& rValue,
                                          const rtl::OUString& rCharacters,
                                          sal_Bool bExportValue = sal_True,
                                          sal_Bool bExportTypeAttribute = sal_True);

    sal_Bool GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& rCurrencySymbol);
    sal_Int16 GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard);
    void WriteAttributes(const sal_Int16 nTypeKey,
                                          const double& rValue,
                                          const rtl::OUString& rCurrencySymbol,
                                          sal_Bool bExportValue = sal_True);
    void SetNumberFormatAttributes(const sal_Int32 nNumberFormat,
                                          const double& rValue,
                                          sal_Bool bExportValue = sal_True);
    void SetNumberFormatAttributes(const rtl::OUString& rValue,
                                          const rtl::OUString& rCharacters,
                                          sal_Bool bExportValue = sal_True,
                                          sal_Bool bExportTypeAttribute = sal_True);
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.11.330); FILE MERGED 2008/04/01 16:09:11 thb 1.11.330.3: #i85898# Stripping all external header guards 2008/04/01 13:04:22 thb 1.11.330.2: #i85898# Stripping all external header guards 2008/03/31 16:27:54 rt 1.11.330.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: numehelp.hxx,v $
 * $Revision: 1.12 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef XMLOFF_NUMEHELP_HXX
#define XMLOFF_NUMEHELP_HXX

#include "sal/config.h"
#include "xmloff/dllapi.h"
#include <sal/types.h>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>

#ifndef __SGI_STL_SET
#include <set>
#endif

class SvXMLExport;
namespace rtl
{
    class OUString;
}

struct XMLNumberFormat
{
    rtl::OUString   sCurrency;
    sal_Int32       nNumberFormat;
    sal_Int16       nType;
    sal_Bool        bIsStandard : 1;
    XMLNumberFormat() : nNumberFormat(0), nType(0) {}
    XMLNumberFormat(const rtl::OUString& sTempCurrency, sal_Int32 nTempFormat,
        sal_Int16 nTempType) : sCurrency(sTempCurrency), nNumberFormat(nTempFormat),
            nType(nTempType) {}
};

struct LessNumberFormat
{
    sal_Bool operator() (const XMLNumberFormat& rValue1, const XMLNumberFormat& rValue2) const
    {
        return rValue1.nNumberFormat < rValue2.nNumberFormat;
    }
};

typedef std::set<XMLNumberFormat, LessNumberFormat> XMLNumberFormatSet;

class XMLOFF_DLLPUBLIC XMLNumberFormatAttributesExportHelper
{
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > xNumberFormats;
    SvXMLExport*        pExport;
    const rtl::OUString sEmpty;
    const rtl::OUString sStandardFormat;
    const rtl::OUString sType;
    const rtl::OUString sAttrValueType;
    const rtl::OUString sAttrValue;
    const rtl::OUString sAttrDateValue;
    const rtl::OUString sAttrTimeValue;
    const rtl::OUString sAttrBooleanValue;
    const rtl::OUString sAttrStringValue;
    const rtl::OUString sAttrCurrency;
    const rtl::OUString msCurrencySymbol;
    const rtl::OUString msCurrencyAbbreviation;
    XMLNumberFormatSet  aNumberFormats;
public :
    XMLNumberFormatAttributesExportHelper(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier);
    XMLNumberFormatAttributesExportHelper(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier,
                                            SvXMLExport& rExport );
    ~XMLNumberFormatAttributesExportHelper();
    void SetExport(SvXMLExport* pExp) { this->pExport = pExp; }

    sal_Int16 GetCellType(const sal_Int32 nNumberFormat, rtl::OUString& sCurrency, sal_Bool& bIsStandard);
    static void WriteAttributes(SvXMLExport& rXMLExport,
                                const sal_Int16 nTypeKey,
                                const double& rValue,
                                const rtl::OUString& rCurrencySymbol,
                                sal_Bool bExportValue = sal_True);
    static sal_Bool GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& rCurrencySymbol,
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier);
    static sal_Int16 GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard,
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier);
    static void SetNumberFormatAttributes(SvXMLExport& rXMLExport,
                                          const sal_Int32 nNumberFormat,
                                          const double& rValue,
                                          sal_Bool bExportValue = sal_True);
    static void SetNumberFormatAttributes(SvXMLExport& rXMLExport,
                                          const rtl::OUString& rValue,
                                          const rtl::OUString& rCharacters,
                                          sal_Bool bExportValue = sal_True,
                                          sal_Bool bExportTypeAttribute = sal_True);

    sal_Bool GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& rCurrencySymbol);
    sal_Int16 GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard);
    void WriteAttributes(const sal_Int16 nTypeKey,
                                          const double& rValue,
                                          const rtl::OUString& rCurrencySymbol,
                                          sal_Bool bExportValue = sal_True);
    void SetNumberFormatAttributes(const sal_Int32 nNumberFormat,
                                          const double& rValue,
                                          sal_Bool bExportValue = sal_True);
    void SetNumberFormatAttributes(const rtl::OUString& rValue,
                                          const rtl::OUString& rCharacters,
                                          sal_Bool bExportValue = sal_True,
                                          sal_Bool bExportTypeAttribute = sal_True);
};

#endif

<|endoftext|>


<commit_before>#include "Deinterleave.h"
#include "IRMutator.h"

namespace Halide {
namespace Internal {

class BlockFlattener : public IRMutator {
private:

    using IRMutator::visit;

    void visit(const Block *op) {
        /* First we dig into the block traversing down the 'first'
         * stmt until we find one that is not a block. We push all of
         * the rest stmt's into the 'rest' stmt of the top-level
         * block, and then fix up the 'rest' stmt recursively at the
         * end. The result of this mutation is an equivalent Block
         * node that does not contain any Block nodes in a 'first' stmt.
         */
        Stmt first = op->first;
        Stmt rest  = op->rest;
        while(const Block *first_block = op->first.as<Block>()) {
            first = mutate(first_block->first);
            if (first_block->rest.defined()) {
                rest = rest.defined()? Block::make(first_block->rest, rest): first_block->rest;
            }
        }

        if (first.same_as(op->first)) {
            rest = mutate(rest);
            stmt = rest.same_as(op->rest)? op: Block::make(first, rest);
        } else {
            stmt = Block::make(first, mutate(rest));
        }
    }
};

Stmt flatten_blocks(Stmt s) {
    BlockFlattener flatten;
    return flatten.mutate(s);
}

}
}
<commit_msg>Some small fixes to BlockFlattening. All tests pass now.<commit_after>#include "Deinterleave.h"
#include "IRMutator.h"

namespace Halide {
namespace Internal {

class BlockFlattener : public IRMutator {
private:

    using IRMutator::visit;

    void visit(const Block *op) {
        /* First we dig into the block traversing down the 'first'
         * stmt until we find one that is not a block. We push all of
         * the rest stmt's into the 'rest' stmt of the top-level
         * block, and then fix up the 'rest' stmt recursively at the
         * end. The result of this mutation is an equivalent Block
         * node that does not contain any Block nodes in a 'first' stmt.
         */
        Stmt first = op->first;
        Stmt rest  = op->rest;
        while(const Block *first_block = first.as<Block>()) {
            first = first_block->first;
            if (first_block->rest.defined()) {
                rest = rest.defined()? Block::make(first_block->rest, rest): first_block->rest;
            }
        }

        if (first.same_as(op->first)) {
            rest = mutate(rest);
            stmt = rest.same_as(op->rest)? op: Block::make(first, rest);
        } else {
            stmt = Block::make(first, mutate(rest));
        }
    }
};

Stmt flatten_blocks(Stmt s) {
    BlockFlattener flatten;
    return flatten.mutate(s);
}

}
}
<|endoftext|>


<commit_before>#include "benchmark.h"
#include "../src/transwarp.h"
#include <chrono>
#include <fstream>

namespace tw = transwarp;

namespace examples {

const double expected = 4273.5;

int func0() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 42;
}

int func1() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 13;
}

int func2(int x, int y) {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return x + y;
}

double func3() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 77.7;
}

double func4(int x, double y) {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return x * y;
}

void calculate_via_functions() {
    const volatile auto val0 = func0();
    const volatile auto val1 = func1();
    const volatile auto val2 = func2(val0, val1);
    const volatile auto val3 = func3();
    const volatile auto val4 = func4(val2, val3);
    if (val4 != expected) {
        throw std::runtime_error("wrong result");
    }
}

std::shared_ptr<tw::itask<double>> build_graph() {
    auto task0 = tw::make_task(tw::root, func0);
    auto task1 = tw::make_task(tw::root, func1);
    auto task2 = tw::make_task(tw::consume, func2, task0, task1);
    auto task3 = tw::make_task(tw::root, func3);
    auto task4 = tw::make_task(tw::consume, func4, task2, task3);
    return task4;
}

void calculate_via_transwarp(tw::itask<double>& task) {
    task.schedule_all();
    if (task.get_future().get() != expected) {
        throw std::runtime_error("wrong result");
    }
    task.reset_all();
}

template<typename Functor>
std::size_t measure(Functor functor, std::size_t sample_size) {
    const auto start = std::chrono::high_resolution_clock::now();
    for (std::size_t i=0; i<sample_size; ++i) {
        functor();
    }
    const auto end = std::chrono::high_resolution_clock::now();
    return static_cast<std::size_t>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count());
}

void benchmark(std::ostream& os, std::size_t sample_size) {
    auto task = build_graph();
    std::ofstream("benchmark.dot") << tw::make_dot(task->get_graph());

    const auto func_us = measure([] { calculate_via_functions(); }, sample_size);

    const auto tw_us = measure([task] { calculate_via_transwarp(*task); }, sample_size);

    os << "functions: " << func_us << " us" << std::endl;
    os << "transwarp: " << tw_us << " us" << std::endl;
    os << "difference: " << static_cast<double>(tw_us - func_us) /
                            static_cast<double>(func_us) * 100. << " %" << std::endl;
}

}

#ifndef USE_LIBUNITTEST
int main() {
    std::cout << "Running example: benchmark ..." << std::endl;
    examples::benchmark(std::cout);
}
#endif
<commit_msg>add some doc<commit_after>#include "benchmark.h"
#include "../src/transwarp.h"
#include <chrono>
#include <fstream>

namespace tw = transwarp;

namespace examples {

const double expected = 4273.5;

int func0() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 42;
}

int func1() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 13;
}

int func2(int x, int y) {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return x + y;
}

double func3() {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return 77.7;
}

double func4(int x, double y) {
    std::this_thread::sleep_for(std::chrono::microseconds(1));
    return x * y;
}

void calculate_via_functions() {
    const volatile auto val0 = func0();
    const volatile auto val1 = func1();
    const volatile auto val2 = func2(val0, val1);
    const volatile auto val3 = func3();
    const volatile auto val4 = func4(val2, val3);
    if (val4 != expected) {
        throw std::runtime_error("wrong result");
    }
}

std::shared_ptr<tw::itask<double>> build_graph() {
    auto task0 = tw::make_task(tw::root, func0);
    auto task1 = tw::make_task(tw::root, func1);
    auto task2 = tw::make_task(tw::consume, func2, task0, task1);
    auto task3 = tw::make_task(tw::root, func3);
    auto task4 = tw::make_task(tw::consume, func4, task2, task3);
    return task4;
}

void calculate_via_transwarp(tw::itask<double>& task) {
    task.schedule_all();
    if (task.get_future().get() != expected) {
        throw std::runtime_error("wrong result");
    }
    task.reset_all();
}

template<typename Functor>
std::size_t measure(Functor functor, std::size_t sample_size) {
    const auto start = std::chrono::high_resolution_clock::now();
    for (std::size_t i=0; i<sample_size; ++i) {
        functor();
    }
    const auto end = std::chrono::high_resolution_clock::now();
    return static_cast<std::size_t>(std::chrono::duration_cast<std::chrono::microseconds>(end - start).count());
}

// This benchmark compares regular function calls with the transwarp graph
void benchmark(std::ostream& os, std::size_t sample_size) {
    auto task = build_graph();
    std::ofstream("benchmark.dot") << tw::make_dot(task->get_graph());

    const auto func_us = measure([] { calculate_via_functions(); }, sample_size);

    const auto tw_us = measure([task] { calculate_via_transwarp(*task); }, sample_size);

    os << "functions: " << func_us << " us" << std::endl;
    os << "transwarp: " << tw_us << " us" << std::endl;
    os << "difference: " << static_cast<double>(tw_us - func_us) /
                            static_cast<double>(func_us) * 100. << " %" << std::endl;
}

}

#ifndef USE_LIBUNITTEST
int main() {
    std::cout << "Running example: benchmark ..." << std::endl;
    examples::benchmark(std::cout);
}
#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DomainMapper.hxx,v $
 *
 *  $Revision: 1.20 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-10 11:30:38 $
 *
 *  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 INCLUDED_DOMAINMAPPER_HXX
#define INCLUDED_DOMAINMAPPER_HXX

#ifndef INCLUDED_WRITERFILTERDLLAPI_H
#include <WriterFilterDllApi.hxx>
#endif
#include <resourcemodel/WW8ResourceModel.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/text/FontEmphasis.hpp>
#include <com/sun/star/style/TabAlign.hpp>

#include <map>

namespace com{ namespace sun {namespace star{
    namespace uno{
        class XComponentContext;
    }
    namespace lang{
        class XMultiServiceFactory;
    }
}}}

namespace writerfilter {
namespace dmapper
{
using namespace std;

class PropertyMap;

class DomainMapper_Impl;

// different context types require different sprm handling (e.g. names)
enum SprmType
{
    SPRM_DEFAULT,
    SPRM_LIST
};
enum SourceDocumentType
{
    DOCUMENT_DOC,
    DOCUMENT_OOXML,
    DOCUMENT_RTF
};
class WRITERFILTER_DLLPUBLIC DomainMapper : public Properties, public Table,
                    public BinaryObj, public Stream
{
    DomainMapper_Impl   *m_pImpl;

public:
    DomainMapper(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext,
                                ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xModel,
                                SourceDocumentType eDocumentType );
    virtual ~DomainMapper();

    // Properties
    virtual void attribute(Id Name, Value & val);
    virtual void sprm(Sprm & sprm);

    // Table
    virtual void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref);

    // BinaryObj
    virtual void data(const sal_uInt8* buf, size_t len,
                      writerfilter::Reference<Properties>::Pointer_t ref);

    // Stream
    virtual void startSectionGroup();
    virtual void endSectionGroup();
    virtual void startParagraphGroup();
    virtual void endParagraphGroup();
    virtual void startCharacterGroup();
    virtual void endCharacterGroup();
    virtual void text(const sal_uInt8 * data, size_t len);
    virtual void utext(const sal_uInt8 * data, size_t len);
    virtual void props(writerfilter::Reference<Properties>::Pointer_t ref);
    virtual void table(Id name,
                       writerfilter::Reference<Table>::Pointer_t ref);
    virtual void substream(Id name,
                           ::writerfilter::Reference<Stream>::Pointer_t ref);
    virtual void info(const string & info);

    void sprm( Sprm& sprm, ::boost::shared_ptr<PropertyMap> pContext, SprmType = SPRM_DEFAULT );

    void PushStyleSheetProperties( ::boost::shared_ptr<PropertyMap> pStyleProperties );
    void PopStyleSheetProperties();

    bool IsOOXMLImport() const;
    ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > GetTextFactory() const;
    void  AddListIDToLFOTable( sal_Int32 nAbstractNumId );

private:
    void handleUnderlineType(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext);
    void handleParaJustification(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext, const bool bExchangeLeftRight);
    bool getColorFromIndex(const sal_Int32 nIndex, sal_Int32 &nColor);
    sal_Int16 getEmphasisValue(const sal_Int32 nIntValue);
    rtl::OUString getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix = true);
    com::sun::star::style::TabAlign getTabAlignFromValue(const sal_Int32 nIntValue);
    sal_Unicode getFillCharFromValue(const sal_Int32 nIntValue);
    void resolveAttributeProperties(Value & val);
    void resolveSprmProps(Sprm & sprm_);
    sal_Int32 mnBackgroundColor;
    bool mbIsHighlightSet;
};

} // namespace dmapper
} // namespace writerfilter
#endif //
<commit_msg>INTEGRATION: CWS xmlfilter03_DEV300 (1.20.2); FILE MERGED 2008/02/06 19:16:56 hub 1.20.2.3: fix build breakage on gcc 4.2.1 2008/02/06 14:05:36 os 1.20.2.2: creating CharStyles for numbering/list symbols 2008/01/28 14:46:36 os 1.20.2.1: list properties as context<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DomainMapper.hxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 16:47:00 $
 *
 *  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 INCLUDED_DOMAINMAPPER_HXX
#define INCLUDED_DOMAINMAPPER_HXX

#ifndef INCLUDED_WRITERFILTERDLLAPI_H
#include <WriterFilterDllApi.hxx>
#endif
#include <resourcemodel/WW8ResourceModel.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/text/FontEmphasis.hpp>
#include <com/sun/star/style/TabAlign.hpp>

#include <map>
#include <vector>

namespace com{ namespace sun {namespace star{
    namespace beans{
        struct PropertyValue;
    }
    namespace uno{
        class XComponentContext;
    }
    namespace lang{
        class XMultiServiceFactory;
    }
    namespace text{
        class XTextRange;
    }
}}}

typedef std::vector< com::sun::star::beans::PropertyValue > PropertyValueVector_t;

namespace writerfilter {
namespace dmapper
{
using namespace std;

class PropertyMap;
class DomainMapper_Impl;

// different context types require different sprm handling (e.g. names)
enum SprmType
{
    SPRM_DEFAULT,
    SPRM_LIST
};
enum SourceDocumentType
{
    DOCUMENT_DOC,
    DOCUMENT_OOXML,
    DOCUMENT_RTF
};
class WRITERFILTER_DLLPUBLIC DomainMapper : public Properties, public Table,
                    public BinaryObj, public Stream
{
    DomainMapper_Impl   *m_pImpl;

public:
    DomainMapper(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext,
                                ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xModel,
                                SourceDocumentType eDocumentType );
    virtual ~DomainMapper();

    // Properties
    virtual void attribute(Id Name, Value & val);
    virtual void sprm(Sprm & sprm);

    // Table
    virtual void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref);

    // BinaryObj
    virtual void data(const sal_uInt8* buf, size_t len,
                      writerfilter::Reference<Properties>::Pointer_t ref);

    // Stream
    virtual void startSectionGroup();
    virtual void endSectionGroup();
    virtual void startParagraphGroup();
    virtual void endParagraphGroup();
    virtual void startCharacterGroup();
    virtual void endCharacterGroup();
    virtual void text(const sal_uInt8 * data, size_t len);
    virtual void utext(const sal_uInt8 * data, size_t len);
    virtual void props(writerfilter::Reference<Properties>::Pointer_t ref);
    virtual void table(Id name,
                       writerfilter::Reference<Table>::Pointer_t ref);
    virtual void substream(Id name,
                           ::writerfilter::Reference<Stream>::Pointer_t ref);
    virtual void info(const string & info);

    void sprm( Sprm& sprm, ::boost::shared_ptr<PropertyMap> pContext, SprmType = SPRM_DEFAULT );

    void PushStyleSheetProperties( ::boost::shared_ptr<PropertyMap> pStyleProperties );
    void PopStyleSheetProperties();

    void PushListProperties( ::boost::shared_ptr<PropertyMap> pListProperties );
    void PopListProperties();

    bool IsOOXMLImport() const;
    ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory > GetTextFactory() const;
    void  AddListIDToLFOTable( sal_Int32 nAbstractNumId );
    ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > GetCurrentTextRange();

    ::rtl::OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties );

private:
    void handleUnderlineType(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext);
    void handleParaJustification(const sal_Int32 nIntValue, const ::boost::shared_ptr<PropertyMap> pContext, const bool bExchangeLeftRight);
    bool getColorFromIndex(const sal_Int32 nIndex, sal_Int32 &nColor);
    sal_Int16 getEmphasisValue(const sal_Int32 nIntValue);
    rtl::OUString getBracketStringFromEnum(const sal_Int32 nIntValue, const bool bIsPrefix = true);
    com::sun::star::style::TabAlign getTabAlignFromValue(const sal_Int32 nIntValue);
    sal_Unicode getFillCharFromValue(const sal_Int32 nIntValue);
    void resolveAttributeProperties(Value & val);
    void resolveSprmProps(Sprm & sprm_);
    sal_Int32 mnBackgroundColor;
    bool mbIsHighlightSet;
};

} // namespace dmapper
} // namespace writerfilter
#endif //
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_scom.H $          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_scom.H
/// @brief Register Access.
///----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 2
/// *HWP Consumed by      : FSP:HB
///----------------------------------------------------------------------------
///
/// @verbatim
/// Register Access via scom.
///
/// @endverbatim
///----------------------------------------------------------------------------

#ifndef P9_IO_SCOM_H_
#define P9_IO_SCOM_H_

//* *****************************
//* Defines
//* *****************************

// @brief IO Base Addresses
#define P9_PSI_PHY_BASE_0x00000000       0x00000000
#define P9_XBUS_PHY_BASE_0x06010C00      0x06010C00
#define P9_ABUS0_PHY_BASE_0x09011000     0x09011000
#define P9_ABUS3_PHY_BASE_0x0C011000     0x0C011000
#define P9_OBUS0_PHY_BASE_0x09010C00     0x09010C00
#define P9_OBUS1_PHY_BASE_0x0A010C00     0x0A010C00
#define P9_OBUS2_PHY_BASE_0x0B010C00     0x0B010C00
#define P9_OBUS3_PHY_BASE_0x0C010C00     0x0C010C00
#define P9_DMI0_PHY_BASE_0x0701103F      0x0701103F
#define CEN_PHY_BASE_0x02010400          0x02010400

//-----------------------------------------------------------------------------
//  FAPI Includes
//-----------------------------------------------------------------------------
#include <fapi2.H>

/**
 * @namespace io
 * This class provides a generic class for a register to read/write SCOMs.
 */
namespace io
{

/**
 * @brief Parses the register data by the i_start and i_width of a field and returns
 *        a right aligned value.
 * @param[in] i_scom_addr     Not used
 * @param[in] i_start         Represents the start bit of the field within the reg
 * @param[in] i_width         Represents the width of the field within the reg
 * @param[in] i_register_data Scom Data from previous io::read()
 * @return Field Data
 */
inline uint64_t get(
    const uint64_t i_scom_addr,
    const uint8_t  i_start,
    const uint8_t  i_width,
    const uint64_t i_register_data )
{
    const uint8_t REGISTER_WIDTH = 64;
    const uint8_t SHIFT          = REGISTER_WIDTH - i_start - i_width;
    const uint64_t MASK          = ( ( (uint64_t)0x1 << i_width ) - 1 ) << SHIFT;
    return ( ( i_register_data & MASK ) >> SHIFT );
}

/**
 * @brief Sets the field specified by the i_start and i_width of the register data to the right
 *        alighted i_data.
 * @param[in]     i_scom_addr      Is not used in this function.
 * @param[in]     i_start          Represents the start bit of the field within the reg
 * @param[in]     i_width          Represents the width of the field within the reg
 * @param[in]     i_data           Data to be set
 * @param[in,out] io_register_data Scom Data
 * @return void
 */
inline void set(
    const uint64_t  i_scom_addr,
    const uint8_t   i_start,
    const uint8_t   i_width,
    const uint64_t  i_data,
    uint64_t&   io_register_data )
{
    const uint8_t REGISTER_WIDTH = 64;
    const uint8_t SHIFT          = REGISTER_WIDTH - i_start - i_width;
    const uint64_t MASK          = ( ( (uint64_t)0x1 << i_width ) - 1 ) << SHIFT;
    io_register_data = ( ( io_register_data & ~MASK ) | ( ( i_data << SHIFT ) & MASK ) );
    return;
}

/**
 * @brief Builds the base scom address
 * @tparam[in] K       fapi2::TargetType
 * @param[in] i_target FAPI2 Target
 * @return 32bit encoded base scom address
 */
template < fapi2::TargetType K >
inline uint32_t get_base_address( const fapi2::Target < K > i_target, uint32_t& o_base_addr )
{
    switch( i_target.getType() )
    {
        case fapi2::TargetType::TARGET_TYPE_XBUS:
            o_base_addr = P9_XBUS_PHY_BASE_0x06010C00;
            break;

        case fapi2::TargetType::TARGET_TYPE_DMI:
            o_base_addr = P9_DMI0_PHY_BASE_0x0701103F;
            break;

        case fapi2::TargetType::TARGET_TYPE_MC:
            o_base_addr = P9_DMI0_PHY_BASE_0x0701103F;
            break;

        case fapi2::TargetType::TARGET_TYPE_ABUS:
        case fapi2::TargetType::TARGET_TYPE_OBUS:
            o_base_addr = P9_OBUS0_PHY_BASE_0x09010C00;
            break;

        case fapi2::TargetType::TARGET_TYPE_MEMBUF_CHIP:
            o_base_addr = CEN_PHY_BASE_0x02010400;
            break;

        default:
            fapi2::IO_GCR_TARGET_TYPE_NOT_FOUND().set_TARGET( i_target ).execute();
            FAPI_ERR("TargetType not found(0x%X)", i_target.getType());
    }

    return fapi2::current_err;
}

/**
 * @brief Builds the base scom address, group, and lane into the full
 *   scom address
 * @tparam[in] K          fapi2::TargetType
 * @param[in] i_target    FAPI2 Target
 * @param[in] i_scom_addr Register scom address information
 * @param[in] i_group     Group encoded into the scom address
 * @param[in] i_lane      Lane encoded into the scom address
 * @return Full 64bit encoded scom address
 */
template < fapi2::TargetType K >
inline uint64_t build_address(
    const fapi2::Target < K > i_target,
    const uint64_t            i_scom_addr,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    uint64_t& o_addr )
{
    const uint8_t ADDRESS_SIZE = 64;
    const uint8_t GROUP_START  = 22;
    const uint8_t GROUP_WIDTH  = 5;
    const uint8_t LANE_START   = 27;
    const uint8_t LANE_WIDTH   = 5;
    const uint8_t GROUP_SHIFT  = ADDRESS_SIZE - GROUP_START - GROUP_WIDTH;
    const uint8_t LANE_SHIFT   = ADDRESS_SIZE - LANE_START  - LANE_WIDTH;

    uint32_t l_base_addr = 0;
    FAPI_TRY( get_base_address( i_target, l_base_addr ) )
    o_addr = ( i_scom_addr | l_base_addr
               | ( (uint64_t) i_group << GROUP_SHIFT )
               | ( (uint64_t) i_lane  << LANE_SHIFT  ) );
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM read function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[out] o_data      Scom Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode read(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    uint64_t&                 o_data )
{
    fapi2::buffer<uint64_t> l_register_data;

    // Stitch together the base scom address, register info, group, lane
    uint64_t l_address = 0;
    FAPI_TRY( build_address( i_target, i_scom_addr, i_group, i_lane, l_address ) );

    // Execute fapi2 getscom
    FAPI_TRY( fapi2::getScom( i_target, l_address, l_register_data ),
              "getScom Failed(0x%X): Addr(0x%016llX) Data(0x%016llX)",
              (uint64_t) fapi2::current_err, l_address, (uint64_t)l_register_data );

    o_data = l_register_data;
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM write function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[in]  i_data      Scom Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode write(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    const uint64_t            i_data )
{
    fapi2::buffer<uint64_t> l_register_data( i_data );

    // Stitch together the base scom address, register info, group, lane
    uint64_t l_address = 0;
    FAPI_TRY( build_address( i_target, i_scom_addr, i_group, i_lane, l_address ) );

    // Execute fapi2 putscom
    FAPI_TRY( fapi2::putScom( i_target, l_address, l_register_data ),
              "putScom Failed(0x%X): Addr(0x%016llX) Data(0x%016llX)",
              (uint64_t) fapi2::current_err, l_address, i_data );
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM read modify write function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[in]  i_data      Field Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode rmw(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    const uint64_t            i_data )
{
    uint64_t l_register_data = 0;

    FAPI_TRY( read(
                  i_scom_addr,
                  i_start,
                  i_width,
                  i_target,
                  i_group,
                  i_lane,
                  l_register_data ) );

    set(i_scom_addr, i_start, i_width, i_data, l_register_data );

    FAPI_TRY( write(
                  i_scom_addr,
                  i_start,
                  i_width,
                  i_target,
                  i_group,
                  i_lane,
                  l_register_data ) );
fapi_try_exit:
    return fapi2::current_err;
}
};

#endif /* P9_IO_SCOM_H_ */
<commit_msg>I/O Metadata Cleanup<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_scom.H $          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_scom.H
/// @brief Register Access.
///----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 3
/// *HWP Consumed by      : FSP:HB
///----------------------------------------------------------------------------
///
/// @verbatim
/// Register Access via scom.
///
/// @endverbatim
///----------------------------------------------------------------------------

#ifndef P9_IO_SCOM_H_
#define P9_IO_SCOM_H_

//* *****************************
//* Defines
//* *****************************

// @brief IO Base Addresses
#define P9_PSI_PHY_BASE_0x00000000       0x00000000
#define P9_XBUS_PHY_BASE_0x06010C00      0x06010C00
#define P9_ABUS0_PHY_BASE_0x09011000     0x09011000
#define P9_ABUS3_PHY_BASE_0x0C011000     0x0C011000
#define P9_OBUS0_PHY_BASE_0x09010C00     0x09010C00
#define P9_OBUS1_PHY_BASE_0x0A010C00     0x0A010C00
#define P9_OBUS2_PHY_BASE_0x0B010C00     0x0B010C00
#define P9_OBUS3_PHY_BASE_0x0C010C00     0x0C010C00
#define P9_DMI0_PHY_BASE_0x0701103F      0x0701103F
#define CEN_PHY_BASE_0x02010400          0x02010400

//-----------------------------------------------------------------------------
//  FAPI Includes
//-----------------------------------------------------------------------------
#include <fapi2.H>

/**
 * @namespace io
 * This class provides a generic class for a register to read/write SCOMs.
 */
namespace io
{

/**
 * @brief Parses the register data by the i_start and i_width of a field and returns
 *        a right aligned value.
 * @param[in] i_scom_addr     Not used
 * @param[in] i_start         Represents the start bit of the field within the reg
 * @param[in] i_width         Represents the width of the field within the reg
 * @param[in] i_register_data Scom Data from previous io::read()
 * @return Field Data
 */
inline uint64_t get(
    const uint64_t i_scom_addr,
    const uint8_t  i_start,
    const uint8_t  i_width,
    const uint64_t i_register_data )
{
    const uint8_t REGISTER_WIDTH = 64;
    const uint8_t SHIFT          = REGISTER_WIDTH - i_start - i_width;
    const uint64_t MASK          = ( ( (uint64_t)0x1 << i_width ) - 1 ) << SHIFT;
    return ( ( i_register_data & MASK ) >> SHIFT );
}

/**
 * @brief Sets the field specified by the i_start and i_width of the register data to the right
 *        alighted i_data.
 * @param[in]     i_scom_addr      Is not used in this function.
 * @param[in]     i_start          Represents the start bit of the field within the reg
 * @param[in]     i_width          Represents the width of the field within the reg
 * @param[in]     i_data           Data to be set
 * @param[in,out] io_register_data Scom Data
 * @return void
 */
inline void set(
    const uint64_t  i_scom_addr,
    const uint8_t   i_start,
    const uint8_t   i_width,
    const uint64_t  i_data,
    uint64_t&   io_register_data )
{
    const uint8_t REGISTER_WIDTH = 64;
    const uint8_t SHIFT          = REGISTER_WIDTH - i_start - i_width;
    const uint64_t MASK          = ( ( (uint64_t)0x1 << i_width ) - 1 ) << SHIFT;
    io_register_data = ( ( io_register_data & ~MASK ) | ( ( i_data << SHIFT ) & MASK ) );
    return;
}

/**
 * @brief Builds the base scom address
 * @tparam[in] K       fapi2::TargetType
 * @param[in] i_target FAPI2 Target
 * @return 32bit encoded base scom address
 */
template < fapi2::TargetType K >
inline uint32_t get_base_address( const fapi2::Target < K > i_target, uint32_t& o_base_addr )
{
    switch( i_target.getType() )
    {
        case fapi2::TargetType::TARGET_TYPE_XBUS:
            o_base_addr = P9_XBUS_PHY_BASE_0x06010C00;
            break;

        case fapi2::TargetType::TARGET_TYPE_DMI:
            o_base_addr = P9_DMI0_PHY_BASE_0x0701103F;
            break;

        case fapi2::TargetType::TARGET_TYPE_MC:
            o_base_addr = P9_DMI0_PHY_BASE_0x0701103F;
            break;

        case fapi2::TargetType::TARGET_TYPE_ABUS:
        case fapi2::TargetType::TARGET_TYPE_OBUS:
            o_base_addr = P9_OBUS0_PHY_BASE_0x09010C00;
            break;

        case fapi2::TargetType::TARGET_TYPE_MEMBUF_CHIP:
            o_base_addr = CEN_PHY_BASE_0x02010400;
            break;

        default:
            fapi2::IO_GCR_TARGET_TYPE_NOT_FOUND().set_TARGET( i_target ).execute();
            FAPI_ERR("TargetType not found(0x%X)", i_target.getType());
    }

    return fapi2::current_err;
}

/**
 * @brief Builds the base scom address, group, and lane into the full
 *   scom address
 * @tparam[in] K          fapi2::TargetType
 * @param[in] i_target    FAPI2 Target
 * @param[in] i_scom_addr Register scom address information
 * @param[in] i_group     Group encoded into the scom address
 * @param[in] i_lane      Lane encoded into the scom address
 * @return Full 64bit encoded scom address
 */
template < fapi2::TargetType K >
inline uint64_t build_address(
    const fapi2::Target < K > i_target,
    const uint64_t            i_scom_addr,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    uint64_t& o_addr )
{
    const uint8_t ADDRESS_SIZE = 64;
    const uint8_t GROUP_START  = 22;
    const uint8_t GROUP_WIDTH  = 5;
    const uint8_t LANE_START   = 27;
    const uint8_t LANE_WIDTH   = 5;
    const uint8_t GROUP_SHIFT  = ADDRESS_SIZE - GROUP_START - GROUP_WIDTH;
    const uint8_t LANE_SHIFT   = ADDRESS_SIZE - LANE_START  - LANE_WIDTH;

    uint32_t l_base_addr = 0;
    FAPI_TRY( get_base_address( i_target, l_base_addr ) )
    o_addr = ( i_scom_addr | l_base_addr
               | ( (uint64_t) i_group << GROUP_SHIFT )
               | ( (uint64_t) i_lane  << LANE_SHIFT  ) );
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM read function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[out] o_data      Scom Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode read(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    uint64_t&                 o_data )
{
    fapi2::buffer<uint64_t> l_register_data;

    // Stitch together the base scom address, register info, group, lane
    uint64_t l_address = 0;
    FAPI_TRY( build_address( i_target, i_scom_addr, i_group, i_lane, l_address ) );

    // Execute fapi2 getscom
    FAPI_TRY( fapi2::getScom( i_target, l_address, l_register_data ),
              "getScom Failed(0x%X): Addr(0x%016llX) Data(0x%016llX)",
              (uint64_t) fapi2::current_err, l_address, (uint64_t)l_register_data );

    o_data = l_register_data;
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM write function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[in]  i_data      Scom Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode write(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    const uint64_t            i_data )
{
    fapi2::buffer<uint64_t> l_register_data( i_data );

    // Stitch together the base scom address, register info, group, lane
    uint64_t l_address = 0;
    FAPI_TRY( build_address( i_target, i_scom_addr, i_group, i_lane, l_address ) );

    // Execute fapi2 putscom
    FAPI_TRY( fapi2::putScom( i_target, l_address, l_register_data ),
              "putScom Failed(0x%X): Addr(0x%016llX) Data(0x%016llX)",
              (uint64_t) fapi2::current_err, l_address, i_data );
fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief SCOM read modify write function
 * @tparam[in] K           fapi2::TargetType
 * @param[in]  i_scom_addr Register Scom Information
 * @param[in]  i_start     Represents the start bit of the field within the reg
 * @param[in]  i_width     Represents the width of the field within the reg
 * @param[in]  i_target    Target to operate on
 * @param[in]  i_group     Group to operate on
 * @param[in]  i_lane      Lane to operate on
 * @param[in]  i_data      Field Data
 * @return return code. Zero on success, else platform specified error
 */
template < fapi2::TargetType K >
inline fapi2::ReturnCode rmw(
    const uint64_t            i_scom_addr,
    const uint8_t             i_start,
    const uint8_t             i_width,
    const fapi2::Target < K > i_target,
    const uint8_t             i_group,
    const uint8_t             i_lane,
    const uint64_t            i_data )
{
    uint64_t l_register_data = 0;

    FAPI_TRY( read(
                  i_scom_addr,
                  i_start,
                  i_width,
                  i_target,
                  i_group,
                  i_lane,
                  l_register_data ) );

    set(i_scom_addr, i_start, i_width, i_data, l_register_data );

    FAPI_TRY( write(
                  i_scom_addr,
                  i_start,
                  i_width,
                  i_target,
                  i_group,
                  i_lane,
                  l_register_data ) );
fapi_try_exit:
    return fapi2::current_err;
}
};

#endif /* P9_IO_SCOM_H_ */
<|endoftext|>


<commit_before>//! \file CurlWikiGrabber.cpp

#include "CurlWikiGrabber.h"

#include <cassert>

#include <curl/curl.h>

#include "WalkerException.h"

namespace WikiWalker
{
  static size_t write_callback(char* ptr,
                               size_t size,
                               size_t nmemb,
                               void* userdata)
  {
    static_cast<std::string*>(userdata)->append(ptr, size * nmemb);
    return size * nmemb;
  }

  CurlWikiGrabber::CurlWikiGrabber() : skipSslVerificationState_(false)
  {
    int error = curl_global_init(CURL_GLOBAL_ALL);

    if(error != 0) {
      throw WalkerException("CURL init failed");
    }
  }

  CurlWikiGrabber::~CurlWikiGrabber()
  {
    curl_global_cleanup();
  }

  //! \todo Curl return code checking
  std::string CurlWikiGrabber::grabUrl(const std::string& url) const
  {
    CURL* handle = curl_easy_init();

    if(nullptr == handle) {
      throw WalkerException("error initiating curl");
    }

    CURLcode crv = curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
    assert(crv == 0);
    crv = curl_easy_setopt(handle,
                           CURLOPT_USERAGENT,
                           "WikiWalker / github.com/dueringa/WikiWalker");
    assert(crv == 0);
    crv = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
    assert(crv == 0);
    // allow redirects
    crv = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
    assert(crv == 0);
    crv = curl_easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "gzip");
    assert(crv == 0);

    if(skipSslVerificationState_) {
      // hostname verification
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
      assert(crv == 0);
      // check against CA
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
      assert(crv == 0);
      // ignore status
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYSTATUS, 0);
      assert(crv == 0);
    }

    std::string gotContent;
    crv = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &gotContent);
    assert(crv == 0);

    gotContent = "";
    crv        = curl_easy_perform(handle);

    if(crv != 0) {
      const char* err = curl_easy_strerror(crv);
      std::string text(err);
      throw WalkerException(text);
    }

    long httpcode = 0;
    crv = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &httpcode);
    assert(crv == 0);

    curl_easy_cleanup(handle);

    handle = nullptr;

    if(httpcode != 200) {
      throw WalkerException("Error getting article. HTTP error.");
    }

    return gotContent;
  }

  void CurlWikiGrabber::skipSslVerification(bool state)
  {
    skipSslVerificationState_ = state;
  }
}  // namespace WikiWalker

// note to self: API
// https://en.wikipedia.org/w/api.php
// /w/api.php?action=query&format=json&prop=links&plnamespace=0&titles=<title>
// maybe &pllimit=100
<commit_msg>Fix compilation with old libcurl versions<commit_after>//! \file CurlWikiGrabber.cpp

#include "CurlWikiGrabber.h"

#include <cassert>

#include <curl/curl.h>

#include "WalkerException.h"

namespace WikiWalker
{
  static size_t write_callback(char* ptr,
                               size_t size,
                               size_t nmemb,
                               void* userdata)
  {
    static_cast<std::string*>(userdata)->append(ptr, size * nmemb);
    return size * nmemb;
  }

  CurlWikiGrabber::CurlWikiGrabber() : skipSslVerificationState_(false)
  {
    int error = curl_global_init(CURL_GLOBAL_ALL);

    if(error != 0) {
      throw WalkerException("CURL init failed");
    }
  }

  CurlWikiGrabber::~CurlWikiGrabber()
  {
    curl_global_cleanup();
  }

  //! \todo Curl return code checking
  std::string CurlWikiGrabber::grabUrl(const std::string& url) const
  {
    CURL* handle = curl_easy_init();

    if(nullptr == handle) {
      throw WalkerException("error initiating curl");
    }

    CURLcode crv = curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
    assert(crv == 0);
    crv = curl_easy_setopt(handle,
                           CURLOPT_USERAGENT,
                           "WikiWalker / github.com/dueringa/WikiWalker");
    assert(crv == 0);
    crv = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
    assert(crv == 0);
    // allow redirects
    crv = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
    assert(crv == 0);
    crv = curl_easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "gzip");
    assert(crv == 0);

    if(skipSslVerificationState_) {
      // hostname verification
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
      assert(crv == 0);
      // check against CA
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0);
      assert(crv == 0);
#ifdef CURLOPT_SSL_VERIFYSTATUS
      // ignore status
      crv = curl_easy_setopt(handle, CURLOPT_SSL_VERIFYSTATUS, 0);
      assert(crv == 0);
#endif
    }

    std::string gotContent;
    crv = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &gotContent);
    assert(crv == 0);

    gotContent = "";
    crv        = curl_easy_perform(handle);

    if(crv != 0) {
      const char* err = curl_easy_strerror(crv);
      std::string text(err);
      throw WalkerException(text);
    }

    long httpcode = 0;
    crv = curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &httpcode);
    assert(crv == 0);

    curl_easy_cleanup(handle);

    handle = nullptr;

    if(httpcode != 200) {
      throw WalkerException("Error getting article. HTTP error.");
    }

    return gotContent;
  }

  void CurlWikiGrabber::skipSslVerification(bool state)
  {
    skipSslVerificationState_ = state;
  }
}  // namespace WikiWalker

// note to self: API
// https://en.wikipedia.org/w/api.php
// /w/api.php?action=query&format=json&prop=links&plnamespace=0&titles=<title>
// maybe &pllimit=100
<|endoftext|>


<commit_before>#pragma once

#include "LocalHook.hpp"
#include "../Misc/DynImport.h"

namespace blackbone
{

template<typename Fn, class C = NoClass>
class VTableDetour : public Detour<Fn, C>
{
public:
    using type    = typename HookHandler<Fn, C>::type;
    using hktype  = typename HookHandler<Fn, C>::hktype;
    using hktypeC = typename HookHandler<Fn, C>::hktypeC;

public:
    VTableDetour()
    {
        DetourBase::AllocateBuffer( nullptr );
    }

    ~VTableDetour()
    {
        Restore();
    }

    /// <summary>
    /// Hook function in vtable
    /// </summary>
    /// <param name="ppVtable">Pointer to vtable pointer</param>
    /// <param name="index">Function index</param>
    /// <param name="hkPtr">Hook function address</param>
    /// <param name="order">Call order. Hook before original or vice versa</param>
    /// <param name="retType">Return value. Use origianl or value from hook</param>
    /// <param name="copyVtable">if true, vtable will be copied and edited, otherwise existing vtable will be edited</param>
    /// <param name="vtableLen">Optional. Valid only when copyVtable is true. Number of function in vtable.
    /// Used to determine number of function to copy</param>
    /// <returns>true on success</returns>
    bool Hook(
        void** ppVtable,
        int index,
        hktype hkPtr,
        CallOrder::e order = CallOrder::HookFirst,
        ReturnMethod::e retType = ReturnMethod::UseOriginal,
        bool copyVtable = false,
        int vtableLen = 0
        )
    {
        auto jmpToHook = AsmFactory::GetAssembler();

        this->_type = HookType::VTable;
        this->_order = order;
        this->_retType = retType;
        this->_callOriginal = this->_original = (*(void***)ppVtable)[index];
        this->_callback = hkPtr;
        this->_internalHandler = &HookHandler<Fn, C>::Handler;
        this->_ppVtable = ppVtable;
        this->_pVtable = *ppVtable;
        this->_vtIndex = index;
        this->_vtCopied = copyVtable;

        // Construct jump to hook handler
#ifdef USE64
        // mov gs:[0x28], this
        (*jmpToHook)->mov( asmjit::host::rax, (uint64_t)this );
        (*jmpToHook)->mov( asmjit::host::qword_ptr_abs( 0x28 ).setSegment( asmjit::host::gs ), asmjit::host::rax );
#else
        // mov fs:[0x14], this
        (*jmpToHook)->mov( asmjit::host::dword_ptr_abs( 0x14 ).setSegment( asmjit::host::fs ), (uint32_t)this );
#endif // USE64

        (*jmpToHook)->jmp( (asmjit::Ptr)this->_internalHandler );
        (*jmpToHook)->relocCode( this->_buf );

        // Modify VTable copy
        if (copyVtable)
        {
            // Copy VTable
            if (vtableLen != 0)
            {
                memcpy( this->_buf + 0x300, *ppVtable, vtableLen * sizeof( void* ) );
            }
            else
            {
                Process proc;
                proc.Attach( GetCurrentProcessId() );
                auto vptr = (*(uintptr_t**)ppVtable)[index];
                auto mod = proc.modules().GetModule( vptr, false );
                uintptr_t imageBase = static_cast<uintptr_t>(mod->baseAddress);
                uintptr_t imageSzie = mod->size;

                for (;; vtableLen++)
                {
                    vptr = (*(uintptr_t**)ppVtable)[vtableLen];
                    if (vptr < imageBase || vptr >= imageBase + imageSzie)
                    {
                        memcpy( this->_buf + 0x300, *ppVtable, vtableLen * sizeof( void* ) );
                        break;
                    }
                }
            }

            // Replace pointer to VTable
            ((void**)this->_buf + 0x300 / sizeof( uintptr_t ))[index] = this->_buf;
            *ppVtable = this->_buf + 0x300;
        }
        // Modify pointer in-place
        else
        {
            DWORD flOld = 0;

            VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), PAGE_EXECUTE_READWRITE, &flOld );
            (*(void***)ppVtable)[index] = this->_buf;
            VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), flOld, &flOld );
        }

        return (this->_hooked = true);
    }

    /// <summary>
    /// Hooks function in vtable
    /// </summary>
    /// <param name="ppVtable">Pointer to vtable pointer</param>
    /// <param name="index">Function index</param>
    /// <param name="hkPtr">Hook class member address</param>
    /// <param name="pClass">Hook class address</param>
    /// <param name="order">Call order. Hook before original or vice versa</param>
    /// <param name="retType">Return value. Use origianl or value from hook</param>
    /// <param name="copyVtable">if true, vtable will be copied and edited, otherwise existing vtable will be edited</param>
    /// <param name="vtableLen">Optional. Valid only when copyVtable is true. Number of function in vtable.
    /// Used to determine number of function to copy</param>
    /// <returns>true on success</returns>
    bool Hook(
        void** ppVtable,
        int index,
        hktypeC hkPtr,
        C* pClass,
        CallOrder::e order = CallOrder::HookFirst,
        ReturnMethod::e retType = ReturnMethod::UseOriginal,
        bool copyVtable = false,
        int vtableLen = 0
        )
    {
        this->_callbackClass = pClass;
        return Hook( ppVtable, index, brutal_cast<hktype>(hkPtr), order, retType, copyVtable, vtableLen );
    }

    /// <summary>
    /// Restore hooked function
    /// </summary>
    /// <returns>true on success, false if not hooked</returns>
    bool Restore()
    {
        if (!this->_hooked)
            return false;

        if (this->_vtCopied)
        {
            *this->_ppVtable = this->_pVtable;
        }
        else
        {
            DWORD flOld = 0;

            VirtualProtect( *(uintptr_t**)this->_ppVtable + this->_vtIndex, sizeof( void* ), PAGE_EXECUTE_READWRITE, &flOld );
            (*(void***)this->_ppVtable)[this->_vtIndex] = this->_original;
            VirtualProtect( *(uintptr_t**)this->_ppVtable + this->_vtIndex, sizeof( void* ), flOld, &flOld );
        }

        this->_hooked = false;
        return true;
    }

private:
    bool   _vtCopied = false;           // VTable was copied
    void** _ppVtable = nullptr;         // Pointer to VTable pointer
    void*  _pVtable = nullptr;          // Pointer to VTable
    int    _vtIndex = 0;                // VTable function index
};

}<commit_msg>keep rtti pointer in vtable hook<commit_after>#pragma once

#include "LocalHook.hpp"
#include "../Misc/DynImport.h"

namespace blackbone
{

template<typename Fn, class C = NoClass>
class VTableDetour : public Detour<Fn, C>
{
public:
    using type    = typename HookHandler<Fn, C>::type;
    using hktype  = typename HookHandler<Fn, C>::hktype;
    using hktypeC = typename HookHandler<Fn, C>::hktypeC;

public:
    VTableDetour()
    {
        DetourBase::AllocateBuffer( nullptr );
    }

    ~VTableDetour()
    {
        Restore();
    }

    /// <summary>
    /// Hook function in vtable
    /// </summary>
    /// <param name="ppVtable">Pointer to vtable pointer</param>
    /// <param name="index">Function index</param>
    /// <param name="hkPtr">Hook function address</param>
    /// <param name="order">Call order. Hook before original or vice versa</param>
    /// <param name="retType">Return value. Use origianl or value from hook</param>
    /// <param name="copyVtable">if true, vtable will be copied and edited, otherwise existing vtable will be edited</param>
    /// <param name="vtableLen">Optional. Valid only when copyVtable is true. Number of function in vtable.
    /// Used to determine number of function to copy</param>
    /// <returns>true on success</returns>
    bool Hook(
        void** ppVtable,
        int index,
        hktype hkPtr,
        CallOrder::e order = CallOrder::HookFirst,
        ReturnMethod::e retType = ReturnMethod::UseOriginal,
        bool copyVtable = false,
        int vtableLen = 0
        )
    {
        auto jmpToHook = AsmFactory::GetAssembler();

        this->_type = HookType::VTable;
        this->_order = order;
        this->_retType = retType;
        this->_callOriginal = this->_original = (*(void***)ppVtable)[index];
        this->_callback = hkPtr;
        this->_internalHandler = &HookHandler<Fn, C>::Handler;
        this->_ppVtable = ppVtable;
        this->_pVtable = *ppVtable;
        this->_vtIndex = index;
        this->_vtCopied = copyVtable;

        // Construct jump to hook handler
#ifdef USE64
        // mov gs:[0x28], this
        (*jmpToHook)->mov( asmjit::host::rax, (uint64_t)this );
        (*jmpToHook)->mov( asmjit::host::qword_ptr_abs( 0x28 ).setSegment( asmjit::host::gs ), asmjit::host::rax );
#else
        // mov fs:[0x14], this
        (*jmpToHook)->mov( asmjit::host::dword_ptr_abs( 0x14 ).setSegment( asmjit::host::fs ), (uint32_t)this );
#endif // USE64

        (*jmpToHook)->jmp( (asmjit::Ptr)this->_internalHandler );
        (*jmpToHook)->relocCode( this->_buf );

        // Modify VTable copy
        if (copyVtable)
        {
            // Copy VTable
            if (vtableLen != 0)
            {
                memcpy( this->_buf + 0x300 - sizeof( void* ), (*(void***)ppVtable) - 1, vtableLen * sizeof( void* ) );
            }
            else
            {
                Process proc;
                proc.Attach( GetCurrentProcessId() );
                auto vptr = (*(uintptr_t**)ppVtable)[index];
                auto mod = proc.modules().GetModule( vptr, false );
                uintptr_t imageBase = static_cast<uintptr_t>(mod->baseAddress);
                uintptr_t imageSzie = mod->size;

                for (;; vtableLen++)
                {
                    vptr = (*(uintptr_t**)ppVtable)[vtableLen];
                    if (vptr < imageBase || vptr >= imageBase + imageSzie)
                    {
                        memcpy( this->_buf + 0x300 - sizeof( void* ), (*(void***)ppVtable) - 1, vtableLen * sizeof( void* ) );
                        break;
                    }
                }
            }

            // Replace pointer to VTable
            ((void**)this->_buf + 0x300 / sizeof( uintptr_t ))[index] = this->_buf;
            *ppVtable = this->_buf + 0x300;
        }
        // Modify pointer in-place
        else
        {
            DWORD flOld = 0;

            VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), PAGE_EXECUTE_READWRITE, &flOld );
            (*(void***)ppVtable)[index] = this->_buf;
            VirtualProtect( *(uintptr_t**)ppVtable + index, sizeof(void*), flOld, &flOld );
        }

        return (this->_hooked = true);
    }

    /// <summary>
    /// Hooks function in vtable
    /// </summary>
    /// <param name="ppVtable">Pointer to vtable pointer</param>
    /// <param name="index">Function index</param>
    /// <param name="hkPtr">Hook class member address</param>
    /// <param name="pClass">Hook class address</param>
    /// <param name="order">Call order. Hook before original or vice versa</param>
    /// <param name="retType">Return value. Use origianl or value from hook</param>
    /// <param name="copyVtable">if true, vtable will be copied and edited, otherwise existing vtable will be edited</param>
    /// <param name="vtableLen">Optional. Valid only when copyVtable is true. Number of function in vtable.
    /// Used to determine number of function to copy</param>
    /// <returns>true on success</returns>
    bool Hook(
        void** ppVtable,
        int index,
        hktypeC hkPtr,
        C* pClass,
        CallOrder::e order = CallOrder::HookFirst,
        ReturnMethod::e retType = ReturnMethod::UseOriginal,
        bool copyVtable = false,
        int vtableLen = 0
        )
    {
        this->_callbackClass = pClass;
        return Hook( ppVtable, index, brutal_cast<hktype>(hkPtr), order, retType, copyVtable, vtableLen );
    }

    /// <summary>
    /// Restore hooked function
    /// </summary>
    /// <returns>true on success, false if not hooked</returns>
    bool Restore()
    {
        if (!this->_hooked)
            return false;

        if (this->_vtCopied)
        {
            *this->_ppVtable = this->_pVtable;
        }
        else
        {
            DWORD flOld = 0;

            VirtualProtect( *(uintptr_t**)this->_ppVtable + this->_vtIndex, sizeof( void* ), PAGE_EXECUTE_READWRITE, &flOld );
            (*(void***)this->_ppVtable)[this->_vtIndex] = this->_original;
            VirtualProtect( *(uintptr_t**)this->_ppVtable + this->_vtIndex, sizeof( void* ), flOld, &flOld );
        }

        this->_hooked = false;
        return true;
    }

private:
    bool   _vtCopied = false;           // VTable was copied
    void** _ppVtable = nullptr;         // Pointer to VTable pointer
    void*  _pVtable = nullptr;          // Pointer to VTable
    int    _vtIndex = 0;                // VTable function index
};

}<|endoftext|>