<commit_before>#include "apiserver/ApiServerComponent.h"

void Susi::Api::ApiServerComponent::onConnect( std::string & id ) {
    Susi::Logger::info( "got new connection!" );
    sessionManager->updateSession( id );
}

void Susi::Api::ApiServerComponent::onClose( std::string & id ) {
    Susi::Logger::info( "lost connection..." );
    sessionManager->killSession( id );
    senders.erase( id );
    eventsToAck.erase( id );

    auto & subs = consumerSubscriptions[id];
    for( auto & kv : subs ) {
        eventManager->unsubscribe( kv.second );
    }
    consumerSubscriptions.erase( id );
    auto & subs2 = processorSubscriptions[id];
    for( auto & kv : subs2 ) {
        eventManager->unsubscribe( kv.second );
    }
    processorSubscriptions.erase( id );
}

void Susi::Api::ApiServerComponent::onMessage( std::string & id, Susi::Util::Any & packet ) {
    try {
        Susi::Logger::debug("onMessage: "+packet.toJSONString());
        auto type = packet["type"];
        if( type.isString() ) {
            if( type=="registerConsumer" ) {
                handleRegisterConsumer( id,packet );
            }
            else if( type=="registerProcessor" ) {
                handleRegisterProcessor( id,packet );
            }
            else if( type=="unregisterConsumer" ) {
                handleUnregisterConsumer( id,packet );
            }
            else if( type=="unregisterProcessor" ) {
                handleUnregisterProcessor( id,packet );
            }
            else if( type=="publish" ) {
                handlePublish( id,packet );
            }
            else if( type=="ack" ) {
                handleAck( id,packet );
            }
            else {
                sendFail( id,"type not known" );
            }
        }
        else {
            sendFail( id,"type is not a string" );
        }
    }
    catch( const std::exception & e ) {
        std::string msg = "exception while processing: ";
        msg += e.what();
        sendFail( id,msg );
    }
}

void Susi::Api::ApiServerComponent::handleRegisterConsumer( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        char authlevel = 3;
        auto sessionAuthlevel = sessionManager->getSessionAttribute( id,"authlevel" );
        if( sessionAuthlevel.isInteger() ) {
            authlevel = static_cast<char>( sessionAuthlevel );
        }
        std::string topic = data["topic"];
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        std::string subName = "";
        if(data["name"].isString()){
            subName = static_cast<std::string>(data["name"]);
        }
        auto & subs = consumerSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) ) != subs.end() ) {
            sendFail( id,"you are allready subscribed to "+topic );
            return;
        }
        Susi::Events::Consumer callback = [this,id]( Susi::Events::SharedEventPtr event ) {
            Susi::Util::Any::Array headers;
            for( auto & kv : event->headers ) {
                headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
            }
            Susi::Util::Any packet;
            packet["type"] = "consumerEvent";
            packet["data"] = event->toAny();
            std::cout<<"got consumer event, try to send it "+packet.toJSONString()<<std::endl;
            std::string _id = id;
            send( _id,packet );
        };
        long subid = eventManager->subscribe( topic,callback,authlevel,subName );
        subs[topic+std::to_string((int)authlevel)] = subid;
        sendOk( id );
    }
    else {
        sendFail( id,"data is not a object" );
    }
}

void Susi::Api::ApiServerComponent::handleRegisterProcessor( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        char authlevel = 3;
        auto sessionAuthlevel = sessionManager->getSessionAttribute( id,"authlevel" );
        if( sessionAuthlevel.isInteger() ) {
            authlevel = static_cast<char>( sessionAuthlevel );
        }
        std::string topic = data["topic"];
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        std::string subName = "";
        if(data["name"].isString()){
            subName = static_cast<std::string>(data["name"]);
        }
        auto & subs = processorSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) ) != subs.end() ) {
            sendFail( id,"you are allready subscribed to "+topic );
            return;
        }
        long subid = eventManager->subscribe( topic,Susi::Events::Processor{[this,id]( Susi::Events::EventPtr event ) {
            Susi::Util::Any::Array headers;
            for( auto & kv : event->headers ) {
                headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
            }
            Susi::Util::Any packet;
            packet["type"] = "processorEvent";
            packet["data"] = event->toAny();
            std::string _id = id;
            eventsToAck[_id][event->id] = std::move( event );
            send( _id,packet );
        }},authlevel,subName );
        subs[topic+std::to_string((int)authlevel)] = subid;
        sendOk( id );
    }
    else {
        sendFail( id,"data is not a object" );
    }
}
void Susi::Api::ApiServerComponent::handleUnregisterConsumer( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        std::string topic = data["topic"];
        char authlevel = 3;
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        auto & subs = consumerSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) )!=subs.end() ) {
            long subid = subs[topic+std::to_string((int)authlevel)];
            eventManager->unsubscribe( subid );
            sendOk( id );
        }
        else {
            sendFail( id,"you are not registered for "+topic );
        }
    }
    else {
        sendFail( id,"data is not a object" );
    }
}

void Susi::Api::ApiServerComponent::handleUnregisterProcessor( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        std::string topic = data["topic"];
        char authlevel = 3;
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        auto & subs = processorSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) )!=subs.end() ) {
            long subid = subs[topic+std::to_string((int)authlevel)];
            eventManager->unsubscribe( subid );
            sendOk( id );
        }
        else {
            sendFail( id,"you are not registered for "+topic );
        }
    }
    else {
        sendFail( id,"data is not a object" );
    }
}
void Susi::Api::ApiServerComponent::handlePublish( std::string & id, Susi::Util::Any & packet ) {
    auto & eventData = packet["data"];
    if( !eventData.isObject() || !eventData["topic"].isString() ) {
        sendFail( id,"publish handler: data is not an object or topic is not set correctly" );
        return;
    }
    char authlevel = 3;
    auto sessionAuthlevel = sessionManager->getSessionAttribute( id, "authlevel" );
    if( sessionAuthlevel.isInteger() ) {
        authlevel = static_cast<char>( sessionAuthlevel );
    }
    else {
        Susi::Logger::debug( "sessionAuthlevelValue: "+sessionAuthlevel.toJSONString() );
    }
    auto event = eventManager->createEvent( eventData["topic"] );
    Susi::Events::Event rawEvent {eventData};
    rawEvent.sessionID = id;
    if( rawEvent.id == "" ) {
        rawEvent.id = std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
    }
    *event = rawEvent;
    if( event->authlevel < authlevel ) {
        event->authlevel = authlevel;
    }
    eventManager->publish( std::move( event ),[this,id]( Susi::Events::SharedEventPtr event ) {
        Susi::Util::Any::Array headers;
        for( auto & kv : event->headers ) {
            headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
        }
        Susi::Util::Any packet;
        packet["type"] = "ack";
        packet["data"] = event->toAny();
        std::string _id = id;
        send( _id,packet );
    } );

    sendOk( id );
}

void Susi::Api::ApiServerComponent::handleAck( std::string & id, Susi::Util::Any & packet ) {
    auto & eventData = packet["data"];
    if( !eventData.isObject() || !eventData["topic"].isString() ) {
        sendFail( id,"ack handler: data is not an object or topic is not set correctly" );
        return;
    }
    std::string eventID = static_cast<std::string>(eventData["id"]);
    if(!(eventsToAck.count(id)>0) || !(eventsToAck[id].count(eventID)>0)){
        sendFail( id , "unexpected ack" );
        return;
    }
    auto event = std::move( eventsToAck[id][eventID] );
    eventsToAck[id].erase( eventID );
    event->headers.clear();
    event->id = eventID;
    if( eventData["headers"].isArray() ) {
        Susi::Util::Any::Array arr = eventData["headers"];
        for( Susi::Util::Any::Object & val : arr ) {
            for( auto & kv : val ) {
                event->headers.push_back( std::make_pair( kv.first,( std::string )kv.second ) );
            }
        }
    }
    if( !eventData["payload"].isNull() ) {
        event->payload = eventData["payload"];
    }
    eventManager->ack( std::move( event ) );
    sendOk( id );
}

void Susi::Api::ApiServerComponent::sendOk( std::string & id ) {
    Susi::Util::Any response;
    response["type"] = "status";
    response["error"] = false;
    send( id,response );
}

void Susi::Api::ApiServerComponent::sendFail( std::string & id,std::string error ) {
    Susi::Util::Any response;
    response["type"] = "status";
    response["error"] = true;
    response["data"] = error;
    send( id,response );
}<commit_msg>[logging];<commit_after>#include "apiserver/ApiServerComponent.h"

void Susi::Api::ApiServerComponent::onConnect( std::string & id ) {
    Susi::Logger::info( "got new connection!" );
    sessionManager->updateSession( id );
}

void Susi::Api::ApiServerComponent::onClose( std::string & id ) {
    Susi::Logger::info( "lost connection..." );
    sessionManager->killSession( id );
    senders.erase( id );
    eventsToAck.erase( id );

    auto & subs = consumerSubscriptions[id];
    for( auto & kv : subs ) {
        eventManager->unsubscribe( kv.second );
    }
    consumerSubscriptions.erase( id );
    auto & subs2 = processorSubscriptions[id];
    for( auto & kv : subs2 ) {
        eventManager->unsubscribe( kv.second );
    }
    processorSubscriptions.erase( id );
}

void Susi::Api::ApiServerComponent::onMessage( std::string & id, Susi::Util::Any & packet ) {
    try {
        Susi::Logger::debug("onMessage: "+packet.toJSONString());
        auto type = packet["type"];
        if( type.isString() ) {
            if( type=="registerConsumer" ) {
                handleRegisterConsumer( id,packet );
            }
            else if( type=="registerProcessor" ) {
                handleRegisterProcessor( id,packet );
            }
            else if( type=="unregisterConsumer" ) {
                handleUnregisterConsumer( id,packet );
            }
            else if( type=="unregisterProcessor" ) {
                handleUnregisterProcessor( id,packet );
            }
            else if( type=="publish" ) {
                handlePublish( id,packet );
            }
            else if( type=="ack" ) {
                handleAck( id,packet );
            }
            else {
                sendFail( id,"type not known" );
            }
        }
        else {
            sendFail( id,"type is not a string" );
        }
    }
    catch( const std::exception & e ) {
        std::string msg = "exception while processing: ";
        msg += e.what();
        sendFail( id,msg );
    }
}

