<commit_before>// Sh: A GPU metaprogramming language.
//
// Copyright 2003-2005 Serious Hack Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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., 51 Franklin Street, Fifth Floor, Boston,
// MA  02110-1301, USA
//////////////////////////////////////////////////////////////////////////////
#include "GlslCode.hpp"
#include <iostream>

#define SH_DEBUG_GLSL_BACKEND

namespace shgl {

using namespace SH;
using namespace std;

GlslSet::GlslSet()
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  SH_DEBUG_ASSERT(m_arb_program);

  m_shaders[0] = 0;
  m_shaders[1] = 0;
}

GlslSet::GlslSet(const SH::ShPointer<GlslCode>& code)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  SH_DEBUG_ASSERT(m_arb_program);

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  attach(code);
}

GlslSet::GlslSet(const SH::ShProgramSet& s)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  SH_DEBUG_ASSERT(m_arb_program);

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  for (ShProgramSet::const_iterator I = s.begin(); I != s.end(); ++I) {
    // TODO: use the glsl backend
    GlslCodePtr code = shref_dynamic_cast<GlslCode>((*I)->code());

    // TODO: use shError()
    SH_DEBUG_ASSERT(code);
    SH_DEBUG_ASSERT(!m_shaders[code->glsl_unit()]);

    attach(code);
  }
}

GlslSet::GlslSet(const GlslSet& other)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  SH_DEBUG_ASSERT(m_arb_program);

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  attach(other.m_shaders[0]);
  attach(other.m_shaders[1]);
}

GlslSet& GlslSet::operator=(const GlslSet& other)
{
  if (&other == this) return *this;

  unbind();

  detach(m_shaders[0]);
  detach(m_shaders[1]);
  attach(other.m_shaders[0]);
  attach(other.m_shaders[1]);

  m_linked = false;

  return *this;
}

GlslSet::~GlslSet()
{
  unbind(); // this is necessary
  SH_GL_CHECK_ERROR(glDeleteObjectARB(m_arb_program));
  m_arb_program = 0;
}

void GlslSet::attach(const SH::ShPointer<GlslCode>& code)
{
  SH_DEBUG_ASSERT(m_arb_program);

  if (!code) return;
  if (m_shaders[code->glsl_unit()] == code) return;

  // Unbind old shader
  unbind();
  if (m_shaders[code->glsl_unit()]) {
    SH_GL_CHECK_ERROR(glDetachObjectARB(m_arb_program, m_shaders[code->glsl_unit()]->glsl_shader()));
  }

  // Bind new shader
  SH_GL_CHECK_ERROR(glAttachObjectARB(m_arb_program, code->glsl_shader()));
  m_shaders[code->glsl_unit()] = code;
  code->bind_generic_attributes(m_arb_program);

  m_linked = false; // will need to relink
}

void GlslSet::detach(const SH::ShPointer<GlslCode>& code)
{
  if (!code) return;
  if (m_shaders[code->glsl_unit()] != code) return;

  unbind();

  SH_DEBUG_ASSERT(m_arb_program);
  SH_GL_CHECK_ERROR(glDetachObjectARB(m_arb_program, code->glsl_shader()));
  m_shaders[code->glsl_unit()] = 0;

  // Need to relink
  m_linked = false;
}

void GlslSet::replace(const SH::ShPointer<GlslCode>& code)
{
  SH_DEBUG_ASSERT(code);
  if (m_shaders[code->glsl_unit()] == code && !m_shaders[1 - code->glsl_unit()]) return;

  detach(m_shaders[0]);
  detach(m_shaders[1]);
  attach(code);
}

void GlslSet::link()
{
  SH_DEBUG_ASSERT(m_arb_program);

  SH_GL_CHECK_ERROR(glLinkProgramARB(m_arb_program));

  // Check linking
  GLint linked;
  glGetObjectParameterivARB(m_arb_program, GL_OBJECT_LINK_STATUS_ARB, &linked);
  if (linked != GL_TRUE) {
    cout << "Program link status: FAILED" << endl << endl;
    cout << "Program infolog:" << endl;
    print_infolog(m_arb_program);
    cout << "Program code:" << endl;
    print_shader_source(m_arb_program);
    cout << endl;
    return;
  }

  m_linked = true;
}

bool GlslSet::empty() const
{
  if (m_shaders[0]) return false;
  if (m_shaders[1]) return false;
  return true;
}

void GlslSet::bind()
{
  if (m_bound) {
    for (int i = 0; i < 2; i++) {
      if (!m_shaders[i]) continue;
      m_shaders[i]->update();
    }
    return;
  }

  if (!m_linked) link();

  if (current() && current() != this) current()->unbind();

  SH_GL_CHECK_ERROR(glUseProgramObjectARB(m_arb_program));

#ifdef SH_DEBUG_GLSL_BACKEND
  // This could be slow, it should not be enabled in release code
  glValidateProgramARB(m_arb_program);
  GLint validated;
  glGetObjectParameterivARB(m_arb_program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated);
  if (validated != GL_TRUE) {
    cout << "Program validate status: FAILED" << endl;
    cout << "Program infolog:" << endl;
    print_infolog(m_arb_program);
  }
#endif

  for (int i = 0; i < 2; i++) {
    if (!m_shaders[i]) continue;
    GlslCodePtr shader = m_shaders[i];
    shader->set_bound(m_arb_program);

    shader->upload_uniforms();
    shader->bind_textures();
  }

  m_current = this;
  m_bound = true;
}

void GlslSet::unbind()
{
  if (!m_bound) return;

  SH_GL_CHECK_ERROR(glUseProgramObjectARB(0));

  for (int i = 0; i < 2; i++) {
    if (!m_shaders[i]) continue;
    m_shaders[i]->set_bound(0);
  }
  m_current = 0;
  m_bound = false;
}

}
<commit_msg>Replace debug warning by a running error when the drivers don't support glsl.<commit_after>// Sh: A GPU metaprogramming language.
//
// Copyright 2003-2005 Serious Hack Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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., 51 Franklin Street, Fifth Floor, Boston,
// MA  02110-1301, USA
//////////////////////////////////////////////////////////////////////////////
#include "GlslCode.hpp"
#include <iostream>

#define SH_DEBUG_GLSL_BACKEND

namespace shgl {

using namespace SH;
using namespace std;

GlslSet::GlslSet()
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  if (!m_arb_program) {
    shError(ShBackendException("Cannot create a glsl program object. Is glsl supported by your GPU/drivers ?"));
  }

  m_shaders[0] = 0;
  m_shaders[1] = 0;
}

GlslSet::GlslSet(const SH::ShPointer<GlslCode>& code)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  if (!m_arb_program) {
    shError(ShBackendException("Cannot create a glsl program object. Is glsl supported by your GPU/drivers ?"));
  }

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  attach(code);
}

GlslSet::GlslSet(const SH::ShProgramSet& s)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  if (!m_arb_program) {
    shError(ShBackendException("Cannot create a glsl program object. Is glsl supported by your GPU/drivers ?"));
  }

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  for (ShProgramSet::const_iterator I = s.begin(); I != s.end(); ++I) {
    // TODO: use the glsl backend
    GlslCodePtr code = shref_dynamic_cast<GlslCode>((*I)->code());

    // TODO: use shError()
    SH_DEBUG_ASSERT(code);
    SH_DEBUG_ASSERT(!m_shaders[code->glsl_unit()]);

    attach(code);
  }
}

GlslSet::GlslSet(const GlslSet& other)
  : m_linked(false), m_bound(false)
{
  SH_GL_CHECK_ERROR(m_arb_program = glCreateProgramObjectARB());
  if (!m_arb_program) {
    shError(ShBackendException("Cannot create a glsl program object. Is glsl supported by your GPU/drivers ?"));
  }

  m_shaders[0] = 0;
  m_shaders[1] = 0;
  attach(other.m_shaders[0]);
  attach(other.m_shaders[1]);
}

GlslSet& GlslSet::operator=(const GlslSet& other)
{
  if (&other == this) return *this;

  unbind();

  detach(m_shaders[0]);
  detach(m_shaders[1]);
  attach(other.m_shaders[0]);
  attach(other.m_shaders[1]);

  m_linked = false;

  return *this;
}

GlslSet::~GlslSet()
{
  unbind(); // this is necessary
  SH_GL_CHECK_ERROR(glDeleteObjectARB(m_arb_program));
  m_arb_program = 0;
}

void GlslSet::attach(const SH::ShPointer<GlslCode>& code)
{
  SH_DEBUG_ASSERT(m_arb_program);

  if (!code) return;
  if (m_shaders[code->glsl_unit()] == code) return;

  // Unbind old shader
  unbind();
  if (m_shaders[code->glsl_unit()]) {
    SH_GL_CHECK_ERROR(glDetachObjectARB(m_arb_program, m_shaders[code->glsl_unit()]->glsl_shader()));
  }

  // Bind new shader
  SH_GL_CHECK_ERROR(glAttachObjectARB(m_arb_program, code->glsl_shader()));
  m_shaders[code->glsl_unit()] = code;
  code->bind_generic_attributes(m_arb_program);

  m_linked = false; // will need to relink
}

void GlslSet::detach(const SH::ShPointer<GlslCode>& code)
{
  if (!code) return;
  if (m_shaders[code->glsl_unit()] != code) return;

  unbind();

  SH_DEBUG_ASSERT(m_arb_program);
  SH_GL_CHECK_ERROR(glDetachObjectARB(m_arb_program, code->glsl_shader()));
  m_shaders[code->glsl_unit()] = 0;

  // Need to relink
  m_linked = false;
}

void GlslSet::replace(const SH::ShPointer<GlslCode>& code)
{
  SH_DEBUG_ASSERT(code);
  if (m_shaders[code->glsl_unit()] == code && !m_shaders[1 - code->glsl_unit()]) return;

  detach(m_shaders[0]);
  detach(m_shaders[1]);
  attach(code);
}

void GlslSet::link()
{
  SH_DEBUG_ASSERT(m_arb_program);

  SH_GL_CHECK_ERROR(glLinkProgramARB(m_arb_program));

  // Check linking
  GLint linked;
  glGetObjectParameterivARB(m_arb_program, GL_OBJECT_LINK_STATUS_ARB, &linked);
  if (linked != GL_TRUE) {
    cout << "Program link status: FAILED" << endl << endl;
    cout << "Program infolog:" << endl;
    print_infolog(m_arb_program);
    cout << "Program code:" << endl;
    print_shader_source(m_arb_program);
    cout << endl;
    return;
  }

  m_linked = true;
}

bool GlslSet::empty() const
{
  if (m_shaders[0]) return false;
  if (m_shaders[1]) return false;
  return true;
}

void GlslSet::bind()
{
  if (m_bound) {
    for (int i = 0; i < 2; i++) {
      if (!m_shaders[i]) continue;
      m_shaders[i]->update();
    }
    return;
  }

  if (!m_linked) link();

  if (current() && current() != this) current()->unbind();

  SH_GL_CHECK_ERROR(glUseProgramObjectARB(m_arb_program));

#ifdef SH_DEBUG_GLSL_BACKEND
  // This could be slow, it should not be enabled in release code
  glValidateProgramARB(m_arb_program);
  GLint validated;
  glGetObjectParameterivARB(m_arb_program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated);
  if (validated != GL_TRUE) {
    cout << "Program validate status: FAILED" << endl;
    cout << "Program infolog:" << endl;
    print_infolog(m_arb_program);
  }
#endif

  for (int i = 0; i < 2; i++) {
    if (!m_shaders[i]) continue;
    GlslCodePtr shader = m_shaders[i];
    shader->set_bound(m_arb_program);

    shader->upload_uniforms();
    shader->bind_textures();
  }

  m_current = this;
  m_bound = true;
}

void GlslSet::unbind()
{
  if (!m_bound) return;

  SH_GL_CHECK_ERROR(glUseProgramObjectARB(0));

  for (int i = 0; i < 2; i++) {
    if (!m_shaders[i]) continue;
    m_shaders[i]->set_bound(0);
  }
  m_current = 0;
  m_bound = false;
}

}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include "AccessController.h"

#include <tuple>

#include "LocalDomainAccessController.h"
#include "joynr/LocalCapabilitiesDirectory.h"
#include "joynr/JoynrMessage.h"
#include "joynr/types/DiscoveryEntry.h"
#include "joynr/Request.h"
#include "joynr/SubscriptionRequest.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/system/RoutingTypes/Address.h"
#include "joynr/serializer/Serializer.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;
using namespace types;

INIT_LOGGER(AccessController);

//--------- InternalConsumerPermissionCallbacks --------------------------------

class AccessController::LdacConsumerPermissionCallback
        : public LocalDomainAccessController::IGetConsumerPermissionCallback
{

public:
    LdacConsumerPermissionCallback(
            AccessController& owningAccessController,
            const JoynrMessage& message,
            const std::string& domain,
            const std::string& interfaceName,
            TrustLevel::Enum trustlevel,
            std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback);

    // Callbacks made from the LocalDomainAccessController
    void consumerPermission(Permission::Enum permission) override;
    void operationNeeded() override;

private:
    AccessController& owningAccessController;
    JoynrMessage message;
    std::string domain;
    std::string interfaceName;
    TrustLevel::Enum trustlevel;
    std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback;

    bool convertToBool(Permission::Enum permission);
};