void Susi::Api::ApiServerComponent::handleRegisterConsumer( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        char authlevel = 3;
        auto sessionAuthlevel = sessionManager->getSessionAttribute( id,"authlevel" );
        if( sessionAuthlevel.isInteger() ) {
            authlevel = static_cast<char>( sessionAuthlevel );
        }
        std::string topic = data["topic"];
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        std::string subName = "";
        if(data["name"].isString()){
            subName = static_cast<std::string>(data["name"]);
        }
        auto & subs = consumerSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) ) != subs.end() ) {
            sendFail( id,"you are allready subscribed to "+topic );
            return;
        }
        Susi::Events::Consumer callback = [this,id]( Susi::Events::SharedEventPtr event ) {
            Susi::Util::Any::Array headers;
            for( auto & kv : event->headers ) {
                headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
            }
            Susi::Util::Any packet;
            packet["type"] = "consumerEvent";
            packet["data"] = event->toAny();
            Susi::Logger::debug("got consumer event, try to send it "+packet.toJSONString());
            std::string _id = id;
            send( _id,packet );
        };
        long subid = eventManager->subscribe( topic,callback,authlevel,subName );
        subs[topic+std::to_string((int)authlevel)] = subid;
        sendOk( id );
    }
    else {
        sendFail( id,"data is not a object" );
    }
}

void Susi::Api::ApiServerComponent::handleRegisterProcessor( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        char authlevel = 3;
        auto sessionAuthlevel = sessionManager->getSessionAttribute( id,"authlevel" );
        if( sessionAuthlevel.isInteger() ) {
            authlevel = static_cast<char>( sessionAuthlevel );
        }
        std::string topic = data["topic"];
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        std::string subName = "";
        if(data["name"].isString()){
            subName = static_cast<std::string>(data["name"]);
        }
        auto & subs = processorSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) ) != subs.end() ) {
            sendFail( id,"you are allready subscribed to "+topic );
            return;
        }
        long subid = eventManager->subscribe( topic,Susi::Events::Processor{[this,id]( Susi::Events::EventPtr event ) {
            Susi::Util::Any::Array headers;
            for( auto & kv : event->headers ) {
                headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
            }
            Susi::Util::Any packet;
            packet["type"] = "processorEvent";
            packet["data"] = event->toAny();
            std::string _id = id;
            eventsToAck[_id][event->id] = std::move( event );
            send( _id,packet );
        }},authlevel,subName );
        subs[topic+std::to_string((int)authlevel)] = subid;
        sendOk( id );
    }
    else {
        sendFail( id,"data is not a object" );
    }
}
void Susi::Api::ApiServerComponent::handleUnregisterConsumer( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        std::string topic = data["topic"];
        char authlevel = 3;
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        auto & subs = consumerSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) )!=subs.end() ) {
            long subid = subs[topic+std::to_string((int)authlevel)];
            eventManager->unsubscribe( subid );
            sendOk( id );
        }
        else {
            sendFail( id,"you are not registered for "+topic );
        }
    }
    else {
        sendFail( id,"data is not a object" );
    }
}

void Susi::Api::ApiServerComponent::handleUnregisterProcessor( std::string & id, Susi::Util::Any & packet ) {
    auto & data = packet["data"];
    if( data.isObject() ) {
        std::string topic = data["topic"];
        char authlevel = 3;
        if(data["authlevel"].isInteger()){
            char supposedAuthlevel = static_cast<char>(data["authlevel"]);
            if(supposedAuthlevel > authlevel){
                authlevel = supposedAuthlevel;
            }
        }
        auto & subs = processorSubscriptions[id];
        if( subs.find( topic+std::to_string((int)authlevel) )!=subs.end() ) {
            long subid = subs[topic+std::to_string((int)authlevel)];
            eventManager->unsubscribe( subid );
            sendOk( id );
        }
        else {
            sendFail( id,"you are not registered for "+topic );
        }
    }
    else {
        sendFail( id,"data is not a object" );
    }
}
void Susi::Api::ApiServerComponent::handlePublish( std::string & id, Susi::Util::Any & packet ) {
    auto & eventData = packet["data"];
    if( !eventData.isObject() || !eventData["topic"].isString() ) {
        sendFail( id,"publish handler: data is not an object or topic is not set correctly" );
        return;
    }
    char authlevel = 3;
    auto sessionAuthlevel = sessionManager->getSessionAttribute( id, "authlevel" );
    if( sessionAuthlevel.isInteger() ) {
        authlevel = static_cast<char>( sessionAuthlevel );
    }
    else {
        Susi::Logger::debug( "sessionAuthlevelValue: "+sessionAuthlevel.toJSONString() );
    }
    auto event = eventManager->createEvent( eventData["topic"] );
    Susi::Events::Event rawEvent {eventData};
    rawEvent.sessionID = id;
    if( rawEvent.id == "" ) {
        rawEvent.id = std::to_string(std::chrono::system_clock::now().time_since_epoch().count());
    }
    *event = rawEvent;
    if( event->authlevel < authlevel ) {
        event->authlevel = authlevel;
    }
    eventManager->publish( std::move( event ),[this,id]( Susi::Events::SharedEventPtr event ) {
        Susi::Util::Any::Array headers;
        for( auto & kv : event->headers ) {
            headers.push_back( Susi::Util::Any::Object {{kv.first,kv.second}} );
        }
        Susi::Util::Any packet;
        packet["type"] = "ack";
        packet["data"] = event->toAny();
        std::string _id = id;
        send( _id,packet );
    } );

    sendOk( id );
}

void Susi::Api::ApiServerComponent::handleAck( std::string & id, Susi::Util::Any & packet ) {
    auto & eventData = packet["data"];
    if( !eventData.isObject() || !eventData["topic"].isString() ) {
        sendFail( id,"ack handler: data is not an object or topic is not set correctly" );
        return;
    }
    std::string eventID = static_cast<std::string>(eventData["id"]);
    if(!(eventsToAck.count(id)>0) || !(eventsToAck[id].count(eventID)>0)){
        sendFail( id , "unexpected ack" );
        return;
    }
    auto event = std::move( eventsToAck[id][eventID] );
    eventsToAck[id].erase( eventID );
    event->headers.clear();
    event->id = eventID;
    if( eventData["headers"].isArray() ) {
        Susi::Util::Any::Array arr = eventData["headers"];
        for( Susi::Util::Any::Object & val : arr ) {
            for( auto & kv : val ) {
                event->headers.push_back( std::make_pair( kv.first,( std::string )kv.second ) );
            }
        }
    }
    if( !eventData["payload"].isNull() ) {
        event->payload = eventData["payload"];
    }
    eventManager->ack( std::move( event ) );
    sendOk( id );
}

void Susi::Api::ApiServerComponent::sendOk( std::string & id ) {
    Susi::Util::Any response;
    response["type"] = "status";
    response["error"] = false;
    send( id,response );
}

void Susi::Api::ApiServerComponent::sendFail( std::string & id,std::string error ) {
    Susi::Util::Any response;
    response["type"] = "status";
    response["error"] = true;
    response["data"] = error;
    send( id,response );
}<|endoftext|>


<commit_before>#include "stdafx.h"
#include "AutoPacket.h"
#include "AutoPacketFactory.h"
#include "AutoPacketProfiler.h"
#include <boost/any.hpp>

AutoPacket::AutoPacket()
{
}

AutoPacket::~AutoPacket()
{
}

void AutoPacket::UpdateSatisfaction(const std::type_info& info) {
  auto decorator = m_factory->FindDecorator(info);
  if(!decorator)
    return;

  const auto& satVec = m_factory->GetSubscriberVector();
  const auto& subscribers = decorator->subscribers;

  // Update all satisfaction counters:
  for(auto q = subscribers.begin(); q != subscribers.end(); q++)
    if(!--m_satCounters[*q].remaining) {
      // No entries remaining in this saturation, we can now make the call
      auto& entry = satVec[*q];
      assert(entry.GetCall());

      if(m_profiler && m_profiler->ShouldProfile()) {
        // Record the current time before we hand control over to the call:
        auto before = boost::chrono::high_resolution_clock::now();

        // Make the actual call
        entry.GetCall()(entry.GetSubscriberPtr(), *this);

        // Record the total time spent in the call
        // TODO:  This naive implementation will also add any time spent in
        // subscribers which are reached from the subscriber defined above.
        // A good profiling system should exclude the time spent in dependent
        // subscribers by having some sort of thread-specific reentrancy
        // detection on this function--perhaps by propagating out a "boost"
        // value which will be subtracted by callers operating at higher
        // elevation levels.
        m_profiler->AddProfilingInformation(
          *entry.GetSubscriberTypeInfo(),
          boost::chrono::high_resolution_clock::now() - before
        );
      }
      else
        // No profiling required, just make the call directly
        entry.GetCall()(entry.GetSubscriberPtr(), *this);
    }
}

void AutoPacket::Release(void) {
  for(size_t i = m_satCounters.size(); i--;)
    m_satCounters[i].subscriber = boost::any();
}

void AutoPacket::Reset(void) {
  for(auto q = m_mp.begin(); q != m_mp.end(); q++)
    if(q->second) {
      delete q->second;
      q->second = nullptr;
    }

  auto& vec = m_factory->GetSubscriberVector();
  m_satCounters.resize(vec.size());
  for(size_t i = vec.size(); i--;) {
    const auto& curSrc = vec[i];
    auto& curDst = m_satCounters[i];

    curDst.remaining = curSrc.GetArity();
    curDst.subscriber = curSrc.GetSubscriber();
  }

  // We will automatically satisfy any requests for AutoPacket:
  UpdateSatisfaction(typeid(AutoPacket));
}

bool AutoPacket::HasSubscribers(const std::type_info& ti) const {
  // Obtain the decorator:
  auto decorator = m_factory->FindDecorator(ti);
  if(!decorator)
    // Nobody anywhere cares about this type
    return false;

  const auto& subscribers = decorator->subscribers;
  for(size_t i = subscribers.size(); i--; )
    if(
      subscribers[i] < m_satCounters.size() &&
      m_satCounters[subscribers[i]].remaining
    )
      // Found a valid, enabled subscriber
      return true;

  // No matches, end here
  return false;
}<commit_msg>Comment updated<commit_after>#include "stdafx.h"
#include "AutoPacket.h"
#include "AutoPacketFactory.h"
#include "AutoPacketProfiler.h"
#include <boost/any.hpp>