AccessController::LdacConsumerPermissionCallback::LdacConsumerPermissionCallback(
        AccessController& parent,
        const JoynrMessage& message,
        const std::string& domain,
        const std::string& interfaceName,
        TrustLevel::Enum trustlevel,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
        : owningAccessController(parent),
          message(message),
          domain(domain),
          interfaceName(interfaceName),
          trustlevel(trustlevel),
          callback(callback)
{
}

void AccessController::LdacConsumerPermissionCallback::consumerPermission(
        Permission::Enum permission)
{
    bool hasPermission = convertToBool(permission);

    if (hasPermission == false) {
        JOYNR_LOG_ERROR(owningAccessController.logger,
                        "Message {} to domain {}, interface {} failed ACL check",
                        message.getHeaderMessageId(),
                        domain,
                        interfaceName);
    }
    callback->hasConsumerPermission(hasPermission);
}

void AccessController::LdacConsumerPermissionCallback::operationNeeded()
{
    std::string operation;
    const std::string messageType = message.getType();
    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_ONE_WAY) {
        try {
            OneWayRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getMethodName();
        } catch (const std::exception& e) {
            JOYNR_LOG_ERROR(logger, "could not deserialize OneWayRequest - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REQUEST) {
        try {
            Request request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getMethodName();
        } catch (const std::exception& e) {
            JOYNR_LOG_ERROR(logger, "could not deserialize Request - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST) {
        try {
            SubscriptionRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getSubscribeToName();

        } catch (const std::invalid_argument& e) {
            JOYNR_LOG_ERROR(
                    logger, "could not deserialize SubscriptionRequest - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST) {
        try {
            BroadcastSubscriptionRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getSubscribeToName();

        } catch (const std::invalid_argument& e) {
            JOYNR_LOG_ERROR(logger,
                            "could not deserialize BroadcastSubscriptionRequest - error {}",
                            e.what());
        }
    }

    if (operation.empty()) {
        JOYNR_LOG_ERROR(owningAccessController.logger, "Could not deserialize request");
        callback->hasConsumerPermission(false);
        return;
    }

    // Get the permission for given operation
    Permission::Enum permission =
            owningAccessController.localDomainAccessController.getConsumerPermission(
                    message.getHeaderCreatorUserId(), domain, interfaceName, operation, trustlevel);

    bool hasPermission = convertToBool(permission);

    if (hasPermission == false) {
        JOYNR_LOG_ERROR(owningAccessController.logger,
                        "Message {} to domain {}, interface/operation {}/{} failed ACL check",
                        message.getHeaderMessageId(),
                        domain,
                        interfaceName,
                        operation);
    }

    callback->hasConsumerPermission(hasPermission);
}

bool AccessController::LdacConsumerPermissionCallback::convertToBool(Permission::Enum permission)
{
    switch (permission) {
    case Permission::YES:
        return true;
    case Permission::ASK:
        assert(false && "Permission.ASK user dialog not yet implemented.");
        return false;
    case Permission::NO:
        return false;
    default:
        return false;
    }
}

//--------- AccessController ---------------------------------------------------

class AccessController::ProviderRegistrationObserver
        : public LocalCapabilitiesDirectory::IProviderRegistrationObserver
{
public:
    explicit ProviderRegistrationObserver(LocalDomainAccessController& localDomainAccessController)
            : localDomainAccessController(localDomainAccessController)
    {
    }
    void onProviderAdd(const DiscoveryEntry& discoveryEntry) override
    {
        std::ignore = discoveryEntry;
        // Ignored
    }

    void onProviderRemove(const DiscoveryEntry& discoveryEntry) override
    {
        localDomainAccessController.unregisterProvider(
                discoveryEntry.getDomain(), discoveryEntry.getInterfaceName());
    }

private:
    LocalDomainAccessController& localDomainAccessController;
};

AccessController::AccessController(LocalCapabilitiesDirectory& localCapabilitiesDirectory,
                                   LocalDomainAccessController& localDomainAccessController)
        : localCapabilitiesDirectory(localCapabilitiesDirectory),
          localDomainAccessController(localDomainAccessController),
          providerRegistrationObserver(
                  std::make_shared<ProviderRegistrationObserver>(localDomainAccessController)),
          whitelistParticipantIds()
{
    localCapabilitiesDirectory.addProviderRegistrationObserver(providerRegistrationObserver);
}

AccessController::~AccessController()
{
    localCapabilitiesDirectory.removeProviderRegistrationObserver(providerRegistrationObserver);
}

void AccessController::addParticipantToWhitelist(const std::string& participantId)
{
    whitelistParticipantIds.push_back(participantId);
}

bool AccessController::needsPermissionCheck(const JoynrMessage& message)
{
    if (util::vectorContains(whitelistParticipantIds, message.getHeaderTo())) {
        return false;
    }

    std::string messageType = message.getType();
    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REPLY ||
        messageType == JoynrMessage::VALUE_MESSAGE_TYPE_PUBLICATION) {
        // reply messages don't need permission check
        // they are filtered by request reply ID or subscritpion ID
        return false;
    }

    // If this point is reached, checking is required
    return true;
}

void AccessController::hasConsumerPermission(
        const JoynrMessage& message,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
{
    if (!needsPermissionCheck(message)) {
        callback->hasConsumerPermission(true);
        return;
    }

    // Get the domain and interface of the message destination
    std::string participantId = message.getHeaderTo();
    std::function<void(const types::DiscoveryEntry&)> lookupSuccessCallback =
            [this, message, callback, participantId](const types::DiscoveryEntry& discoveryEntry) {
        if (discoveryEntry.getParticipantId() != participantId) {
            JOYNR_LOG_ERROR(
                    logger, "Failed to get capabilities for participantId {}", participantId);
            callback->hasConsumerPermission(false);
            return;
        }

        std::string domain = discoveryEntry.getDomain();
        std::string interfaceName = discoveryEntry.getInterfaceName();

        // TODO: remove this shortcut used for system integration tests
        if (interfaceName == "tests/test") {
            callback->hasConsumerPermission(true);
            return;
        }

        // Create a callback object
        auto ldacCallback = std::make_shared<LdacConsumerPermissionCallback>(
                *this, message, domain, interfaceName, TrustLevel::HIGH, callback);

        // Try to determine permission without expensive message deserialization
        // For now TrustLevel::HIGH is assumed.
        std::string msgCreatorUid = message.getHeaderCreatorUserId();
        localDomainAccessController.getConsumerPermission(
                msgCreatorUid, domain, interfaceName, TrustLevel::HIGH, ldacCallback);
    };

    std::function<void(const joynr::exceptions::ProviderRuntimeException&)> lookupErrorCallback =
            [callback](const joynr::exceptions::ProviderRuntimeException& exception) {
        std::ignore = exception;
        callback->hasConsumerPermission(false);
    };
    localCapabilitiesDirectory.lookup(participantId, lookupSuccessCallback, lookupErrorCallback);
}

bool AccessController::hasProviderPermission(const std::string& userId,
                                             TrustLevel::Enum trustLevel,
                                             const std::string& domain,
                                             const std::string& interfaceName)
{
    std::ignore = userId;
    std::ignore = trustLevel;
    std::ignore = domain;
    std::ignore = interfaceName;

    assert(false && "Not yet implemented.");
    return true;
}

} // namespace joynr
<commit_msg>[C++] Do not check against false for booleans<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include "AccessController.h"

#include <tuple>

#include "LocalDomainAccessController.h"
#include "joynr/LocalCapabilitiesDirectory.h"
#include "joynr/JoynrMessage.h"
#include "joynr/types/DiscoveryEntry.h"
#include "joynr/Request.h"
#include "joynr/SubscriptionRequest.h"
#include "joynr/BroadcastSubscriptionRequest.h"
#include "joynr/system/RoutingTypes/Address.h"
#include "joynr/serializer/Serializer.h"

namespace joynr
{

using namespace infrastructure;
using namespace infrastructure::DacTypes;
using namespace types;

INIT_LOGGER(AccessController);

//--------- InternalConsumerPermissionCallbacks --------------------------------

class AccessController::LdacConsumerPermissionCallback
        : public LocalDomainAccessController::IGetConsumerPermissionCallback
{

public:
    LdacConsumerPermissionCallback(
            AccessController& owningAccessController,
            const JoynrMessage& message,
            const std::string& domain,
            const std::string& interfaceName,
            TrustLevel::Enum trustlevel,
            std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback);

    // Callbacks made from the LocalDomainAccessController
    void consumerPermission(Permission::Enum permission) override;
    void operationNeeded() override;

private:
    AccessController& owningAccessController;
    JoynrMessage message;
    std::string domain;
    std::string interfaceName;
    TrustLevel::Enum trustlevel;
    std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback;

    bool convertToBool(Permission::Enum permission);
};

AccessController::LdacConsumerPermissionCallback::LdacConsumerPermissionCallback(
        AccessController& parent,
        const JoynrMessage& message,
        const std::string& domain,
        const std::string& interfaceName,
        TrustLevel::Enum trustlevel,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
        : owningAccessController(parent),
          message(message),
          domain(domain),
          interfaceName(interfaceName),
          trustlevel(trustlevel),
          callback(callback)
{
}

void AccessController::LdacConsumerPermissionCallback::consumerPermission(
        Permission::Enum permission)
{
    bool hasPermission = convertToBool(permission);

    if (!hasPermission) {
        JOYNR_LOG_ERROR(owningAccessController.logger,
                        "Message {} to domain {}, interface {} failed ACL check",
                        message.getHeaderMessageId(),
                        domain,
                        interfaceName);
    }
    callback->hasConsumerPermission(hasPermission);
}

void AccessController::LdacConsumerPermissionCallback::operationNeeded()
{
    std::string operation;
    const std::string messageType = message.getType();
    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_ONE_WAY) {
        try {
            OneWayRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getMethodName();
        } catch (const std::exception& e) {
            JOYNR_LOG_ERROR(logger, "could not deserialize OneWayRequest - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REQUEST) {
        try {
            Request request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getMethodName();
        } catch (const std::exception& e) {
            JOYNR_LOG_ERROR(logger, "could not deserialize Request - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST) {
        try {
            SubscriptionRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getSubscribeToName();

        } catch (const std::invalid_argument& e) {
            JOYNR_LOG_ERROR(
                    logger, "could not deserialize SubscriptionRequest - error {}", e.what());
        }
    } else if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST) {
        try {
            BroadcastSubscriptionRequest request;
            joynr::serializer::deserializeFromJson(request, message.getPayload());
            operation = request.getSubscribeToName();

        } catch (const std::invalid_argument& e) {
            JOYNR_LOG_ERROR(logger,
                            "could not deserialize BroadcastSubscriptionRequest - error {}",
                            e.what());
        }
    }

    if (operation.empty()) {
        JOYNR_LOG_ERROR(owningAccessController.logger, "Could not deserialize request");
        callback->hasConsumerPermission(false);
        return;
    }

    // Get the permission for given operation
    Permission::Enum permission =
            owningAccessController.localDomainAccessController.getConsumerPermission(
                    message.getHeaderCreatorUserId(), domain, interfaceName, operation, trustlevel);

    bool hasPermission = convertToBool(permission);

    if (!hasPermission) {
        JOYNR_LOG_ERROR(owningAccessController.logger,
                        "Message {} to domain {}, interface/operation {}/{} failed ACL check",
                        message.getHeaderMessageId(),
                        domain,
                        interfaceName,
                        operation);
    }

    callback->hasConsumerPermission(hasPermission);
}

bool AccessController::LdacConsumerPermissionCallback::convertToBool(Permission::Enum permission)
{
    switch (permission) {
    case Permission::YES:
        return true;
    case Permission::ASK:
        assert(false && "Permission.ASK user dialog not yet implemented.");
        return false;
    case Permission::NO:
        return false;
    default:
        return false;
    }
}

//--------- AccessController ---------------------------------------------------

class AccessController::ProviderRegistrationObserver
        : public LocalCapabilitiesDirectory::IProviderRegistrationObserver
{
public:
    explicit ProviderRegistrationObserver(LocalDomainAccessController& localDomainAccessController)
            : localDomainAccessController(localDomainAccessController)
    {
    }
    void onProviderAdd(const DiscoveryEntry& discoveryEntry) override
    {
        std::ignore = discoveryEntry;
        // Ignored
    }

    void onProviderRemove(const DiscoveryEntry& discoveryEntry) override
    {
        localDomainAccessController.unregisterProvider(
                discoveryEntry.getDomain(), discoveryEntry.getInterfaceName());
    }

private:
    LocalDomainAccessController& localDomainAccessController;
};

AccessController::AccessController(LocalCapabilitiesDirectory& localCapabilitiesDirectory,
                                   LocalDomainAccessController& localDomainAccessController)
        : localCapabilitiesDirectory(localCapabilitiesDirectory),
          localDomainAccessController(localDomainAccessController),
          providerRegistrationObserver(
                  std::make_shared<ProviderRegistrationObserver>(localDomainAccessController)),
          whitelistParticipantIds()
{
    localCapabilitiesDirectory.addProviderRegistrationObserver(providerRegistrationObserver);
}

AccessController::~AccessController()
{
    localCapabilitiesDirectory.removeProviderRegistrationObserver(providerRegistrationObserver);
}

void AccessController::addParticipantToWhitelist(const std::string& participantId)
{
    whitelistParticipantIds.push_back(participantId);
}

bool AccessController::needsPermissionCheck(const JoynrMessage& message)
{
    if (util::vectorContains(whitelistParticipantIds, message.getHeaderTo())) {
        return false;
    }

    std::string messageType = message.getType();
    if (messageType == JoynrMessage::VALUE_MESSAGE_TYPE_REPLY ||
        messageType == JoynrMessage::VALUE_MESSAGE_TYPE_PUBLICATION) {
        // reply messages don't need permission check
        // they are filtered by request reply ID or subscritpion ID
        return false;
    }

    // If this point is reached, checking is required
    return true;
}

void AccessController::hasConsumerPermission(
        const JoynrMessage& message,
        std::shared_ptr<IAccessController::IHasConsumerPermissionCallback> callback)
{
    if (!needsPermissionCheck(message)) {
        callback->hasConsumerPermission(true);
        return;
    }

    // Get the domain and interface of the message destination
    std::string participantId = message.getHeaderTo();
    std::function<void(const types::DiscoveryEntry&)> lookupSuccessCallback =
            [this, message, callback, participantId](const types::DiscoveryEntry& discoveryEntry) {
        if (discoveryEntry.getParticipantId() != participantId) {
            JOYNR_LOG_ERROR(
                    logger, "Failed to get capabilities for participantId {}", participantId);
            callback->hasConsumerPermission(false);
            return;
        }

        std::string domain = discoveryEntry.getDomain();
        std::string interfaceName = discoveryEntry.getInterfaceName();

        // TODO: remove this shortcut used for system integration tests
        if (interfaceName == "tests/test") {
            callback->hasConsumerPermission(true);
            return;
        }

        // Create a callback object
        auto ldacCallback = std::make_shared<LdacConsumerPermissionCallback>(
                *this, message, domain, interfaceName, TrustLevel::HIGH, callback);

        // Try to determine permission without expensive message deserialization
        // For now TrustLevel::HIGH is assumed.
        std::string msgCreatorUid = message.getHeaderCreatorUserId();
        localDomainAccessController.getConsumerPermission(
                msgCreatorUid, domain, interfaceName, TrustLevel::HIGH, ldacCallback);
    };

    std::function<void(const joynr::exceptions::ProviderRuntimeException&)> lookupErrorCallback =
            [callback](const joynr::exceptions::ProviderRuntimeException& exception) {
        std::ignore = exception;
        callback->hasConsumerPermission(false);
    };
    localCapabilitiesDirectory.lookup(participantId, lookupSuccessCallback, lookupErrorCallback);
}

bool AccessController::hasProviderPermission(const std::string& userId,
                                             TrustLevel::Enum trustLevel,
                                             const std::string& domain,
                                             const std::string& interfaceName)
{
    std::ignore = userId;
    std::ignore = trustLevel;
    std::ignore = domain;
    std::ignore = interfaceName;

    assert(false && "Not yet implemented.");
    return true;
}

} // namespace joynr
<|endoftext|>


<commit_before>#ifndef _INCLUDED_DS_SUFFIX_ARRAY_HPP
#define _INCLUDED_DS_SUFFIX_ARRAY_HPP

#include <divsufsort.h>
#include <divsufsort64.h>

#include <sdsl/int_vector.hpp>

#include <tudocomp/io.hpp>
#include <tudocomp/util.hpp>
#include "forward.hpp"
namespace tdc {

template<class T>
class SuffixArray {

public:
    typedef sdsl::int_vector<> iv_t;

private:
    iv_t m_sa;

public:
    inline iv_t& data() {
        return m_sa;
    }

    inline const iv_t& data() const {
        return m_sa;
    }

    inline iv_t::value_type operator[](iv_t::size_type i) const {
        return m_sa[i];
    }

    inline iv_t::size_type size() const {
        return m_sa.size();
    }

    inline void construct(T& t);
};

}//ns
namespace tdc {

template<class T>
void SuffixArray<T>::construct(T& t) {
	const size_t len = t.size();

	//TODO:  t.text(); should do the job?
	uint8_t* copy = new uint8_t[len + 1];
	for(size_t i = 0; i < len; i++) {
		copy[i] = t[i];
	}
	copy[len] = 0;

	//TODO: with int32_t we can only create SA for texts less than 4GB
	// should be divsufsort64

	//Use divsufsort to construct
	int32_t *sa = new int32_t[len + 1];
	divsufsort(copy, sa, len + 1);

	delete[] copy;

	//Bit compress using SDSL
	size_t w = bits_for(len + 1);
	m_sa = iv_t(len + 1, 0, w);

	for(size_t i = 0; i < len + 1; i++) {
		m_sa[i]  = sa[i];
        DCHECK_LT(m_sa[i], len+1);
	}

	delete[] sa;
}

}//ns

#endif

<commit_msg>added bwt in SuffixArray.hpp<commit_after>#ifndef _INCLUDED_DS_SUFFIX_ARRAY_HPP
#define _INCLUDED_DS_SUFFIX_ARRAY_HPP

#include <divsufsort.h>
#include <divsufsort64.h>

#include <sdsl/int_vector.hpp>

#include <tudocomp/io.hpp>
#include <tudocomp/util.hpp>
#include "forward.hpp"
namespace tdc {

template<class T>
class SuffixArray {

public:
    typedef sdsl::int_vector<> iv_t;

private:
    iv_t m_sa;

public:
    inline iv_t& data() {
        return m_sa;
    }

    inline const iv_t& data() const {
        return m_sa;
    }

    inline iv_t::value_type operator[](iv_t::size_type i) const {
        return m_sa[i];
    }

    inline iv_t::size_type size() const {
        return m_sa.size();
    }

    inline void construct(T& t);
};

}//ns
namespace tdc {

template<class T>
void SuffixArray<T>::construct(T& t) {
	const size_t len = t.size();

	//TODO:  t.text(); should do the job?
	uint8_t* copy = new uint8_t[len + 1];
	for(size_t i = 0; i < len; i++) {
		copy[i] = t[i];
	}
	copy[len] = 0;

	//TODO: with int32_t we can only create SA for texts less than 4GB
	// should be divsufsort64

	//Use divsufsort to construct
	int32_t *sa = new int32_t[len + 1];
	divsufsort(copy, sa, len + 1);

	delete[] copy;

	//Bit compress using SDSL
	size_t w = bits_for(len + 1);
	m_sa = iv_t(len + 1, 0, w);

	for(size_t i = 0; i < len + 1; i++) {
		m_sa[i]  = sa[i];
        DCHECK_LT(m_sa[i], len+1);
	}

	delete[] sa;
}

/**
 * Computes the value BWT[i] of a text T given its suffix array SA
 * Runs in O(1) time since BWT[i] = SA[(T[i]-1) mod |SA|]
 */
template<typename text_t, typename sa_t>
inline typename text_t::value_type bwt(const text_t& text, const sa_t& sa, const size_t i) {
	return (sa[i] == 0) ? text[sa.size()-1] : text[sa[i]-1];
}

}//ns

#endif

<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TStopwatch.cxx,v 1.5 2002/06/13 13:42:55 rdm Exp $
// Author: Fons Rademakers   11/10/95

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStopwatch                                                           //
//                                                                      //
// Stopwatch class. This class returns the real and cpu time between    //
// the start and stop events.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStopwatch.h"
#include "TString.h"

#if defined(R__MAC)
#   include <time.h>
static clock_t gTicks = CLOCKS_PER_SEC;
#elif defined(R__UNIX)
#   include <sys/times.h>
#   include <unistd.h>
static clock_t gTicks = 0;
#elif defined(R__VMS)
#   include <time.h>
#   include <unistd.h>
static clock_t gTicks = 1000;
#elif defined(WIN32)
#   include "TError.h"
    const Double_t gTicks = 1.0e-7;
#   include "Windows4Root.h"
#endif

ClassImp(TStopwatch)

//______________________________________________________________________________
TStopwatch::TStopwatch()
{
   // Create a stopwatch and start it.

#ifdef R__UNIX
   if (!gTicks) gTicks = (clock_t)sysconf(_SC_CLK_TCK);
#endif
   fState         = kUndefined;
   fTotalCpuTime  = 0;
   fTotalRealTime = 0;
   fCounter       = 0;
   Start();
}

//______________________________________________________________________________
void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
   }
   if (fState != kRunning) {
#ifndef R__UNIX
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
#else
      struct tms cpt;
      fStartRealTime = (Double_t)times(&cpt) / gTicks;
      fStartCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   }
   fState = kRunning;
   fCounter++;
}

//______________________________________________________________________________
void TStopwatch::Stop()
{
   // Stop the stopwatch.

#ifndef R__UNIX
   fStopRealTime = GetRealTime();
   fStopCpuTime  = GetCPUTime();
#else
   struct tms cpt;
   fStopRealTime = (Double_t)times(&cpt) / gTicks;
   fStopCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   if (fState == kRunning) {
      fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
      fTotalRealTime += fStopRealTime - fStartRealTime;
   }
   fState = kStopped;
}

//______________________________________________________________________________
void TStopwatch::Continue()
{
   // Resume a stopped stopwatch. The stopwatch continues counting from the last
   // Start() onwards (this is like the laptimer function).

   if (fState == kUndefined)
      Error("Continue", "stopwatch not started");

   if (fState == kStopped) {
      fTotalCpuTime  -= fStopCpuTime  - fStartCpuTime;
      fTotalRealTime -= fStopRealTime - fStartRealTime;
   }

   fState = kRunning;
}

//______________________________________________________________________________
Double_t TStopwatch::RealTime()
{
   // Return the realtime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("RealTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalRealTime;
}

//______________________________________________________________________________
Double_t TStopwatch::CpuTime()
{
   // Return the cputime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("CpuTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalCpuTime;
}

//______________________________________________________________________________
Double_t TStopwatch::GetRealTime()
{
   // Private static method returning system realtime.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   Double_t trt = (Double_t)times(&cpt);
   return trt / (Double_t) gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)
   union {
      FILETIME ftFileTime;
      __int64  ftInt64;
   } ftRealTime; // time the process has spent in kernel mode
   SYSTEMTIME st;
   GetSystemTime(&st);
   SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
   return (Double_t)ftRealTime.ftInt64 * gTicks;
#endif
}

//______________________________________________________________________________
Double_t TStopwatch::GetCPUTime()
{
   // Private static method returning system CPU time.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   times(&cpt);
   return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)

   OSVERSIONINFO OsVersionInfo;

   //         Value                      Platform
   //----------------------------------------------------
   //  VER_PLATFORM_WIN32s          Win32s on Windows 3.1
   //  VER_PLATFORM_WIN32_WINDOWS   Win32 on Windows 95
   //  VER_PLATFORM_WIN32_NT        Windows NT
   //
   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
   GetVersionEx(&OsVersionInfo);
   if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      DWORD       ret;
      FILETIME    ftCreate,       // when the process was created
                  ftExit;         // when the process exited

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftKernel; // time the process has spent in kernel mode

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftUser;   // time the process has spent in user mode

      HANDLE hProcess = GetCurrentProcess();
      ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
                                       &ftKernel.ftFileTime,
                                       &ftUser.ftFileTime);
      if (ret != TRUE) {
         ret = GetLastError ();
         ::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
      }

      // Process times are returned in a 64-bit structure, as the number of
      // 100 nanosecond ticks since 1 January 1601.  User mode and kernel mode
      // times for this process are in separate 64-bit structures.
      // To convert to floating point seconds, we will:
      //
      // Convert sum of high 32-bit quantities to 64-bit int

      return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  } else
      return GetRealTime();
#endif
}

//______________________________________________________________________________
void TStopwatch::Print(Option_t *opt) const
{
   // Print the real and cpu time passed between the start and stop events.
   // and the number of times (slices) this TStopwatch was called
   // (if this number > 1). If opt="m" printout realtime in milli second
   // precision.

   Double_t  realt = const_cast<TStopwatch*>(this)->RealTime();
   Double_t  cput  = const_cast<TStopwatch*>(this)->CpuTime();

   Int_t  hours = Int_t(realt / 3600);
   realt -= hours * 3600;
   Int_t  min   = Int_t(realt / 60);
   realt -= min * 60;
   Int_t  sec   = Int_t(realt);

   realt = TMath::Max(realt, 0.);
   cput  = TMath::Max(cput, 0.);

   if (opt && *opt == 'm') {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f", hours, min, realt, cput);
      }
   } else {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%02d, CP time %.3f, %d slices", hours, min, sec, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%02d, CP time %.3f", hours, min, sec, cput);
      }
   }
}
<commit_msg>From Eddy Offermann; I have made gTicks Double_t because the current code does first the division and then cast it to Double_t . The easiest solution is making gTicks Double_t .<commit_after>// @(#)root/base:$Name:  $:$Id: TStopwatch.cxx,v 1.6 2002/10/07 10:41:38 rdm Exp $
// Author: Fons Rademakers   11/10/95

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStopwatch                                                           //
//                                                                      //
// Stopwatch class. This class returns the real and cpu time between    //
// the start and stop events.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStopwatch.h"
#include "TString.h"

#if defined(R__MAC)
#   include <time.h>
static Double_t gTicks = CLOCKS_PER_SEC;
#elif defined(R__UNIX)
#   include <sys/times.h>
#   include <unistd.h>
static Double_t gTicks = 0;
#elif defined(R__VMS)
#   include <time.h>
#   include <unistd.h>
static Double_t gTicks = 1000;
#elif defined(WIN32)
#   include "TError.h"
    const Double_t gTicks = 1.0e-7;
#   include "Windows4Root.h"
#endif

ClassImp(TStopwatch)

//______________________________________________________________________________
TStopwatch::TStopwatch()
{
   // Create a stopwatch and start it.

#ifdef R__UNIX
   if (!gTicks) gTicks = (Double_t)sysconf(_SC_CLK_TCK);
#endif
   fState         = kUndefined;
   fTotalCpuTime  = 0;
   fTotalRealTime = 0;
   fCounter       = 0;
   Start();
}

//______________________________________________________________________________
void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
   }
   if (fState != kRunning) {
#ifndef R__UNIX
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
#else
      struct tms cpt;
      fStartRealTime = (Double_t)times(&cpt) / gTicks;
      fStartCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   }
   fState = kRunning;
   fCounter++;
}

//______________________________________________________________________________
void TStopwatch::Stop()
{
   // Stop the stopwatch.

#ifndef R__UNIX
   fStopRealTime = GetRealTime();
   fStopCpuTime  = GetCPUTime();
#else
   struct tms cpt;
   fStopRealTime = (Double_t)times(&cpt) / gTicks;
   fStopCpuTime  = (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#endif
   if (fState == kRunning) {
      fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
      fTotalRealTime += fStopRealTime - fStartRealTime;
   }
   fState = kStopped;
}

//______________________________________________________________________________
void TStopwatch::Continue()
{
   // Resume a stopped stopwatch. The stopwatch continues counting from the last
   // Start() onwards (this is like the laptimer function).

   if (fState == kUndefined)
      Error("Continue", "stopwatch not started");

   if (fState == kStopped) {
      fTotalCpuTime  -= fStopCpuTime  - fStartCpuTime;
      fTotalRealTime -= fStopRealTime - fStartRealTime;
   }

   fState = kRunning;
}

//______________________________________________________________________________
Double_t TStopwatch::RealTime()
{
   // Return the realtime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("RealTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalRealTime;
}

//______________________________________________________________________________
Double_t TStopwatch::CpuTime()
{
   // Return the cputime passed between the start and stop events. If the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("CpuTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalCpuTime;
}

//______________________________________________________________________________
Double_t TStopwatch::GetRealTime()
{
   // Private static method returning system realtime.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   Double_t trt = (Double_t)times(&cpt);
   return trt / (Double_t) gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)
   union {
      FILETIME ftFileTime;
      __int64  ftInt64;
   } ftRealTime; // time the process has spent in kernel mode
   SYSTEMTIME st;
   GetSystemTime(&st);
   SystemTimeToFileTime(&st,&ftRealTime.ftFileTime);
   return (Double_t)ftRealTime.ftInt64 * gTicks;
#endif
}