AutoPacket::AutoPacket()
{
}

AutoPacket::~AutoPacket()
{
}

void AutoPacket::UpdateSatisfaction(const std::type_info& info) {
  auto decorator = m_factory->FindDecorator(info);
  if(!decorator)
    // Trivial return, there's no subscriber to this decoration
    return;

  const auto& satVec = m_factory->GetSubscriberVector();
  const auto& subscribers = decorator->subscribers;

  // Update all satisfaction counters:
  for(auto q = subscribers.begin(); q != subscribers.end(); q++)
    if(!--m_satCounters[*q].remaining) {
      // No entries remaining in this saturation, we can now make the call
      auto& entry = satVec[*q];
      assert(entry.GetCall());

      if(m_profiler && m_profiler->ShouldProfile()) {
        // Record the current time before we hand control over to the call:
        auto before = boost::chrono::high_resolution_clock::now();

        // Make the actual call
        entry.GetCall()(entry.GetSubscriberPtr(), *this);

        // Record the total time spent in the call
        // TODO:  This naive implementation will also add any time spent in
        // subscribers which are reached from the subscriber defined above.
        // A good profiling system should exclude the time spent in dependent
        // subscribers by having some sort of thread-specific reentrancy
        // detection on this function--perhaps by propagating out a "boost"
        // value which will be subtracted by callers operating at higher
        // elevation levels.
        m_profiler->AddProfilingInformation(
          *entry.GetSubscriberTypeInfo(),
          boost::chrono::high_resolution_clock::now() - before
        );
      }
      else
        // No profiling required, just make the call directly
        entry.GetCall()(entry.GetSubscriberPtr(), *this);
    }
}

void AutoPacket::Release(void) {
  for(size_t i = m_satCounters.size(); i--;)
    m_satCounters[i].subscriber = boost::any();
}

void AutoPacket::Reset(void) {
  for(auto q = m_mp.begin(); q != m_mp.end(); q++)
    if(q->second) {
      delete q->second;
      q->second = nullptr;
    }

  auto& vec = m_factory->GetSubscriberVector();
  m_satCounters.resize(vec.size());
  for(size_t i = vec.size(); i--;) {
    const auto& curSrc = vec[i];
    auto& curDst = m_satCounters[i];

    curDst.remaining = curSrc.GetArity();
    curDst.subscriber = curSrc.GetSubscriber();
  }

  // We will automatically satisfy any requests for AutoPacket:
  UpdateSatisfaction(typeid(AutoPacket));
}

bool AutoPacket::HasSubscribers(const std::type_info& ti) const {
  // Obtain the decorator:
  auto decorator = m_factory->FindDecorator(ti);
  if(!decorator)
    // Nobody anywhere cares about this type
    return false;

  const auto& subscribers = decorator->subscribers;
  for(size_t i = subscribers.size(); i--; )
    if(
      subscribers[i] < m_satCounters.size() &&
      m_satCounters[subscribers[i]].remaining
    )
      // Found a valid, enabled subscriber
      return true;

  // No matches, end here
  return false;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: RelationTableView.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: oj $ $Date: 2002-02-08 08:56:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_RELATION_TABLEVIEW_HXX
#define DBAUI_RELATION_TABLEVIEW_HXX

#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif

namespace dbaui
{
    class ORelationDesignView;
    class ORelationTableConnectionData;
    class ORelationTableView : public OJoinTableView
    {
        OTableConnection*               m_pExistingConnection; // is set when a connection was draged on an existing connection
        ORelationTableConnectionData*   m_pCurrentlyTabConnData; // set when we creating a connection with more than one keycolumn
    protected:
        virtual void ConnDoubleClicked( OTableConnection* pConnection );
        virtual void KeyInput( const KeyEvent& rEvt );
        virtual void AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, BOOL bNewTable = FALSE);

    public:
        ORelationTableView( Window* pParent, ORelationDesignView* pView );
        virtual ~ORelationTableView();

        //  virtual void AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, BOOL bNewTable = FALSE);
        virtual void RemoveTabWin( OTableWindow* pTabWin );
        virtual void AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest);
        virtual ::std::vector<OTableConnection*>::const_iterator RemoveConnection(OTableConnection* pConn,sal_Bool _bDelete);

        virtual void ReSync();

        void AddNewRelation();
            // reisst den Dialog fuer eine voellig neue Relation hoch
        // wird vom AddTabDlg benutzt, um festzustellen, ob noch Tabellen hinzugefuegt werden duerfen
        virtual BOOL IsAddAllowed();

        virtual void lookForUiActivities();
    };
}
#endif // DBAUI_RELATION_TABLEVIEW_HXX

<commit_msg>#99302# correct movement<commit_after>/*************************************************************************
 *
 *  $RCSfile: RelationTableView.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: oj $ $Date: 2002-05-22 11:25:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_RELATION_TABLEVIEW_HXX
#define DBAUI_RELATION_TABLEVIEW_HXX

#ifndef DBAUI_JOINTABLEVIEW_HXX
#include "JoinTableView.hxx"
#endif

namespace dbaui
{
    class ORelationDesignView;
    class ORelationTableConnectionData;
    class ORelationTableView : public OJoinTableView
    {
        OTableConnection*               m_pExistingConnection; // is set when a connection was draged on an existing connection
        ORelationTableConnectionData*   m_pCurrentlyTabConnData; // set when we creating a connection with more than one keycolumn
    protected:
        virtual void ConnDoubleClicked( OTableConnection* pConnection );
        virtual void AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, BOOL bNewTable = FALSE);

    public:
        ORelationTableView( Window* pParent, ORelationDesignView* pView );
        virtual ~ORelationTableView();

        //  virtual void AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, BOOL bNewTable = FALSE);
        virtual void RemoveTabWin( OTableWindow* pTabWin );
        virtual void AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest);
        virtual ::std::vector<OTableConnection*>::const_iterator RemoveConnection(OTableConnection* pConn,sal_Bool _bDelete);

        virtual void ReSync();

        void AddNewRelation();
            // reisst den Dialog fuer eine voellig neue Relation hoch
        // wird vom AddTabDlg benutzt, um festzustellen, ob noch Tabellen hinzugefuegt werden duerfen
        virtual BOOL IsAddAllowed();

        virtual void lookForUiActivities();
    };
}
#endif // DBAUI_RELATION_TABLEVIEW_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DBTypeWizDlgSetup.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:32:58 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBU_REGHELPER_HXX_
#include "dbu_reghelper.hxx"
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTLISTENER_HPP_
#include <com/sun/star/document/XEventListener.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XSET_HPP_
#include <com/sun/star/container/XSet.hpp>
#endif
#ifndef DBAUI_DBTYPEWIZDLGSETUP_HXX
#include "DBTypeWizDlgSetup.hxx"
#endif
#ifndef DBAUI_DBWIZSETUP_HXX
#include "dbwizsetup.hxx"
#endif
#ifndef _COM_SUN_STAR_SDB_XOFFICEDATABASEDOCUMENT_HPP_
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

using namespace dbaui;
namespace css = ::com::sun::star;

extern "C" void SAL_CALL createRegistryInfo_ODBTypeWizDialogSetup()
{
    static OMultiInstanceAutoRegistration< ODBTypeWizDialogSetup > aAutoRegistration;
}

//.........................................................................
namespace dbaui
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::sdbc;

//=========================================================================
//-------------------------------------------------------------------------
ODBTypeWizDialogSetup::ODBTypeWizDialogSetup(const Reference< XMultiServiceFactory >& _rxORB)
    :ODatabaseAdministrationDialog(_rxORB)
    ,m_bOpenDatabase(sal_True)
    ,m_bStartTableWizard(sal_False)
{
    registerProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenDatabase")), 3, PropertyAttribute::TRANSIENT,
        &m_bOpenDatabase, getBooleanCppuType());

    registerProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartTableWizard")), 4, PropertyAttribute::TRANSIENT,
        &m_bStartTableWizard, getBooleanCppuType());
}
//-------------------------------------------------------------------------
Sequence<sal_Int8> SAL_CALL ODBTypeWizDialogSetup::getImplementationId(  ) throw(RuntimeException)
{
    static ::cppu::OImplementationId aId;
    return aId.getImplementationId();
}