//______________________________________________________________________________
Double_t TStopwatch::GetCPUTime()
{
   // Private static method returning system CPU time.

#if defined(R__MAC)
   return (Double_t)clock() / gTicks;
#elif defined(R__UNIX)
   struct tms cpt;
   times(&cpt);
   return (Double_t)(cpt.tms_utime+cpt.tms_stime) / gTicks;
#elif defined(R__VMS)
   return (Double_t)clock() / gTicks;
#elif defined(WIN32)

   OSVERSIONINFO OsVersionInfo;

   //         Value                      Platform
   //----------------------------------------------------
   //  VER_PLATFORM_WIN32s          Win32s on Windows 3.1
   //  VER_PLATFORM_WIN32_WINDOWS   Win32 on Windows 95
   //  VER_PLATFORM_WIN32_NT        Windows NT
   //
   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
   GetVersionEx(&OsVersionInfo);
   if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      DWORD       ret;
      FILETIME    ftCreate,       // when the process was created
                  ftExit;         // when the process exited

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftKernel; // time the process has spent in kernel mode

      union {
         FILETIME ftFileTime;
         __int64  ftInt64;
      } ftUser;   // time the process has spent in user mode

      HANDLE hProcess = GetCurrentProcess();
      ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
                                       &ftKernel.ftFileTime,
                                       &ftUser.ftFileTime);
      if (ret != TRUE) {
         ret = GetLastError ();
         ::Error ("GetCPUTime", " Error on GetProcessTimes 0x%lx", (int)ret);
      }

      // Process times are returned in a 64-bit structure, as the number of
      // 100 nanosecond ticks since 1 January 1601.  User mode and kernel mode
      // times for this process are in separate 64-bit structures.
      // To convert to floating point seconds, we will:
      //
      // Convert sum of high 32-bit quantities to 64-bit int

      return (Double_t) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
  } else
      return GetRealTime();