//-------------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODBTypeWizDialogSetup::Create(const Reference< XMultiServiceFactory >& _rxFactory)
{
    Reference < XInterface > xDBWizard = *(new ODBTypeWizDialogSetup(_rxFactory));
    return xDBWizard;
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODBTypeWizDialogSetup::getImplementationName() throw(RuntimeException)
{
    return getImplementationName_Static();
}

//-------------------------------------------------------------------------
::rtl::OUString ODBTypeWizDialogSetup::getImplementationName_Static() throw(RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.ODBTypeWizDialogSetup"));
}

//-------------------------------------------------------------------------
::comphelper::StringSequence SAL_CALL ODBTypeWizDialogSetup::getSupportedServiceNames() throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

//-------------------------------------------------------------------------
::comphelper::StringSequence ODBTypeWizDialogSetup::getSupportedServiceNames_Static() throw(RuntimeException)
{
    ::comphelper::StringSequence aSupported(1);
    aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DatabaseWizardDialog"));
    return aSupported;
}

//-------------------------------------------------------------------------
Reference<XPropertySetInfo>  SAL_CALL ODBTypeWizDialogSetup::getPropertySetInfo() throw(RuntimeException)
{
    return createPropertySetInfo( getInfoHelper() );
}

//-------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& ODBTypeWizDialogSetup::getInfoHelper()
{
    return *const_cast<ODBTypeWizDialogSetup*>(this)->getArrayHelper();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* ODBTypeWizDialogSetup::createArrayHelper( ) const
{
    Sequence< Property > aProps;
    describeProperties(aProps);
    return new ::cppu::OPropertyArrayHelper(aProps);
}
//------------------------------------------------------------------------------
Dialog* ODBTypeWizDialogSetup::createDialog(Window* _pParent)
{
    return new ODbTypeWizDialogSetup(_pParent, m_pDatasourceItems, m_xORB, m_aInitialSelection);
}
// -----------------------------------------------------------------------------
void ODBTypeWizDialogSetup::executedDialog(sal_Int16 _nExecutionResult)
{
    if ( _nExecutionResult == RET_OK )
    {
        const ODbTypeWizDialogSetup* pDialog = static_cast< ODbTypeWizDialogSetup* >( m_pDialog );
        m_bOpenDatabase = pDialog->IsDatabaseDocumentToBeOpened();
        m_bStartTableWizard = pDialog->IsTableWizardToBeStarted();
    }
}

//.........................................................................
}   // namespace dbaui
//.........................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.10.258); FILE MERGED 2008/03/31 13:28:09 rt 1.10.258.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: DBTypeWizDlgSetup.cxx,v $
 * $Revision: 1.11 $
 *
 * 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.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBU_REGHELPER_HXX_
#include "dbu_reghelper.hxx"
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTLISTENER_HPP_
#include <com/sun/star/document/XEventListener.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XSET_HPP_
#include <com/sun/star/container/XSet.hpp>
#endif
#ifndef DBAUI_DBTYPEWIZDLGSETUP_HXX
#include "DBTypeWizDlgSetup.hxx"
#endif
#ifndef DBAUI_DBWIZSETUP_HXX
#include "dbwizsetup.hxx"
#endif
#ifndef _COM_SUN_STAR_SDB_XOFFICEDATABASEDOCUMENT_HPP_
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif

using namespace dbaui;
namespace css = ::com::sun::star;

extern "C" void SAL_CALL createRegistryInfo_ODBTypeWizDialogSetup()
{
    static OMultiInstanceAutoRegistration< ODBTypeWizDialogSetup > aAutoRegistration;
}

//.........................................................................
namespace dbaui
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::sdbc;

//=========================================================================
//-------------------------------------------------------------------------
ODBTypeWizDialogSetup::ODBTypeWizDialogSetup(const Reference< XMultiServiceFactory >& _rxORB)
    :ODatabaseAdministrationDialog(_rxORB)
    ,m_bOpenDatabase(sal_True)
    ,m_bStartTableWizard(sal_False)
{
    registerProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenDatabase")), 3, PropertyAttribute::TRANSIENT,
        &m_bOpenDatabase, getBooleanCppuType());

    registerProperty(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartTableWizard")), 4, PropertyAttribute::TRANSIENT,
        &m_bStartTableWizard, getBooleanCppuType());
}
//-------------------------------------------------------------------------
Sequence<sal_Int8> SAL_CALL ODBTypeWizDialogSetup::getImplementationId(  ) throw(RuntimeException)
{
    static ::cppu::OImplementationId aId;
    return aId.getImplementationId();
}

//-------------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODBTypeWizDialogSetup::Create(const Reference< XMultiServiceFactory >& _rxFactory)
{
    Reference < XInterface > xDBWizard = *(new ODBTypeWizDialogSetup(_rxFactory));
    return xDBWizard;
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODBTypeWizDialogSetup::getImplementationName() throw(RuntimeException)
{
    return getImplementationName_Static();
}

//-------------------------------------------------------------------------
::rtl::OUString ODBTypeWizDialogSetup::getImplementationName_Static() throw(RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.ODBTypeWizDialogSetup"));
}

//-------------------------------------------------------------------------
::comphelper::StringSequence SAL_CALL ODBTypeWizDialogSetup::getSupportedServiceNames() throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

//-------------------------------------------------------------------------
::comphelper::StringSequence ODBTypeWizDialogSetup::getSupportedServiceNames_Static() throw(RuntimeException)
{
    ::comphelper::StringSequence aSupported(1);
    aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DatabaseWizardDialog"));
    return aSupported;
}

//-------------------------------------------------------------------------
Reference<XPropertySetInfo>  SAL_CALL ODBTypeWizDialogSetup::getPropertySetInfo() throw(RuntimeException)
{
    return createPropertySetInfo( getInfoHelper() );
}

//-------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& ODBTypeWizDialogSetup::getInfoHelper()
{
    return *const_cast<ODBTypeWizDialogSetup*>(this)->getArrayHelper();
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* ODBTypeWizDialogSetup::createArrayHelper( ) const
{
    Sequence< Property > aProps;
    describeProperties(aProps);
    return new ::cppu::OPropertyArrayHelper(aProps);
}
//------------------------------------------------------------------------------
Dialog* ODBTypeWizDialogSetup::createDialog(Window* _pParent)
{
    return new ODbTypeWizDialogSetup(_pParent, m_pDatasourceItems, m_xORB, m_aInitialSelection);
}
// -----------------------------------------------------------------------------
void ODBTypeWizDialogSetup::executedDialog(sal_Int16 _nExecutionResult)
{
    if ( _nExecutionResult == RET_OK )
    {
        const ODbTypeWizDialogSetup* pDialog = static_cast< ODbTypeWizDialogSetup* >( m_pDialog );
        m_bOpenDatabase = pDialog->IsDatabaseDocumentToBeOpened();
        m_bStartTableWizard = pDialog->IsTableWizardToBeStarted();
    }
}

//.........................................................................
}   // namespace dbaui
//.........................................................................

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: sgfbram.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:58:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SGFBRAM_HXX
#define _SGFBRAM_HXX

// die folgenden Zeilen knnen raus, sobald das auch im WNT-Update verfgbar ist:
#if defined(WNT)
typedef void                INT64;
typedef void                UINT64;
typedef long                INT32;
typedef unsigned long       UINT32;
typedef short               INT16;
typedef unsigned short      UINT16;
typedef char                INT8;
typedef unsigned char       UINT8;
#endif

#define SgfBitImag0   1 /* Bitmap                      */
#define SgfBitImag1   4 /* Bitmap                      */
#define SgfBitImag2   5 /* Bitmap                      */
#define SgfBitImgMo   6 /* Monochrome Bitmap           */
#define SgfSimpVect   2 /* Einfaches Vectorformat      */
#define SgfPostScrp   3 /* Postscript file             */
#define SgfStarDraw   7 /* StarDraw SGV-Datei          */
#define SgfDontKnow 255 /* Unbekannt oder kein SGF/SGV */

// Konstanten fr SgfHeader.SwGrCol
#define SgfBlckWhit 1 /* Schwarz/Wei Bild                  Ŀ SimpVector,  */
#define SgfGrayscal 2 /* Bild mit Graustufen                  StarDraw und */
#define Sgf16Colors 3 /* Farbbild (16 Farben)                Bit Image    */
#define SgfVectFarb 4 /* Farben fr Linien verwenden        Ŀ              */
#define SgfVectGray 5 /* Graustufen fr Linien verwenden      Nur fr      */
#define SgfVectWdth 6 /* Strichstrken fr Linien verwenden  SimpVector   */

#define SgfHeaderSize 42
class SgfHeader
{
public:
    UINT16 Magic;
    UINT16 Version;
    UINT16 Typ;
    UINT16 Xsize;
    UINT16 Ysize;
    INT16  Xoffs;
    INT16  Yoffs;
    UINT16 Planes;    // Layer
    UINT16 SwGrCol;
    char   Autor[10];
    char   Programm[10];
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (38 mod 4 =2) !

    UINT32 GetOffset();
    friend SvStream& operator>>(SvStream& rIStream, SgfHeader& rHead);
    BOOL   ChkMagic();
};

#define SgfEntrySize 22
class SgfEntry
{
public:
    UINT16 Typ;
    UINT16 iFrei;
    UINT16 lFreiLo,lFreiHi;
    char   cFrei[10];
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (18 mod 4 =2) !

    UINT32 GetOffset();
    friend SvStream& operator>>(SvStream& rIStream, SgfEntry& rEntr);
};

#define SgfVectorSize 10
class SgfVector
{
public:
    UINT16 Flag;
    INT16 x;
    INT16 y;
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (6 mod 4 =2) !

    friend SvStream& operator>>(SvStream& rIStream, SgfVector& rEntr);
};

extern long SgfVectXofs;
extern long SgfVectYofs;
extern long SgfVectXmul;
extern long SgfVectYmul;
extern long SgfVectXdiv;
extern long SgfVectYdiv;
extern BOOL SgfVectScal;

////////////////////////////////////////////////////////////////////////////////////////////////////
// Windows BMP /////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

#define BmpFileHeaderSize 14
class BmpFileHeader
{
public:
    UINT16 Typ;            // = "BM"
    UINT16 SizeLo,SizeHi;  // Filesize in Bytes
    UINT16 Reserve1;       // Reserviert
    UINT16 Reserve2;       // Reserviert
    UINT16 OfsLo,OfsHi;    // Offset?

    void   SetSize(UINT32 Size);
    void   SetOfs(UINT32 Size);
    UINT32 GetOfs();
    friend SvStream& operator<<(SvStream& rOStream, BmpFileHeader& rHead);
};

#define BmpInfoHeaderSize 40
class BmpInfoHeader
{
public:
    UINT32 Size;       // Gre des BmpInfoHeaders
    INT32  Width;      // Breite in Pixel
    INT32  Hight;      // Hhe in Pixel
    UINT16 Planes;     // Anzahl der Planes (immer 1)
    UINT16 PixBits;    // Anzahl der Bit je Pixel (1,4,8,oder 24)
    UINT32 Compress;   // Datenkompression
    UINT32 ImgSize;    // Gre der Images in Bytes. Ohne Kompression ist auch 0 erlaubt.
    INT32  xDpmm;      // Dot per Meter (0 ist erlaubt)
    INT32  yDpmm;      // Dot per Meter (0 ist erlaubt)
    UINT32 ColUsed;    // Anzahl der verwendeten Farben (0=alle)
    UINT32 ColMust;    // Anzahl der wichtigen Farben (0=alle)

    friend SvStream& operator<<(SvStream& rOStream, BmpInfoHeader& rHead);
};

#define RGBQuadSize 4
class RGBQuad {
private:
    BYTE Red;
    BYTE Grn;
    BYTE Blu;
    BYTE Fil;
public:
    RGBQuad(BYTE R, BYTE G, BYTE B) { Red=R; Grn=G; Blu=B; Fil=0; }
};

#endif //_SGFBRAM_HXX
<commit_msg>using typedefs of solar.h instead of own definition<commit_after>/*************************************************************************
 *
 *  $RCSfile: sgfbram.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: sj $ $Date: 2002-07-03 10:22:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SGFBRAM_HXX
#define _SGFBRAM_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#define SgfBitImag0   1 /* Bitmap                      */
#define SgfBitImag1   4 /* Bitmap                      */
#define SgfBitImag2   5 /* Bitmap                      */
#define SgfBitImgMo   6 /* Monochrome Bitmap           */
#define SgfSimpVect   2 /* Einfaches Vectorformat      */
#define SgfPostScrp   3 /* Postscript file             */
#define SgfStarDraw   7 /* StarDraw SGV-Datei          */
#define SgfDontKnow 255 /* Unbekannt oder kein SGF/SGV */

// Konstanten fr SgfHeader.SwGrCol
#define SgfBlckWhit 1 /* Schwarz/Wei Bild                  Ŀ SimpVector,  */
#define SgfGrayscal 2 /* Bild mit Graustufen                  StarDraw und */
#define Sgf16Colors 3 /* Farbbild (16 Farben)                Bit Image    */
#define SgfVectFarb 4 /* Farben fr Linien verwenden        Ŀ              */
#define SgfVectGray 5 /* Graustufen fr Linien verwenden      Nur fr      */
#define SgfVectWdth 6 /* Strichstrken fr Linien verwenden  SimpVector   */

#define SgfHeaderSize 42
class SgfHeader
{
public:
    UINT16 Magic;
    UINT16 Version;
    UINT16 Typ;
    UINT16 Xsize;
    UINT16 Ysize;
    INT16  Xoffs;
    INT16  Yoffs;
    UINT16 Planes;    // Layer
    UINT16 SwGrCol;
    char   Autor[10];
    char   Programm[10];
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (38 mod 4 =2) !

    UINT32 GetOffset();
    friend SvStream& operator>>(SvStream& rIStream, SgfHeader& rHead);
    BOOL   ChkMagic();
};

#define SgfEntrySize 22
class SgfEntry
{
public:
    UINT16 Typ;
    UINT16 iFrei;
    UINT16 lFreiLo,lFreiHi;
    char   cFrei[10];
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (18 mod 4 =2) !

    UINT32 GetOffset();
    friend SvStream& operator>>(SvStream& rIStream, SgfEntry& rEntr);
};

#define SgfVectorSize 10
class SgfVector
{
public:
    UINT16 Flag;
    INT16 x;
    INT16 y;
    UINT16 OfsLo,OfsHi; // DWord-Allignment ist notwendig (6 mod 4 =2) !

    friend SvStream& operator>>(SvStream& rIStream, SgfVector& rEntr);
};

extern long SgfVectXofs;
extern long SgfVectYofs;
extern long SgfVectXmul;
extern long SgfVectYmul;
extern long SgfVectXdiv;
extern long SgfVectYdiv;
extern BOOL SgfVectScal;

////////////////////////////////////////////////////////////////////////////////////////////////////
// Windows BMP /////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

#define BmpFileHeaderSize 14
class BmpFileHeader
{
public:
    UINT16 Typ;            // = "BM"
    UINT16 SizeLo,SizeHi;  // Filesize in Bytes
    UINT16 Reserve1;       // Reserviert
    UINT16 Reserve2;       // Reserviert
    UINT16 OfsLo,OfsHi;    // Offset?

    void   SetSize(UINT32 Size);
    void   SetOfs(UINT32 Size);
    UINT32 GetOfs();
    friend SvStream& operator<<(SvStream& rOStream, BmpFileHeader& rHead);
};

#define BmpInfoHeaderSize 40
class BmpInfoHeader
{
public:
    UINT32 Size;       // Gre des BmpInfoHeaders
    INT32  Width;      // Breite in Pixel
    INT32  Hight;      // Hhe in Pixel
    UINT16 Planes;     // Anzahl der Planes (immer 1)
    UINT16 PixBits;    // Anzahl der Bit je Pixel (1,4,8,oder 24)
    UINT32 Compress;   // Datenkompression
    UINT32 ImgSize;    // Gre der Images in Bytes. Ohne Kompression ist auch 0 erlaubt.
    INT32  xDpmm;      // Dot per Meter (0 ist erlaubt)
    INT32  yDpmm;      // Dot per Meter (0 ist erlaubt)
    UINT32 ColUsed;    // Anzahl der verwendeten Farben (0=alle)
    UINT32 ColMust;    // Anzahl der wichtigen Farben (0=alle)

    friend SvStream& operator<<(SvStream& rOStream, BmpInfoHeader& rHead);
};

#define RGBQuadSize 4
class RGBQuad {
private:
    BYTE Red;
    BYTE Grn;
    BYTE Blu;
    BYTE Fil;
public:
    RGBQuad(BYTE R, BYTE G, BYTE B) { Red=R; Grn=G; Blu=B; Fil=0; }
};

#endif //_SGFBRAM_HXX
<|endoftext|>


<commit_before>//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Mehtods for finding all instances of a USR. Our strategy is very
/// simple; we just compare the USR at every relevant AST node with the one
/// provided.
///
//===----------------------------------------------------------------------===//

#include "USRLocFinder.h"
#include "USRFinder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallVector.h"

using namespace llvm;

namespace clang {
namespace rename {

namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
    : public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
public:
  explicit USRLocFindingASTVisitor(StringRef USR, StringRef PrevName) : USR(USR), PrevName(PrevName) {
  }

  // Declaration visitors:

  bool VisitNamedDecl(const NamedDecl *Decl) {
    if (getUSRForDecl(Decl) == USR) {
      LocationsFound.push_back(Decl->getLocation());
    }
    return true;
  }

  bool VisitVarDecl(clang::VarDecl *Decl) {
    clang::QualType Type = Decl->getType();
    const clang::RecordDecl *RecordDecl = Type->getPointeeCXXRecordDecl();
    if (RecordDecl) {
      if (getUSRForDecl(RecordDecl) == USR) {
        // The declaration refers to a type that is to be renamed.
        LocationsFound.push_back(Decl->getTypeSpecStartLoc());
      }
    }
    return true;
  }

  bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
    const ASTContext &Context = ConstructorDecl->getASTContext();
    for (clang::CXXConstructorDecl::init_const_iterator it = ConstructorDecl->init_begin(); it != ConstructorDecl->init_end(); ++it) {
      const clang::CXXCtorInitializer* Initializer = *it;
      if (Initializer->getSourceOrder() == -1) {
        // Ignore implicit initializers.
        continue;
      }

      if (const clang::FieldDecl *FieldDecl = Initializer->getAnyMember()) {
        if (getUSRForDecl(FieldDecl) == USR) {
          // The initializer refers to a field that is to be renamed.
          SourceLocation Location = Initializer->getSourceLocation();
          StringRef TokenName = Lexer::getSourceText(CharSourceRange::getTokenRange(Location), Context.getSourceManager(), Context.getLangOpts());
          if (TokenName == PrevName) {
            // The token of the source location we find actually has the old name.
            LocationsFound.push_back(Initializer->getSourceLocation());
          }
        }
      }
    }

    if (getUSRForDecl(ConstructorDecl) == USR) {
      // This takes care of the class name part of a non-inline ctor definition.
      LocationsFound.push_back(ConstructorDecl->getLocStart());
    }
    return true;
  }

  bool VisitCXXDestructorDecl(clang::CXXDestructorDecl *DestructorDecl) {
    if (getUSRForDecl(DestructorDecl->getParent()) == USR) {
      // Handles "~Foo" from "Foo::~Foo".
      SourceLocation Location = DestructorDecl->getLocation();
      const ASTContext &Context = DestructorDecl->getASTContext();
      StringRef TokenName = Lexer::getSourceText(
          CharSourceRange::getTokenRange(Location), Context.getSourceManager(),
          Context.getLangOpts());
      // 1 is the length of the "~" string that is not to be touched by the
      // rename.
      assert(TokenName.startswith("~"));
      LocationsFound.push_back(Location.getLocWithOffset(1));

      if (DestructorDecl->isThisDeclarationADefinition()) {
        // Handles "Foo" from "Foo::~Foo".
        LocationsFound.push_back(DestructorDecl->getLocStart());
      }
    }

    return true;
  }

  // Expression visitors:

  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
    const auto *Decl = Expr->getFoundDecl();

    checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
    if (getUSRForDecl(Decl) == USR) {
      const SourceManager &Manager = Decl->getASTContext().getSourceManager();
      SourceLocation Location = Manager.getSpellingLoc(Expr->getLocation());
      LocationsFound.push_back(Location);
    }

    return true;
  }

  bool VisitMemberExpr(const MemberExpr *Expr) {
    const auto *Decl = Expr->getFoundDecl().getDecl();
    if (getUSRForDecl(Decl) == USR) {
      const SourceManager &Manager = Decl->getASTContext().getSourceManager();
      SourceLocation Location = Manager.getSpellingLoc(Expr->getMemberLoc());
      LocationsFound.push_back(Location);
    }
    return true;
  }

  bool VisitCXXConstructExpr(const CXXConstructExpr *Expr) {
    CXXConstructorDecl *Decl = Expr->getConstructor();

    if (getUSRForDecl(Decl) == USR) {
      // This takes care of 'new <name>' expressions.
      LocationsFound.push_back(Expr->getLocation());
    }

    return true;
  }

  bool VisitCXXStaticCastExpr(clang::CXXStaticCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXDynamicCastExpr(clang::CXXDynamicCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXReinterpretCastExpr(clang::CXXReinterpretCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXConstCastExpr(clang::CXXConstCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  // Non-visitors:

  // \brief Returns a list of unique locations. Duplicate or overlapping
  // locations are erroneous and should be reported!
  const std::vector<clang::SourceLocation> &getLocationsFound() const {
    return LocationsFound;
  }

private:
  // Namespace traversal:
  void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
    while (NameLoc) {
      const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
      if (Decl && getUSRForDecl(Decl) == USR)
        LocationsFound.push_back(NameLoc.getLocalBeginLoc());
      NameLoc = NameLoc.getPrefix();
    }
  }

  bool handleCXXNamedCastExpr(clang::CXXNamedCastExpr *Expr) {
    clang::QualType Type = Expr->getType();
    // See if this a cast of a pointer.
    const RecordDecl* Decl = Type->getPointeeCXXRecordDecl();
    if (!Decl) {
      // See if this is a cast of a reference.
      Decl = Type->getAsCXXRecordDecl();
    }

    if (Decl && getUSRForDecl(Decl) == USR) {
      SourceLocation Location = Expr->getTypeInfoAsWritten()->getTypeLoc().getBeginLoc();
      LocationsFound.push_back(Location);
    }

    return true;
  }

  // All the locations of the USR were found.
  const std::string USR;
  // Old name that is renamed.
  const std::string PrevName;
  std::vector<clang::SourceLocation> LocationsFound;
};
} // namespace

std::vector<SourceLocation> getLocationsOfUSR(StringRef USR,
                                              StringRef PrevName,
                                              Decl *Decl) {
  USRLocFindingASTVisitor visitor(USR, PrevName);

  visitor.TraverseDecl(Decl);
  return visitor.getLocationsFound();
}

} // namespace rename
} // namespace clang
<commit_msg>[clang-tools] mark TokenName as unused<commit_after>//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Mehtods for finding all instances of a USR. Our strategy is very
/// simple; we just compare the USR at every relevant AST node with the one
/// provided.
///
//===----------------------------------------------------------------------===//