#endif
}

//______________________________________________________________________________
void TStopwatch::Print(Option_t *opt) const
{
   // Print the real and cpu time passed between the start and stop events.
   // and the number of times (slices) this TStopwatch was called
   // (if this number > 1). If opt="m" printout realtime in milli second
   // precision.

   Double_t  realt = const_cast<TStopwatch*>(this)->RealTime();
   Double_t  cput  = const_cast<TStopwatch*>(this)->CpuTime();

   Int_t  hours = Int_t(realt / 3600);
   realt -= hours * 3600;
   Int_t  min   = Int_t(realt / 60);
   realt -= min * 60;
   Int_t  sec   = Int_t(realt);

   realt = TMath::Max(realt, 0.);
   cput  = TMath::Max(cput, 0.);

   if (opt && *opt == 'm') {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f, %d slices", hours, min, realt, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%06.3f, CP time %.3f", hours, min, realt, cput);
      }
   } else {
      if (Counter() > 1) {
         Printf("Real time %d:%02d:%02d, CP time %.3f, %d slices", hours, min, sec, cput, Counter());
      } else {
         Printf("Real time %d:%02d:%02d, CP time %.3f", hours, min, sec, cput);
      }
   }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName(const SkString& name) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        SkScalar pad = fRadius*3/2 + SK_Scalar1;
        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);

        int loop_count;

        if (fRadius > SkIntToScalar(50)) {
          loop_count = 10;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup(r);

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect(r);
        }
    }

    virtual void makeBlurryRect(const SkRect&) = 0;
    virtual void preBenchSetup(const SkRect&) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName(name);
    }
protected:
    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
                             SkBlurMask::kHigh_Quality);
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName(name);
    }

protected:
    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
        r.roundOut(&fSrcMask.fBounds);
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());

        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
    }

    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
                                  SkBlurMask::kNormal_Style,
                                  SkBlurMask::kHigh_Quality);
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<commit_msg>speculative change to speedup blurrect bench for large radius, to see if the bots are timing out<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName(const SkString& name) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        SkScalar pad = fRadius*3/2 + SK_Scalar1;
        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);

        int loop_count;

        if (fRadius > SkIntToScalar(25)) {
          loop_count = 100;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup(r);

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect(r);
        }
    }

    virtual void makeBlurryRect(const SkRect&) = 0;
    virtual void preBenchSetup(const SkRect&) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName(name);
    }
protected:
    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
                             SkBlurMask::kHigh_Quality);
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName(name);
    }

protected:
    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
        r.roundOut(&fSrcMask.fBounds);
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());

        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
    }

    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
                                  SkBlurMask::kNormal_Style,
                                  SkBlurMask::kHigh_Quality);
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<|endoftext|>


<commit_before>#include "SimpleAudioEngine.h"

#include "AppDelegate.h"
#include "MenuScene.h"
#include "Path.h"

USING_NS_CC;

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    auto director = Director::getInstance();
    auto glView = director->getOpenGLView();

	if(!glView) {
		glView = GLView::createWithRect("Flappy Bird", Rect(0, 0, 360, 640));
		director->setOpenGLView(glView);
	}

    // turn on display FPS
    director->setDisplayStats(false);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

	glView->setDesignResolutionSize(288, 512, ResolutionPolicy::NO_BORDER);

	srand(time(NULL));

	preloadSFX();

    // create a scene. it's an autorelease object
    auto scene = MenuScene::createScene();

    // run
    director->runWithScene(scene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    Director::getInstance()->stopAnimation();

    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    Director::getInstance()->startAnimation();

    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

void AppDelegate::preloadSFX()
{
	auto audioEngine = CocosDenshion::SimpleAudioEngine::getInstance();

	audioEngine->preloadEffect(SFX_DIE);
	audioEngine->preloadEffect(SFX_HIT);
	audioEngine->preloadEffect(SFX_POINT);
	audioEngine->preloadEffect(SFX_SWOOSHING);
	audioEngine->preloadEffect(SFX_WING);

	audioEngine->setEffectsVolume(0.4f);
}

<commit_msg>translate tab to space<commit_after>#include "SimpleAudioEngine.h"

#include "AppDelegate.h"
#include "MenuScene.h"
#include "Path.h"

USING_NS_CC;

bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    auto director = Director::getInstance();
    auto glView = director->getOpenGLView();

    if(!glView) {
        glView = GLView::createWithRect("Flappy Bird", Rect(0, 0, 360, 640));
        director->setOpenGLView(glView);
    }

    // turn on display FPS
    director->setDisplayStats(false);

    // set FPS. the default value is 1.0/60 if you don't call this
    director->setAnimationInterval(1.0 / 60);

    glView->setDesignResolutionSize(288, 512, ResolutionPolicy::NO_BORDER);

    srand(time(NULL));

    preloadSFX();

    // create a scene. it's an autorelease object
    auto scene = MenuScene::createScene();

    // run
    director->runWithScene(scene);

    return true;
}

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
    Director::getInstance()->stopAnimation();

    // if you use SimpleAudioEngine, it must be pause
    // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
    Director::getInstance()->startAnimation();

    // if you use SimpleAudioEngine, it must resume here
    // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

void AppDelegate::preloadSFX()
{
    auto audioEngine = CocosDenshion::SimpleAudioEngine::getInstance();

    audioEngine->preloadEffect(SFX_DIE);
    audioEngine->preloadEffect(SFX_HIT);
    audioEngine->preloadEffect(SFX_POINT);
    audioEngine->preloadEffect(SFX_SWOOSHING);
    audioEngine->preloadEffect(SFX_WING);

    audioEngine->setEffectsVolume(0.4f);
}

<|endoftext|>


<commit_before>/// @file
/// @author uentity
/// @date 01.07.2019
/// @brief Implements manipulations with object formatters
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include <bs/serialize/object_formatter.h>
#include <bs/objbase.h>
#include <bs/kernel/misc.h>
#include <bs/uuid.h>

#include <map>
#include <set>
#include <mutex>

NAMESPACE_BEGIN(blue_sky)
NAMESPACE_BEGIN()

/*-----------------------------------------------------------------------------
 *  Formatters manip impl
 *-----------------------------------------------------------------------------*/
struct fmaster {
	// obj_type_id -> set of unique object_formatter instances sorted by name
	// [NOTE] type_id is stored as string view!
	using fmt_storage_t = std::map< std::string_view, std::set<object_formatter, std::less<>>, std::less<> >;
	fmt_storage_t fmt_storage;

	using registry_t = std::map<const objbase*, std::string_view>;
	registry_t registry;

	// sync access to storage above
	std::mutex fmt_guard;

	fmaster() {}
	fmaster(const fmaster& rhs) : fmt_storage(rhs.fmt_storage) {}
	fmaster(fmaster&& rhs) : fmt_storage(std::move(rhs.fmt_storage)) {}

	static auto self() -> fmaster& {
		static fmaster& self = []() -> fmaster& {
			// generate random key
			auto& kstorage = kernel::idx_key_storage(to_string(gen_uuid()));
			auto r = kstorage.insert_element(0, fmaster());
			if(!r.first) throw error("Failed to make impl of object formatters in kernel storage!");
			return *r.first;
		}();

		return self;
	}

	auto install_formatter(const type_descriptor& obj_type, object_formatter&& of) -> bool {
		auto solo = std::lock_guard{ fmt_guard };
		return fmt_storage[obj_type.name].insert(std::move(of)).second;
	}

	auto uninstall_formatter(std::string_view obj_type_id, std::string fmt_name) -> bool {
		// deny removing fallback binary formatter
		if(fmt_name == detail::bin_fmt_name) return false;

		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			auto& fmt_set = fmts->second;
			if(auto pfmt = fmt_set.find(fmt_name); pfmt != fmt_set.end()) {
				// erase format
				auto solo = std::lock_guard{ fmt_guard };
				fmt_set.erase(pfmt);
				return true;
			}
		}
		return false;
	}

	auto formatter_installed(std::string_view obj_type_id, std::string_view fmt_name) -> bool {
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end())
			return fmts->second.find(fmt_name) != fmts->second.end();
		return false;
	}

	auto list_installed_formatters(std::string_view obj_type_id) -> std::vector<std::string> {
		auto res = std::vector<std::string>{};
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			res.reserve(fmts->second.size());
			for(const auto& f : fmts->second)
				res.emplace_back(f.name);
		}
		return res;
	}

	auto get_formatter(std::string_view obj_type_id, std::string_view fmt_name) -> object_formatter* {
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			auto& fmt_set = fmts->second;
			if(auto pfmt = fmt_set.find(fmt_name); pfmt != fmt_set.end())
				return &const_cast<object_formatter&>(*pfmt);
		}
		return nullptr;
	}

	auto register_formatter(const objbase& obj, std::string_view fmt_name) -> bool {
		if(auto frm = get_formatter(obj.bs_resolve_type().name, fmt_name)) {
			auto solo = std::lock_guard{ fmt_guard };
			registry[&obj] = frm->name;
			return true;
		}
		return false;
	}

	auto deregister_formatter(const objbase& obj) -> bool {
		if(auto r = registry.find(&obj); r != registry.end()) {
			auto solo = std::lock_guard{ fmt_guard };
			registry.erase(r);
			return true;
		}
		return false;
	}

	auto get_obj_formatter(const objbase* obj) -> object_formatter* {
		if(auto r = registry.find(obj); r != registry.end())
			return get_formatter(obj->bs_resolve_type().name, r->second);
		return nullptr;
	}
};