#include "USRLocFinder.h"
#include "USRFinder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallVector.h"

using namespace llvm;

namespace clang {
namespace rename {

namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
    : public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
public:
  explicit USRLocFindingASTVisitor(StringRef USR, StringRef PrevName) : USR(USR), PrevName(PrevName) {
  }

  // Declaration visitors:

  bool VisitNamedDecl(const NamedDecl *Decl) {
    if (getUSRForDecl(Decl) == USR) {
      LocationsFound.push_back(Decl->getLocation());
    }
    return true;
  }

  bool VisitVarDecl(clang::VarDecl *Decl) {
    clang::QualType Type = Decl->getType();
    const clang::RecordDecl *RecordDecl = Type->getPointeeCXXRecordDecl();
    if (RecordDecl) {
      if (getUSRForDecl(RecordDecl) == USR) {
        // The declaration refers to a type that is to be renamed.
        LocationsFound.push_back(Decl->getTypeSpecStartLoc());
      }
    }
    return true;
  }

  bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
    const ASTContext &Context = ConstructorDecl->getASTContext();
    for (clang::CXXConstructorDecl::init_const_iterator it = ConstructorDecl->init_begin(); it != ConstructorDecl->init_end(); ++it) {
      const clang::CXXCtorInitializer* Initializer = *it;
      if (Initializer->getSourceOrder() == -1) {
        // Ignore implicit initializers.
        continue;
      }

      if (const clang::FieldDecl *FieldDecl = Initializer->getAnyMember()) {
        if (getUSRForDecl(FieldDecl) == USR) {
          // The initializer refers to a field that is to be renamed.
          SourceLocation Location = Initializer->getSourceLocation();
          StringRef TokenName = Lexer::getSourceText(CharSourceRange::getTokenRange(Location), Context.getSourceManager(), Context.getLangOpts());
          if (TokenName == PrevName) {
            // The token of the source location we find actually has the old name.
            LocationsFound.push_back(Initializer->getSourceLocation());
          }
        }
      }
    }

    if (getUSRForDecl(ConstructorDecl) == USR) {
      // This takes care of the class name part of a non-inline ctor definition.
      LocationsFound.push_back(ConstructorDecl->getLocStart());
    }
    return true;
  }

  bool VisitCXXDestructorDecl(clang::CXXDestructorDecl *DestructorDecl) {
    if (getUSRForDecl(DestructorDecl->getParent()) == USR) {
      // Handles "~Foo" from "Foo::~Foo".
      SourceLocation Location = DestructorDecl->getLocation();
      const ASTContext &Context = DestructorDecl->getASTContext();
      StringRef LLVM_ATTRIBUTE_UNUSED TokenName = Lexer::getSourceText(
          CharSourceRange::getTokenRange(Location), Context.getSourceManager(),
          Context.getLangOpts());
      // 1 is the length of the "~" string that is not to be touched by the
      // rename.
      assert(TokenName.startswith("~"));
      LocationsFound.push_back(Location.getLocWithOffset(1));

      if (DestructorDecl->isThisDeclarationADefinition()) {
        // Handles "Foo" from "Foo::~Foo".
        LocationsFound.push_back(DestructorDecl->getLocStart());
      }
    }

    return true;
  }

  // Expression visitors:

  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
    const auto *Decl = Expr->getFoundDecl();

    checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
    if (getUSRForDecl(Decl) == USR) {
      const SourceManager &Manager = Decl->getASTContext().getSourceManager();
      SourceLocation Location = Manager.getSpellingLoc(Expr->getLocation());
      LocationsFound.push_back(Location);
    }

    return true;
  }

  bool VisitMemberExpr(const MemberExpr *Expr) {
    const auto *Decl = Expr->getFoundDecl().getDecl();
    if (getUSRForDecl(Decl) == USR) {
      const SourceManager &Manager = Decl->getASTContext().getSourceManager();
      SourceLocation Location = Manager.getSpellingLoc(Expr->getMemberLoc());
      LocationsFound.push_back(Location);
    }
    return true;
  }

  bool VisitCXXConstructExpr(const CXXConstructExpr *Expr) {
    CXXConstructorDecl *Decl = Expr->getConstructor();

    if (getUSRForDecl(Decl) == USR) {
      // This takes care of 'new <name>' expressions.
      LocationsFound.push_back(Expr->getLocation());
    }

    return true;
  }

  bool VisitCXXStaticCastExpr(clang::CXXStaticCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXDynamicCastExpr(clang::CXXDynamicCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXReinterpretCastExpr(clang::CXXReinterpretCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  bool VisitCXXConstCastExpr(clang::CXXConstCastExpr *Expr) {
    return handleCXXNamedCastExpr(Expr);
  }

  // Non-visitors:

  // \brief Returns a list of unique locations. Duplicate or overlapping
  // locations are erroneous and should be reported!
  const std::vector<clang::SourceLocation> &getLocationsFound() const {
    return LocationsFound;
  }

private:
  // Namespace traversal:
  void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
    while (NameLoc) {
      const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
      if (Decl && getUSRForDecl(Decl) == USR)
        LocationsFound.push_back(NameLoc.getLocalBeginLoc());
      NameLoc = NameLoc.getPrefix();
    }
  }

  bool handleCXXNamedCastExpr(clang::CXXNamedCastExpr *Expr) {
    clang::QualType Type = Expr->getType();
    // See if this a cast of a pointer.
    const RecordDecl* Decl = Type->getPointeeCXXRecordDecl();
    if (!Decl) {
      // See if this is a cast of a reference.
      Decl = Type->getAsCXXRecordDecl();
    }

    if (Decl && getUSRForDecl(Decl) == USR) {
      SourceLocation Location = Expr->getTypeInfoAsWritten()->getTypeLoc().getBeginLoc();
      LocationsFound.push_back(Location);
    }

    return true;
  }

  // All the locations of the USR were found.
  const std::string USR;
  // Old name that is renamed.
  const std::string PrevName;
  std::vector<clang::SourceLocation> LocationsFound;
};
} // namespace

std::vector<SourceLocation> getLocationsOfUSR(StringRef USR,
                                              StringRef PrevName,
                                              Decl *Decl) {
  USRLocFindingASTVisitor visitor(USR, PrevName);

  visitor.TraverseDecl(Decl);
  return visitor.getLocationsFound();
}

} // namespace rename
} // namespace clang
<|endoftext|>


<commit_before><commit_msg>Remove the pointer declarations for the TFormula (remove memory leak)<commit_after><|endoftext|>


<commit_before>// This file is part of the "x0" project
//   (c) 2009-2015 Christian Parpart <https://github.com/christianparpart>
//
// x0 is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <xzero/UnixSignals.h>
#include <xzero/UnixSignalInfo.h>
#include <xzero/executor/Executor.h>
#include <xzero/io/FileDescriptor.h>
#include <xzero/RuntimeError.h>
#include <xzero/Duration.h>
#include <xzero/logging.h>
#include <memory>
#include <mutex>
#include <atomic>
#include <vector>
#include <list>
#include <signal.h>

#if defined(XZERO_OS_LINUX)
#include <sys/signalfd.h>
#include <unistd.h>
#endif

#if defined(XZERO_OS_DARWIN)
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#endif

namespace xzero {

#if !defined(NDEBUG)
#define TRACE(msg...) logTrace("UnixSignals", msg)
#else
#define TRACE(msg...) do {} while (0)
#endif

class SignalWatcher : public Executor::Handle {
 public:
  typedef Executor::Task Task;

  explicit SignalWatcher(UnixSignals::SignalHandler action)
      : action_(action) {};

  void fire() {
    Executor::Handle::fire(std::bind(action_, info));
  }

  UnixSignalInfo info;

 private:
  UnixSignals::SignalHandler action_;
};

std::string UnixSignals::toString(int signo) {
  switch (signo) {
    // XXX POSIX.1-1990
    case SIGHUP: return "SIGHUP";
    case SIGINT: return "SIGINT";
    case SIGQUIT: return "SIGQUIT";
    case SIGILL: return "SIGILL";
    case SIGABRT: return "SIGABRT";
    case SIGFPE: return "SIGFPE";
    /* SIGKILL: cannot be trapped */
    case SIGSEGV: return "SIGSEGV";
    case SIGPIPE: return "SIGPIPE";
    case SIGALRM: return "SIGALRM";
    case SIGTERM: return "SIGTERM";
    case SIGUSR1: return "SIGUSR1";
    case SIGUSR2: return "SIGUSR2";
    case SIGCHLD: return "SIGCHLD";
    case SIGCONT: return "SIGCONT";
    /* SIGSTOP: cannot be trapped */
    // XXX POSIX.1-2001
    case SIGTSTP: return "SIGTSTP";
    case SIGTTIN: return "SIGTTIN";
    case SIGTTOU: return "SIGTTOU";
    case SIGBUS: return "SIGBUS";
    case SIGPOLL: return "SIGPOLL";
    case SIGPROF: return "SIGPROF";
    case SIGSYS: return "SIGSYS";
    case SIGTRAP: return "SIGTRAP";
    case SIGURG: return "SIGURG";
    case SIGVTALRM: return "SIGVTALRM";
    case SIGXCPU: return "SIGXCPU";
    case SIGXFSZ: return "SIGXFSZ";
    // XXX various other signals
#if defined(SIGPWR)
    case SIGPWR: return "SIGPWR";
#endif
#if defined(SIGWINCH)
    case SIGWINCH: return "SIGWINCH";
#endif
    default: break;
  }

  char buf[16];
  snprintf(buf, sizeof(buf), "<%d>", signo);
  return buf;
}

#if defined(XZERO_OS_LINUX) // {{{
class LinuxSignals : public UnixSignals {
 public:
  explicit LinuxSignals(Executor* executor);
  ~LinuxSignals();
  HandleRef executeOnSignal(int signo, SignalHandler task) override;
  void onSignal();