NAMESPACE_END()

/*-----------------------------------------------------------------------------
 *  Formatters manip public API
 *-----------------------------------------------------------------------------*/
#define FM fmaster::self()

auto install_formatter(const type_descriptor& obj_type, object_formatter of) -> bool {
	return FM.install_formatter(obj_type, std::move(of));
}

auto uninstall_formatter(std::string_view obj_type_id, std::string fmt_name) -> bool {
	return FM.uninstall_formatter(obj_type_id, std::move(fmt_name));
}

auto formatter_installed(std::string_view obj_type_id, std::string_view fmt_name) -> bool {
	return FM.formatter_installed(obj_type_id, fmt_name);
}

auto list_installed_formatters(std::string_view obj_type_id) -> std::vector<std::string> {
	return FM.list_installed_formatters(obj_type_id);
}

auto get_formatter(std::string_view obj_type_id, std::string_view fmt_name) -> object_formatter* {
	return FM.get_formatter(obj_type_id, fmt_name);
}

auto get_obj_formatter(const objbase* obj) -> object_formatter* {
	return FM.get_obj_formatter(obj);
}

/*-----------------------------------------------------------------------------
 *  object_formatter
 *-----------------------------------------------------------------------------*/
object_formatter::object_formatter(
	std::string fmt_name, object_saver_fn saver, object_loader_fn loader, bool stores_node_
) : base_t{std::move(saver), std::move(loader)}, name(std::move(fmt_name)), stores_node(stores_node_)
{}

// compare formatters by name
auto operator<(const object_formatter& lhs, const object_formatter& rhs) {
	return lhs.name < rhs.name;
}
// ... and with arbitrary string key
auto operator<(const object_formatter& lhs, std::string_view rhs) {
	return lhs.name < rhs;
}
auto operator<(std::string_view lhs, const object_formatter& rhs) {
	return lhs < rhs.name;
}

auto object_formatter::save(const objbase& obj, std::string obj_fname) const -> error {
	FM.register_formatter(obj, name);
	auto res = error::eval_safe([&]{ first(obj, std::move(obj_fname), name); });
	FM.deregister_formatter(obj);
	return res;
}

auto object_formatter::load(objbase& obj, std::string obj_fname) const -> error {
	FM.register_formatter(obj, name);
	auto res = error::eval_safe([&]{ second(obj, std::move(obj_fname), name); });
	FM.deregister_formatter(obj);
	return res;
}

NAMESPACE_END(blue_sky)
<commit_msg>serial: safer work with formatters registries<commit_after>/// @file
/// @author uentity
/// @date 01.07.2019
/// @brief Implements manipulations with object formatters
/// @copyright
/// This Source Code Form is subject to the terms of the Mozilla Public License,
/// v. 2.0. If a copy of the MPL was not distributed with this file,
/// You can obtain one at https://mozilla.org/MPL/2.0/

#include <bs/serialize/object_formatter.h>
#include <bs/objbase.h>
#include <bs/kernel/misc.h>
#include <bs/uuid.h>

#include <map>
#include <set>
#include <mutex>

NAMESPACE_BEGIN(blue_sky)
NAMESPACE_BEGIN()

/*-----------------------------------------------------------------------------
 *  Formatters manip impl
 *-----------------------------------------------------------------------------*/
struct fmaster {
	// obj_type_id -> set of unique object_formatter instances sorted by name
	// [NOTE] type_id is stored as string view!
	using fmt_storage_t = std::map< std::string_view, std::set<object_formatter, std::less<>>, std::less<> >;
	fmt_storage_t fmt_storage;

	using registry_t = std::map<const objbase*, std::string_view>;
	registry_t registry;

	// sync access to data above
	std::mutex fmt_guard, reg_guard;

	fmaster() {}
	fmaster(const fmaster& rhs) : fmt_storage(rhs.fmt_storage) {}
	fmaster(fmaster&& rhs) : fmt_storage(std::move(rhs.fmt_storage)) {}

	static auto self() -> fmaster& {
		static fmaster& self = []() -> fmaster& {
			// generate random key
			auto& kstorage = kernel::idx_key_storage(to_string(gen_uuid()));
			auto r = kstorage.insert_element(0, fmaster());
			if(!r.first) throw error("Failed to make impl of object formatters in kernel storage!");
			return *r.first;
		}();

		return self;
	}

	auto install_formatter(const type_descriptor& obj_type, object_formatter&& of) -> bool {
		auto solo = std::lock_guard{ fmt_guard };
		return fmt_storage[obj_type.name].insert(std::move(of)).second;
	}

	auto uninstall_formatter(std::string_view obj_type_id, std::string fmt_name) -> bool {
		// deny removing fallback binary formatter
		if(fmt_name == detail::bin_fmt_name) return false;

		auto solo = std::lock_guard{ fmt_guard };
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			auto& fmt_set = fmts->second;
			if(auto pfmt = fmt_set.find(fmt_name); pfmt != fmt_set.end()) {
				// erase format
				fmt_set.erase(pfmt);
				return true;
			}
		}
		return false;
	}

	auto formatter_installed(std::string_view obj_type_id, std::string_view fmt_name) -> bool {
		auto solo = std::lock_guard{ fmt_guard };
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end())
			return fmts->second.find(fmt_name) != fmts->second.end();
		return false;
	}

	auto list_installed_formatters(std::string_view obj_type_id) -> std::vector<std::string> {
		auto solo = std::lock_guard{ fmt_guard };
		auto res = std::vector<std::string>{};
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			res.reserve(fmts->second.size());
			for(const auto& f : fmts->second)
				res.emplace_back(f.name);
		}
		return res;
	}

	auto get_formatter(std::string_view obj_type_id, std::string_view fmt_name) -> object_formatter* {
		auto solo = std::lock_guard{ fmt_guard };
		if(auto fmts = fmt_storage.find(obj_type_id); fmts != fmt_storage.end()) {
			auto& fmt_set = fmts->second;
			if(auto pfmt = fmt_set.find(fmt_name); pfmt != fmt_set.end())
				return &const_cast<object_formatter&>(*pfmt);
		}
		return nullptr;
	}

	auto register_formatter(const objbase& obj, std::string_view fmt_name) -> bool {
		if(auto frm = get_formatter(obj.bs_resolve_type().name, fmt_name)) {
			auto solo = std::lock_guard{ reg_guard };
			registry[&obj] = frm->name;
			return true;
		}
		return false;
	}

	auto deregister_formatter(const objbase& obj) -> bool {
		auto solo = std::lock_guard{ reg_guard };
		if(auto r = registry.find(&obj); r != registry.end()) {
			registry.erase(r);
			return true;
		}
		return false;
	}

	auto get_obj_formatter(const objbase* obj) -> object_formatter* {
		auto solo = std::lock_guard{ reg_guard };
		if(auto r = registry.find(obj); r != registry.end())
			return get_formatter(obj->bs_resolve_type().name, r->second);
		return nullptr;
	}
};

NAMESPACE_END()

/*-----------------------------------------------------------------------------
 *  Formatters manip public API
 *-----------------------------------------------------------------------------*/
#define FM fmaster::self()

auto install_formatter(const type_descriptor& obj_type, object_formatter of) -> bool {
	return FM.install_formatter(obj_type, std::move(of));
}

auto uninstall_formatter(std::string_view obj_type_id, std::string fmt_name) -> bool {
	return FM.uninstall_formatter(obj_type_id, std::move(fmt_name));
}

auto formatter_installed(std::string_view obj_type_id, std::string_view fmt_name) -> bool {
	return FM.formatter_installed(obj_type_id, fmt_name);
}

auto list_installed_formatters(std::string_view obj_type_id) -> std::vector<std::string> {
	return FM.list_installed_formatters(obj_type_id);
}

auto get_formatter(std::string_view obj_type_id, std::string_view fmt_name) -> object_formatter* {
	return FM.get_formatter(obj_type_id, fmt_name);
}