 private:
  Executor* executor_;
  Executor::HandleRef handle_;
  FileDescriptor fd_;
  sigset_t signalMask_;
  std::mutex mutex_;
  std::atomic<size_t> interests_;
  std::vector<std::list<RefPtr<SignalWatcher>>> watchers_;
};

LinuxSignals::LinuxSignals(Executor* executor)
    : executor_(executor),
      fd_(),
      signalMask_(),
      mutex_(),
      interests_(0),
      watchers_(128) {
  sigemptyset(&signalMask_);
}

LinuxSignals::~LinuxSignals() {
}

UnixSignals::HandleRef LinuxSignals::executeOnSignal(int signo,
                                                     SignalHandler task) {
  std::lock_guard<std::mutex> _l(mutex_);

  sigaddset(&signalMask_, signo);

  // on-demand create signalfd instance / update signalfd's mask
  if (fd_.isOpen()) {
    signalfd(fd_, &signalMask_, 0);
  } else {
    fd_ = signalfd(-1, &signalMask_, SFD_NONBLOCK | SFD_CLOEXEC);
    TRACE("executeOnSignal: signalfd=$0", fd_.get());
  }

  // block this signal also to avoid default disposition
  sigprocmask(SIG_BLOCK, &signalMask_, nullptr);

  TRACE("executeOnSignal: $0", toString(signo));
  RefPtr<SignalWatcher> hr(new SignalWatcher(task));
  watchers_[signo].emplace_back(hr);

  if (interests_.load() == 0) {
    handle_ = executor_->executeOnReadable(
        fd_,
        std::bind(&LinuxSignals::onSignal, this));
  }

  interests_++;

  return hr.as<Executor::Handle>();
}

void LinuxSignals::onSignal() {
  std::lock_guard<std::mutex> _l(mutex_);

  sigset_t clearMask;
  sigemptyset(&clearMask);

  signalfd_siginfo events[16];
  ssize_t n = 0;
  for (;;) {
    n = read(fd_, events, sizeof(events));
    if (n < 0) {
      if (errno == EINTR)
        continue;

      RAISE_ERRNO(errno);
    }
    break;
  }

  // move pending signals out of the watchers
  std::vector<RefPtr<SignalWatcher>> pending;
  n /= sizeof(*events);
  pending.reserve(n);
  {
    for (int i = 0; i < n; ++i) {
      const signalfd_siginfo& event = events[i];
      int signo = event.ssi_signo;
      std::list<RefPtr<SignalWatcher>>& watchers = watchers_[signo];

      logDebug("UnixSignals",
               "Caught signal $0 from PID $1 UID $2.",
               toString(signo),
               event.ssi_pid,
               event.ssi_uid);

      for (RefPtr<SignalWatcher>& watcher: watchers) {
        watcher->info.pid = event.ssi_pid;
        watcher->info.uid = event.ssi_uid;
      }

      sigdelset(&signalMask_, signo);
      interests_ -= watchers_[signo].size();
      pending.insert(pending.end(), watchers.begin(), watchers.end());
      watchers.clear();
    }

    // reregister for further signals, if anyone interested
    if (interests_.load() > 0) {
      executor_->executeOnReadable(
          fd_,
          std::bind(&LinuxSignals::onSignal, this));
    }
  }

  // update signal mask
  sigprocmask(SIG_BLOCK, &signalMask_, nullptr);
  signalfd(fd_, &signalMask_, 0);

  // notify interests (XXX must not be invoked on local stack)
  for (RefPtr<SignalWatcher>& hr: pending)
    executor_->execute(std::bind(&SignalWatcher::fire, hr));
}
#endif
// }}}
#if defined(XZERO_OS_DARWIN) // {{{
class KQueueSignals : public UnixSignals {
 public:
  explicit KQueueSignals(Executor* executor);
  ~KQueueSignals();
  HandleRef executeOnSignal(int signo, SignalHandler task) override;
  void onSignal();

 private:
  Executor* executor_;
  Executor::HandleRef handle_;
  FileDescriptor fd_;
  sigset_t oldSignalMask_;
  std::vector<std::list<RefPtr<SignalWatcher>>> watchers_;
  std::atomic<size_t> interests_;
  std::mutex mutex_;
};

KQueueSignals::KQueueSignals(Executor* executor)
    : executor_(executor),
      handle_(),
      fd_(kqueue()),
      oldSignalMask_(),
      watchers_(128),
      interests_(0),
      mutex_() {
  sigprocmask(SIG_SETMASK, nullptr, &oldSignalMask_);
}

KQueueSignals::~KQueueSignals() {
  if (handle_)
    handle_->cancel();

  // restore old signal mask
  sigprocmask(SIG_SETMASK, &oldSignalMask_, nullptr);
}

KQueueSignals::HandleRef KQueueSignals::executeOnSignal(int signo,
                                                        SignalHandler task) {
  std::lock_guard<std::mutex> _l(mutex_);

  // add event to kqueue
  if (watchers_[signo].empty()) {
    struct kevent ke;
    EV_SET(&ke, signo, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT,
           0 /* fflags */,
           0 /* data */,
           nullptr /* udata */);
    int rv = kevent(fd_, &ke, 1, nullptr, 0, nullptr);
    if (rv < 0) {
      RAISE_ERRNO(errno);
    }

    blockSignal(signo);
  }

  RefPtr<SignalWatcher> hr(new SignalWatcher(task));
  watchers_[signo].emplace_back(hr);

  if (interests_.load() == 0) {
    handle_ = executor_->executeOnReadable(
        fd_,
        std::bind(&KQueueSignals::onSignal, this));
  }

  interests_++;

  return hr.as<Executor::Handle>();
}

void KQueueSignals::onSignal() {
  // collect pending signals
  timespec timeout;
  timeout.tv_sec = 0;
  timeout.tv_nsec = 0;
  struct kevent events[16];

  int rv = 0;
  for (;;) {
    rv = kevent(fd_, nullptr, 0, events, 128, &timeout);
    if (rv < 0) {
      if (errno == EINTR) {
        continue;
      }
      RAISE_ERRNO(errno);
    }
    break;
  }

  std::vector<RefPtr<SignalWatcher>> pending;
  pending.reserve(rv);
  {
    // move pending signals out of the watchers
    std::lock_guard<std::mutex> _l(mutex_);
    for (int i = 0; i < rv; ++i) {
      int signo = events[i].ident;
      std::list<RefPtr<SignalWatcher>>& watchers = watchers_[signo];

      logDebug("UnixSignals", "Caught signal $0.", toString(signo));

      pending.insert(pending.end(), watchers.begin(), watchers.end());
      interests_ -= watchers_[signo].size();
      watchers.clear();
    }

    // reregister for further signals, if anyone interested
    if (interests_.load() > 0) {
      handle_ = executor_->executeOnReadable(
          fd_,
          std::bind(&KQueueSignals::onSignal, this));
    }
  }

  // notify interests
  for (RefPtr<SignalWatcher>& hr: pending)
    executor_->execute(std::bind(&SignalWatcher::fire, hr));
}
#endif
// }}}

std::unique_ptr<UnixSignals> UnixSignals::create(Executor* executor) {
#if defined(XZERO_OS_LINUX)
  return std::unique_ptr<UnixSignals>(new LinuxSignals(executor));
#elif defined(XZERO_OS_DARWIN)
  return std::unique_ptr<UnixSignals>(new KQueueSignals(executor));
#else
#error "Unsupported platform."
#endif
}

void UnixSignals::blockSignal(int signo) {
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, signo);
  int rv = sigprocmask(SIG_BLOCK, &sigset, nullptr);
  if (rv < 0)
    RAISE_ERRNO(errno);
}

void UnixSignals::unblockSignal(int signo) {
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, signo);
  int rv = sigprocmask(SIG_UNBLOCK, &sigset, nullptr);
  if (rv < 0)
    RAISE_ERRNO(errno);
}

} // namespace xzero
<commit_msg>UnixSignals: make use of new Executor API's reference counting in order to passivily watch on unix signals without blocking the main event loop.<commit_after>// This file is part of the "x0" project
//   (c) 2009-2015 Christian Parpart <https://github.com/christianparpart>
//
// x0 is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include <xzero/UnixSignals.h>
#include <xzero/UnixSignalInfo.h>
#include <xzero/executor/Executor.h>
#include <xzero/io/FileDescriptor.h>
#include <xzero/RuntimeError.h>
#include <xzero/Duration.h>
#include <xzero/logging.h>
#include <memory>
#include <mutex>
#include <atomic>
#include <vector>
#include <list>
#include <signal.h>

#if defined(XZERO_OS_LINUX)
#include <sys/signalfd.h>
#include <unistd.h>
#endif

#if defined(XZERO_OS_DARWIN)
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#endif

namespace xzero {

#if !defined(NDEBUG)
#define TRACE(msg...) logTrace("UnixSignals", msg)
#else
#define TRACE(msg...) do {} while (0)
#endif

class SignalWatcher : public Executor::Handle {
 public:
  typedef Executor::Task Task;

  explicit SignalWatcher(UnixSignals::SignalHandler action)
      : action_(action) {};

  void fire() {
    Executor::Handle::fire(std::bind(action_, info));
  }

  UnixSignalInfo info;