auto get_obj_formatter(const objbase* obj) -> object_formatter* {
	return FM.get_obj_formatter(obj);
}

/*-----------------------------------------------------------------------------
 *  object_formatter
 *-----------------------------------------------------------------------------*/
object_formatter::object_formatter(
	std::string fmt_name, object_saver_fn saver, object_loader_fn loader, bool stores_node_
) : base_t{std::move(saver), std::move(loader)}, name(std::move(fmt_name)), stores_node(stores_node_)
{}

// compare formatters by name
auto operator<(const object_formatter& lhs, const object_formatter& rhs) {
	return lhs.name < rhs.name;
}
// ... and with arbitrary string key
auto operator<(const object_formatter& lhs, std::string_view rhs) {
	return lhs.name < rhs;
}
auto operator<(std::string_view lhs, const object_formatter& rhs) {
	return lhs < rhs.name;
}

auto object_formatter::save(const objbase& obj, std::string obj_fname) const -> error {
	FM.register_formatter(obj, name);
	auto res = error::eval_safe([&]{ first(obj, std::move(obj_fname), name); });
	FM.deregister_formatter(obj);
	return res;
}

auto object_formatter::load(objbase& obj, std::string obj_fname) const -> error {
	FM.register_formatter(obj, name);
	auto res = error::eval_safe([&]{ second(obj, std::move(obj_fname), name); });
	FM.deregister_formatter(obj);
	return res;
}

NAMESPACE_END(blue_sky)
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <dcopref.h>
#include <kdebug.h>
#include <klocale.h>

#include "summarywidget.h"

SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
  : QTextBrowser( parent, name ),
    DCOPObject( "WeatherSummaryWidget" )
{
  if ( !connectDCOPSignal( 0, 0, "fileUpdate(QString)", "refresh(QString)", false ) )
    kdDebug() << "Could not attach signal..." << endl;
  else
    kdDebug() << "attached dcop signals..." << endl;

  DCOPRef dcopCall( "KWeatherService", "WeatherService" );
  DCOPReply reply = dcopCall.call( "listStations()", true );
  if ( reply.isValid() ) {
    mStations = reply;

    connect( &mTimer, SIGNAL( timeout() ), this, SLOT( timeout() ) );
    mTimer.start( 0 );
  } else {
    setText( i18n( "Can't find kweather service." ) );
  }
}

void SummaryWidget::updateView()
{
  clear();

  if ( mStations.count() == 0 ) {
    setText( i18n( "No weather stations defined." ) );
    return;
  }

  WeatherData data = mWeatherMap[ mStations[ 0 ] ];

  QString cover;
  for ( uint i = 0; i < data.cover().count(); ++i )
    cover += QString( "
%1
" ).arg( data.cover()[ i ] );

  QString line1 = QString( "
	%1
" )
                         .arg( "
" + cover + "
" );
  QString line2 = QString( "
%1:	%2	%3:	%4
" )
                         .arg( i18n( "Temperature" ) )
                         .arg( data.temperature() )
                         .arg( i18n( "Dew Point" ) )
                         .arg( data.dewPoint() );

  QString line3 = QString( "
%1:	%2	%3:	%4
" )
                         .arg( i18n( "Air Pressure" ) )
                         .arg( data.pressure() )
                         .arg( i18n( "Rel. Humidity" ) )
                         .arg( data.relativeHumidity() );

  QString line4 = QString( "
%1:	%2
" )
                         .arg( i18n( "Wind Speed" ) )
                         .arg( data.windSpeed() );

  QMimeSourceFactory::defaultFactory()->setPixmap( "weather_icon", data.icon() );

  QString text = QString( "
%1

%2
" )
                        .arg( i18n( "Weather Report" ) )
                        .arg( line1 + line2 + line3 + line4 );
  setText( text );
}

void SummaryWidget::timeout()
{
  mTimer.stop();

  DCOPRef dcopCall( "KWeatherService", "WeatherService" );
  dcopCall.send( "updateAll()" );

  mTimer.start( 15 * 60000 );
}

void SummaryWidget::refresh( QString station )
{
  DCOPRef dcopCall( "KWeatherService", "WeatherService" );

  mWeatherMap[ station ].setIcon( dcopCall.call( "currentIcon(QString)", station, true ) );
  mWeatherMap[ station ].setCover( dcopCall.call( "cover(QString)", station, true ) );
  mWeatherMap[ station ].setTemperature( dcopCall.call( "temperature(QString)", station, true ) );
  mWeatherMap[ station ].setPressure( dcopCall.call( "pressure(QString)", station, true ) );
  mWeatherMap[ station ].setWindSpeed( dcopCall.call( "wind(QString)", station, true ) );
  mWeatherMap[ station ].setDewPoint( dcopCall.call( "dewPoint(QString)", station, true ) );
  mWeatherMap[ station ].setRelativeHumidity( dcopCall.call( "relativeHumidity(QString)", station, true ) );

  updateView();
}

#include "summarywidget.moc"
<commit_msg>- gui update - starts the kweatherservice now, if not already running<commit_after>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <dcopclient.h>
#include <dcopref.h>
#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>

#include "summarywidget.h"

SummaryWidget::SummaryWidget( QWidget *parent, const char *name )
  : QTextBrowser( parent, name ),
    DCOPObject( "WeatherSummaryWidget" )
{
  if ( !connectDCOPSignal( 0, 0, "fileUpdate(QString)", "refresh(QString)", false ) )
    kdDebug() << "Could not attach signal..." << endl;
  else
    kdDebug() << "attached dcop signals..." << endl;

  QString error;
  QCString appID;

  bool serviceAvailable = true;
  if ( !kapp->dcopClient()->isApplicationRegistered( "KWeatherService" ) ) {
    if ( !KApplication::startServiceByDesktopName( "kweatherservice", QStringList(), &error, &appID ) ) {
      setText( error );
      serviceAvailable = false;
    }
  }

  if ( serviceAvailable ) {
    DCOPRef dcopCall( "KWeatherService", "WeatherService" );
    DCOPReply reply = dcopCall.call( "listStations()", true );
    if ( reply.isValid() ) {
      mStations = reply;

      connect( &mTimer, SIGNAL( timeout() ), this, SLOT( timeout() ) );
      mTimer.start( 0 );
    } else {
      setText( "ERROR: dcop reply not valid" );
    }
  }
}

void SummaryWidget::updateView()
{
  clear();

  if ( mStations.count() == 0 ) {
    setText( i18n( "No weather stations defined." ) );
    return;
  }

  WeatherData data = mWeatherMap[ mStations[ 0 ] ];

  QString cover;
  for ( uint i = 0; i < data.cover().count(); ++i )
    cover += QString( "
%1
" ).arg( data.cover()[ i ] );

  QString line1 = QString( "
	%1
" )
                         .arg( "
" + cover + "
" );
  QString line2 = QString( "
%1:	%2	%3:	%4
" )
                         .arg( i18n( "Temperature" ) )
                         .arg( data.temperature() )
                         .arg( i18n( "Dew Point" ) )
                         .arg( data.dewPoint() );

  QString line3 = QString( "
%1:	%2	%3:	%4
" )
                         .arg( i18n( "Air Pressure" ) )
                         .arg( data.pressure() )
                         .arg( i18n( "Rel. Humidity" ) )
                         .arg( data.relativeHumidity() );

  QString line4 = QString( "
%1:	%2
" )
                         .arg( i18n( "Wind Speed" ) )
                         .arg( data.windSpeed() );

  QMimeSourceFactory::defaultFactory()->setPixmap( "weather_icon", data.icon() );

  QString text = QString( "
%1

%2
" )
                        .arg( i18n( "Weather Report" ) )
                        .arg( line1 + line2 + line3 + line4 );
  setText( text );
}

void SummaryWidget::timeout()
{
  mTimer.stop();

  DCOPRef dcopCall( "KWeatherService", "WeatherService" );
  dcopCall.send( "updateAll()" );

  mTimer.start( 15 * 60000 );
}

void SummaryWidget::refresh( QString station )
{
  DCOPRef dcopCall( "KWeatherService", "WeatherService" );

  mWeatherMap[ station ].setIcon( dcopCall.call( "currentIcon(QString)", station, true ) );
  mWeatherMap[ station ].setCover( dcopCall.call( "cover(QString)", station, true ) );
  mWeatherMap[ station ].setTemperature( dcopCall.call( "temperature(QString)", station, true ) );
  mWeatherMap[ station ].setPressure( dcopCall.call( "pressure(QString)", station, true ) );
  mWeatherMap[ station ].setWindSpeed( dcopCall.call( "wind(QString)", station, true ) );
  mWeatherMap[ station ].setDewPoint( dcopCall.call( "dewPoint(QString)", station, true ) );
  mWeatherMap[ station ].setRelativeHumidity( dcopCall.call( "relativeHumidity(QString)", station, true ) );

  updateView();
}

#include "summarywidget.moc"
<|endoftext|>