 private:
  UnixSignals::SignalHandler action_;
};

std::string UnixSignals::toString(int signo) {
  switch (signo) {
    // XXX POSIX.1-1990
    case SIGHUP: return "SIGHUP";
    case SIGINT: return "SIGINT";
    case SIGQUIT: return "SIGQUIT";
    case SIGILL: return "SIGILL";
    case SIGABRT: return "SIGABRT";
    case SIGFPE: return "SIGFPE";
    /* SIGKILL: cannot be trapped */
    case SIGSEGV: return "SIGSEGV";
    case SIGPIPE: return "SIGPIPE";
    case SIGALRM: return "SIGALRM";
    case SIGTERM: return "SIGTERM";
    case SIGUSR1: return "SIGUSR1";
    case SIGUSR2: return "SIGUSR2";
    case SIGCHLD: return "SIGCHLD";
    case SIGCONT: return "SIGCONT";
    /* SIGSTOP: cannot be trapped */
    // XXX POSIX.1-2001
    case SIGTSTP: return "SIGTSTP";
    case SIGTTIN: return "SIGTTIN";
    case SIGTTOU: return "SIGTTOU";
    case SIGBUS: return "SIGBUS";
    case SIGPOLL: return "SIGPOLL";
    case SIGPROF: return "SIGPROF";
    case SIGSYS: return "SIGSYS";
    case SIGTRAP: return "SIGTRAP";
    case SIGURG: return "SIGURG";
    case SIGVTALRM: return "SIGVTALRM";
    case SIGXCPU: return "SIGXCPU";
    case SIGXFSZ: return "SIGXFSZ";
    // XXX various other signals
#if defined(SIGPWR)
    case SIGPWR: return "SIGPWR";
#endif
#if defined(SIGWINCH)
    case SIGWINCH: return "SIGWINCH";
#endif
    default: break;
  }

  char buf[16];
  snprintf(buf, sizeof(buf), "<%d>", signo);
  return buf;
}

#if defined(XZERO_OS_LINUX) // {{{
class LinuxSignals : public UnixSignals {
 public:
  explicit LinuxSignals(Executor* executor);
  ~LinuxSignals();
  HandleRef executeOnSignal(int signo, SignalHandler task) override;
  void onSignal();

 private:
  Executor* executor_;
  FileDescriptor fd_;
  sigset_t signalMask_;
  std::mutex mutex_;
  std::atomic<size_t> interests_;
  std::vector<std::list<RefPtr<SignalWatcher>>> watchers_;
};

LinuxSignals::LinuxSignals(Executor* executor)
    : executor_(executor),
      fd_(),
      signalMask_(),
      mutex_(),
      interests_(0),
      watchers_(128) {
  sigemptyset(&signalMask_);
}

LinuxSignals::~LinuxSignals() {
}

UnixSignals::HandleRef LinuxSignals::executeOnSignal(int signo,
                                                     SignalHandler task) {
  std::lock_guard<std::mutex> _l(mutex_);

  sigaddset(&signalMask_, signo);

  // on-demand create signalfd instance / update signalfd's mask
  if (fd_.isOpen()) {
    signalfd(fd_, &signalMask_, 0);
  } else {
    fd_ = signalfd(-1, &signalMask_, SFD_NONBLOCK | SFD_CLOEXEC);
    TRACE("executeOnSignal: signalfd=$0", fd_.get());
  }

  // block this signal also to avoid default disposition
  sigprocmask(SIG_BLOCK, &signalMask_, nullptr);

  TRACE("executeOnSignal: $0", toString(signo));
  RefPtr<SignalWatcher> hr(new SignalWatcher(task));
  watchers_[signo].emplace_back(hr);

  if (interests_.load() == 0) {
    executor_->executeOnReadable(fd_, std::bind(&LinuxSignals::onSignal, this));
    executor_->unref();
  }

  interests_++;

  return hr.as<Executor::Handle>();
}

void LinuxSignals::onSignal() {
  std::lock_guard<std::mutex> _l(mutex_);
  executor_->ref();

  sigset_t clearMask;
  sigemptyset(&clearMask);

  signalfd_siginfo events[16];
  ssize_t n = 0;
  for (;;) {
    n = read(fd_, events, sizeof(events));
    if (n < 0) {
      if (errno == EINTR)
        continue;

      RAISE_ERRNO(errno);
    }
    break;
  }

  // move pending signals out of the watchers
  std::vector<RefPtr<SignalWatcher>> pending;
  n /= sizeof(*events);
  pending.reserve(n);
  {
    for (int i = 0; i < n; ++i) {
      const signalfd_siginfo& event = events[i];
      int signo = event.ssi_signo;
      std::list<RefPtr<SignalWatcher>>& watchers = watchers_[signo];

      logDebug("UnixSignals",
               "Caught signal $0 from PID $1 UID $2.",
               toString(signo),
               event.ssi_pid,
               event.ssi_uid);

      for (RefPtr<SignalWatcher>& watcher: watchers) {
        watcher->info.pid = event.ssi_pid;
        watcher->info.uid = event.ssi_uid;
      }

      sigdelset(&signalMask_, signo);
      interests_ -= watchers_[signo].size();
      pending.insert(pending.end(), watchers.begin(), watchers.end());
      watchers.clear();
    }

    // reregister for further signals, if anyone interested
    if (interests_.load() > 0) {
      executor_->executeOnReadable(fd_, std::bind(&LinuxSignals::onSignal, this));
      executor_->unref();
    }
  }

  // update signal mask
  sigprocmask(SIG_BLOCK, &signalMask_, nullptr);
  signalfd(fd_, &signalMask_, 0);

  // notify interests (XXX must not be invoked on local stack)
  for (RefPtr<SignalWatcher>& hr: pending)
    executor_->execute(std::bind(&SignalWatcher::fire, hr));
}
#endif
// }}}
#if defined(XZERO_OS_DARWIN) // {{{
class KQueueSignals : public UnixSignals {
 public:
  explicit KQueueSignals(Executor* executor);
  ~KQueueSignals();
  HandleRef executeOnSignal(int signo, SignalHandler task) override;
  void onSignal();

 private:
  Executor* executor_;
  FileDescriptor fd_;
  sigset_t oldSignalMask_;
  std::vector<std::list<RefPtr<SignalWatcher>>> watchers_;
  std::atomic<size_t> interests_;
  std::mutex mutex_;
};

KQueueSignals::KQueueSignals(Executor* executor)
    : executor_(executor),
      fd_(kqueue()),
      oldSignalMask_(),
      watchers_(128),
      interests_(0),
      mutex_() {
  sigprocmask(SIG_SETMASK, nullptr, &oldSignalMask_);
}

KQueueSignals::~KQueueSignals() {
  // restore old signal mask
  sigprocmask(SIG_SETMASK, &oldSignalMask_, nullptr);
}

KQueueSignals::HandleRef KQueueSignals::executeOnSignal(int signo,
                                                        SignalHandler task) {
  std::lock_guard<std::mutex> _l(mutex_);

  // add event to kqueue
  if (watchers_[signo].empty()) {
    struct kevent ke;
    EV_SET(&ke, signo, EVFILT_SIGNAL, EV_ADD | EV_ONESHOT,
           0 /* fflags */,
           0 /* data */,
           nullptr /* udata */);
    int rv = kevent(fd_, &ke, 1, nullptr, 0, nullptr);
    if (rv < 0) {
      RAISE_ERRNO(errno);
    }

    blockSignal(signo);
  }

  RefPtr<SignalWatcher> hr(new SignalWatcher(task));
  watchers_[signo].emplace_back(hr);

  if (interests_.load() == 0) {
    executor_->executeOnReadable(fd_, std::bind(&KQueueSignals::onSignal, this));
    executor_->unref();
  }

  interests_++;

  return hr.as<Executor::Handle>();
}

void KQueueSignals::onSignal() {
  executor_->ref();

  // collect pending signals
  timespec timeout;
  timeout.tv_sec = 0;
  timeout.tv_nsec = 0;
  struct kevent events[16];

  int rv = 0;
  for (;;) {
    rv = kevent(fd_, nullptr, 0, events, 128, &timeout);
    if (rv < 0) {
      if (errno == EINTR) {
        continue;
      }
      RAISE_ERRNO(errno);
    }
    break;
  }

  std::vector<RefPtr<SignalWatcher>> pending;
  pending.reserve(rv);
  {
    // move pending signals out of the watchers
    std::lock_guard<std::mutex> _l(mutex_);
    for (int i = 0; i < rv; ++i) {
      int signo = events[i].ident;
      std::list<RefPtr<SignalWatcher>>& watchers = watchers_[signo];

      logDebug("UnixSignals", "Caught signal $0.", toString(signo));

      interests_ -= watchers_[signo].size();
      pending.insert(pending.end(), watchers.begin(), watchers.end());
      watchers.clear();
    }

    // reregister for further signals, if anyone interested
    if (interests_.load() > 0) {
      executor_->executeOnReadable(fd_, std::bind(&KQueueSignals::onSignal, this));
      executor_->unref();
    }
  }

  // notify interests
  for (RefPtr<SignalWatcher>& hr: pending)
    executor_->execute(std::bind(&SignalWatcher::fire, hr));
}
#endif
// }}}

std::unique_ptr<UnixSignals> UnixSignals::create(Executor* executor) {
#if defined(XZERO_OS_LINUX)
  return std::unique_ptr<UnixSignals>(new LinuxSignals(executor));
#elif defined(XZERO_OS_DARWIN)
  return std::unique_ptr<UnixSignals>(new KQueueSignals(executor));
#else
#error "Unsupported platform."
#endif
}

void UnixSignals::blockSignal(int signo) {
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, signo);
  int rv = sigprocmask(SIG_BLOCK, &sigset, nullptr);
  if (rv < 0)
    RAISE_ERRNO(errno);
}

void UnixSignals::unblockSignal(int signo) {
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, signo);
  int rv = sigprocmask(SIG_UNBLOCK, &sigset, nullptr);
  if (rv < 0)
    RAISE_ERRNO(errno);
}

} // namespace xzero
<|endoftext|>


<commit_before>#include <cstdint>
#include <iostream>

template <typename T> requires std::integral<T> T succ(const T from) {
  return from + static_cast<T>(1);
}

int main(int argc, char *argv[]) {
  constexpr uint16_t value = 1;
  std::cout << succ(value) << "\n";
  std::cout << succ(static_cast<long long>(2)) << "\n";
  int32_t n = 3;
  std::cout << succ(n) << "\n";
  return 0;
}

/*
Local Variables:
mode: c++
coding: utf-8-dos
tab-width: nil
c-file-style: "stroustrup"
Last:
*/
<commit_msg>Compare Rust code with C++ code<commit_after>#include <cstdint>
#include <iostream>

template <typename T> requires std::integral<T> T succ(T x) {
  return x + static_cast<T>(1);
}

int main(int argc, char *argv[]) {
  constexpr uint16_t value = 1;
  std::cout << succ(value) << "\n";
  std::cout << succ(static_cast<long long>(2)) << "\n";
  int32_t n = 3;
  std::cout << succ(n) << "\n";
  return 0;
}

/*
Local Variables:
mode: c++
coding: utf-8-dos
tab-width: nil
c-file-style: "stroustrup"
Last:
*/
<|endoftext|>