<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Andreas Streichardt
////////////////////////////////////////////////////////////////////////////////

#include "Scheduler/AcceptorTcp.h"
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Endpoint/EndpointIp.h"
#include "Scheduler/SocketTcp.h"

using namespace arangodb;

void AcceptorTcp::open() {
  boost::asio::ip::tcp::resolver resolver(_ioService);

  std::string hostname = _endpoint->host();
  int portNumber = _endpoint->port();

  boost::asio::ip::tcp::endpoint asioEndpoint;
  boost::system::error_code err;
  auto address = boost::asio::ip::address::from_string(hostname,err);
  if (!err) {
    asioEndpoint = boost::asio::ip::tcp::endpoint(address,portNumber);
  } else { // we need to resolve the string containing the ip
    std::unique_ptr<boost::asio::ip::tcp::resolver::query> query;
    if (_endpoint->domain() == AF_INET6) {
      query.reset(new boost::asio::ip::tcp::resolver::query(boost::asio::ip::tcp::v6(), hostname, std::to_string(portNumber)));
    } else if (_endpoint->domain() == AF_INET) {
      query.reset(new boost::asio::ip::tcp::resolver::query(boost::asio::ip::tcp::v4(), hostname, std::to_string(portNumber)));
    } else {
      THROW_ARANGO_EXCEPTION(TRI_ERROR_IP_ADDRESS_INVALID);
    }

    boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(*query, err);
    if (err) {
      LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to to resolve endpoint: " << err.message();
      throw std::runtime_error(err.message());
    }

    if (boost::asio::ip::tcp::resolver::iterator{} == iter) {
      LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to to resolve endpoint: endpoint is default constructed";
    }

    asioEndpoint = iter->endpoint(); // function not documented in boost?!
  }
  _acceptor.open(asioEndpoint.protocol());

  _acceptor.set_option(
      boost::asio::ip::tcp::acceptor::reuse_address(
        ((EndpointIp*)_endpoint)->reuseAddress()));

#if 0
#ifdef _WIN32
  // on Windows everything is different of course:
  // we need to set SO_EXCLUSIVEADDRUSE to prevent others from binding to our
  // ip/port.
  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx
  int trueOption = 1;

  if (::setsockopt(_acceptor.native(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char const*) &trueOption, sizeof(int)) != 0) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to set acceptor socket option: " << WSAGetLastError();
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_FAILED, "unable to set acceptor socket option");
  }
#endif
#endif

  _acceptor.bind(asioEndpoint, err);
  if (err) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to bind endpoint: " << err.message();
    throw std::runtime_error(err.message());
  }
  _acceptor.listen(_endpoint->listenBacklog(), err);
  if (err) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to bind endpoint: " << err.message();
    throw std::runtime_error(err.message());
  }
}

void AcceptorTcp::asyncAccept(AcceptHandler const& handler) {
  createPeer();
  auto peer = dynamic_cast<SocketTcp*>(_peer.get());
  if (peer == nullptr) {
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected socket type");
  }
  _acceptor.async_accept(peer->_socket, peer->_peerEndpoint, handler);
}

void AcceptorTcp::createPeer() {
  if (_endpoint->encryption() == Endpoint::EncryptionType::SSL) {
    _peer.reset(new SocketTcp(_ioService, SslServerFeature::SSL->createSslContext(), true));
  } else {
    _peer.reset(new SocketTcp(
        _ioService,
        boost::asio::ssl::context(boost::asio::ssl::context::method::sslv23),
        false));
  }
}
<commit_msg>fix multiple binds to the same ip/port on Windows (#3734)<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Andreas Streichardt
////////////////////////////////////////////////////////////////////////////////

#include "Scheduler/AcceptorTcp.h"
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Endpoint/EndpointIp.h"
#include "Scheduler/SocketTcp.h"

using namespace arangodb;

void AcceptorTcp::open() {
  boost::asio::ip::tcp::resolver resolver(_ioService);

  std::string hostname = _endpoint->host();
  int portNumber = _endpoint->port();

  boost::asio::ip::tcp::endpoint asioEndpoint;
  boost::system::error_code err;
  auto address = boost::asio::ip::address::from_string(hostname,err);
  if (!err) {
    asioEndpoint = boost::asio::ip::tcp::endpoint(address,portNumber);
  } else { // we need to resolve the string containing the ip
    std::unique_ptr<boost::asio::ip::tcp::resolver::query> query;
    if (_endpoint->domain() == AF_INET6) {
      query.reset(new boost::asio::ip::tcp::resolver::query(boost::asio::ip::tcp::v6(), hostname, std::to_string(portNumber)));
    } else if (_endpoint->domain() == AF_INET) {
      query.reset(new boost::asio::ip::tcp::resolver::query(boost::asio::ip::tcp::v4(), hostname, std::to_string(portNumber)));
    } else {
      THROW_ARANGO_EXCEPTION(TRI_ERROR_IP_ADDRESS_INVALID);
    }

    boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(*query, err);
    if (err) {
      LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to to resolve endpoint: " << err.message();
      throw std::runtime_error(err.message());
    }

    if (boost::asio::ip::tcp::resolver::iterator{} == iter) {
      LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to to resolve endpoint: endpoint is default constructed";
    }

    asioEndpoint = iter->endpoint(); // function not documented in boost?!
  }
  _acceptor.open(asioEndpoint.protocol());

#ifdef _WIN32
  // on Windows everything is different of course:
  // we need to set SO_EXCLUSIVEADDRUSE to prevent others from binding to our
  // ip/port.
  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx
  BOOL trueOption = 1;

  if (::setsockopt(_acceptor.native(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char const*) &trueOption, sizeof(BOOL)) != 0) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to set acceptor socket option: " << WSAGetLastError();
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_FAILED, "unable to set acceptor socket option");
  }
#else
  _acceptor.set_option(
      boost::asio::ip::tcp::acceptor::reuse_address(
        ((EndpointIp*)_endpoint)->reuseAddress()));

#endif

  _acceptor.bind(asioEndpoint, err);
  if (err) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to bind endpoint: " << err.message();
    throw std::runtime_error(err.message());
  }
  _acceptor.listen(_endpoint->listenBacklog(), err);
  if (err) {
    LOG_TOPIC(ERR, Logger::COMMUNICATION) << "unable to bind endpoint: " << err.message();
    throw std::runtime_error(err.message());
  }
}

void AcceptorTcp::asyncAccept(AcceptHandler const& handler) {
  createPeer();
  auto peer = dynamic_cast<SocketTcp*>(_peer.get());
  if (peer == nullptr) {
    THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected socket type");
  }
  _acceptor.async_accept(peer->_socket, peer->_peerEndpoint, handler);
}

void AcceptorTcp::createPeer() {
  if (_endpoint->encryption() == Endpoint::EncryptionType::SSL) {
    _peer.reset(new SocketTcp(_ioService, SslServerFeature::SSL->createSslContext(), true));
  } else {
    _peer.reset(new SocketTcp(
        _ioService,
        boost::asio::ssl::context(boost::asio::ssl::context::method::sslv23),
        false));
  }
}
<|endoftext|>


<commit_before>#include "serprog.hpp"

#include <bitset>

static const char NAME[16] = "serprog-due";

template<typename I>
inline bool read(Stream& s, I& i, unsigned n = sizeof(I))
{
  return (s.readBytes(reinterpret_cast<char*>(&i), n) == n);
}

template<typename I>
inline void write(Print& p, I i)
{
  p.write(reinterpret_cast<char*>(&i), sizeof(I));
}

void serprog::ack()
{
  out.write(0x06);
}

void serprog::nak()
{
  out.write(0x15);
}

void serprog::version()
{
  ack();
  write(out, short(1));
}

void serprog::map()
{
  ack();
  std::bitset<32> bits;
  for(auto& cmd : cmds)
  {
    int i = ((&cmd - cmds) % bits.size());
    bits.set(i, cmd);
    if(i == (bits.size() - 1))
      write(out, bits.to_ulong());
  }
}

void serprog::name()
{
  ack();
  out.write(NAME, sizeof(NAME));
}

void serprog::size()
{
  ack();
  write(out, short(256));
}

void serprog::gbus()
{
  ack();
  out.write(8);
}

void serprog::sync()
{
  nak();
  ack();
}

void serprog::sbus()
{
  char bus;
  if(read(in, bus) && (bus == 8))
    ack();
  else
    nak();
}

void serprog::op()
{
  unsigned slen = 0;
  if(!read(in, slen, 3))
    return nak();

  unsigned rlen = 0;
  if(!read(in, rlen, 3))
    return nak();

  SPI.beginTransaction(cfg);
  digitalWrite(52, LOW);

  while(slen--)
  {
    char c;
    if(read(in, c))
      SPI.transfer(c);
    else
      return nak();
  }

  ack();

  while(rlen--)
    out.write(SPI.transfer(0));

  digitalWrite(52, HIGH);
  SPI.endTransaction();
}

void serprog::freq()
{
  unsigned freq;
  if(read(in, freq) && freq)
  {
    freq = constrain(freq, 4e6, F_CPU);
    cfg = {freq, MSBFIRST, SPI_MODE0};

    ack();
    write(out, freq);
  }
  else
    nak();
}

void serprog::loop()
{
  if(in.available())
  {
    char op = in.read();
    if(cmds[op])
      (this->*cmds[op])();
    else
      nak();
  }
}
<commit_msg>Use stdint<commit_after>#include "serprog.hpp"

#include <stddef.h>
#include <stdint.h>

static const char NAME[16] = "serprog-due";

template<typename I>
inline bool read(Stream& s, I& i, size_t n = sizeof(I))
{
  return (s.readBytes(reinterpret_cast<char*>(&i), n) == n);
}

template<typename I>
inline void write(Print& p, I i)
{
  p.write(reinterpret_cast<char*>(&i), sizeof(I));
}

void serprog::ack()
{
  out.write(0x06);
}

void serprog::nak()
{
  out.write(0x15);
}

void serprog::version()
{
  ack();
  write(out, uint16_t(1));
}

void serprog::map()
{
  ack();
  uint32_t bits = 0;
  for(auto& cmd : cmds)
  {
    int i = ((&cmd - cmds) & 31);
    bitWrite(bits, i, cmd);
    if(i == 31)
      write(out, bits);
  }
}

void serprog::name()
{
  ack();
  out.write(NAME, sizeof(NAME));
}

void serprog::size()
{
  ack();
  write(out, uint16_t(256));
}

void serprog::gbus()
{
  ack();
  out.write(8);
}

void serprog::sync()
{
  nak();
  ack();
}

void serprog::sbus()
{
  char bus;
  if(read(in, bus) && (bus == 8))
    ack();
  else
    nak();
}

void serprog::op()
{
  uint32_t slen = 0;
  if(!read(in, slen, 3))
    return nak();

  uint32_t rlen = 0;
  if(!read(in, rlen, 3))
    return nak();

  SPI.beginTransaction(cfg);
  digitalWrite(52, LOW);

  while(slen--)
  {
    char c;
    if(read(in, c))
      SPI.transfer(c);
    else
      return nak();
  }

  ack();

  while(rlen--)
    out.write(SPI.transfer(0));

  digitalWrite(52, HIGH);
  SPI.endTransaction();
}

void serprog::freq()
{
  uint32_t freq;
  if(read(in, freq) && freq)
  {
    freq = constrain(freq, 4e6, F_CPU);
    cfg = {freq, MSBFIRST, SPI_MODE0};

    ack();
    write(out, freq);
  }
  else
    nak();
}

void serprog::loop()
{
  if(in.available())
  {
    char op = in.read();
    if(cmds[op])
      (this->*cmds[op])();
    else
      nak();
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stddef.h>
#include <stdint.h>
#include <unistd.h>

#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
#include "perfetto/base/utils.h"
#include "perfetto/ipc/host.h"
#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/producer.h"
#include "perfetto/tracing/core/trace_writer.h"
#include "perfetto/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/ipc/service_ipc_host.h"
#include "src/base/test/test_task_runner.h"
#include "test/fake_consumer.h"
#include "test/task_runner_thread.h"

#define PRODUCER_SOCKET "/tmp/perfetto-producer"
#define CONSUMER_SOCKET "/tmp/perfetto-consumer"

namespace perfetto {
namespace shm_fuzz {

// Fake producer writing a protozero message of data into shared memory
// buffer, followed by a sentinel message to signal completion to the
// consumer.
class FakeProducer : public Producer {
 public:
  FakeProducer(std::string name, const uint8_t* data, size_t size)
      : name_(std::move(name)), data_(data), size_(size) {}

  void Connect(const char* socket_name, base::TaskRunner* task_runner) {
    endpoint_ = ProducerIPCClient::Connect(socket_name, this, task_runner);
  }

  void OnConnect() override {
    DataSourceDescriptor descriptor;
    descriptor.set_name(name_);
    endpoint_->RegisterDataSource(descriptor,
                                  [this](DataSourceID id) { id_ = id; });
  }

  void OnDisconnect() override {}

  void CreateDataSourceInstance(
      DataSourceInstanceID,
      const DataSourceConfig& source_config) override {
    auto trace_writer = endpoint_->CreateTraceWriter(
        static_cast<BufferID>(source_config.target_buffer()));

    auto packet = trace_writer->NewTracePacket();
    packet->stream_writer_->WriteBytes(data_, size_);
    packet->Finalize();

    auto end_packet = trace_writer->NewTracePacket();
    end_packet->set_test("end");
    end_packet->Finalize();

    // Temporarily create a new packet to flush the final packet to the
    // consumer.
    // TODO(primiano): remove this hack once flushing the final packet is fixed.
    trace_writer->NewTracePacket();
  }

  void TearDownDataSourceInstance(DataSourceInstanceID) override {}

 private:
  const std::string name_;
  const uint8_t* data_;
  const size_t size_;
  DataSourceID id_ = 0;
  std::unique_ptr<Service::ProducerEndpoint> endpoint_;
};

class FakeProducerDelegate : public ThreadDelegate {
 public:
  FakeProducerDelegate(const uint8_t* data, size_t size)
      : data_(data), size_(size) {}
  ~FakeProducerDelegate() override = default;

  void Initialize(base::TaskRunner* task_runner) override {
    producer_.reset(
        new FakeProducer("android.perfetto.FakeProducer", data_, size_));
    producer_->Connect(PRODUCER_SOCKET, task_runner);
  }

 private:
  std::unique_ptr<FakeProducer> producer_;
  const uint8_t* data_;
  const size_t size_;
};

class ServiceDelegate : public ThreadDelegate {
 public:
  ServiceDelegate() = default;
  ~ServiceDelegate() override = default;
  void Initialize(base::TaskRunner* task_runner) override {
    svc_ = ServiceIPCHost::CreateInstance(task_runner);
    unlink(PRODUCER_SOCKET);
    unlink(CONSUMER_SOCKET);
    svc_->Start(PRODUCER_SOCKET, CONSUMER_SOCKET);
  }

 private:
  std::unique_ptr<ServiceIPCHost> svc_;
  base::ScopedFile producer_fd_;
  base::ScopedFile consumer_fd_;
};

int FuzzSharedMemory(const uint8_t* data, size_t size);

int FuzzSharedMemory(const uint8_t* data, size_t size) {
  TaskRunnerThread service_thread;
  service_thread.Start(std::unique_ptr<ServiceDelegate>(new ServiceDelegate()));

  TaskRunnerThread producer_thread;
  producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
      new FakeProducerDelegate(data, size)));

  // Setup the TraceConfig for the consumer.
  TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(4096 * 10);
  trace_config.set_duration_ms(200);

  // Create the buffer for ftrace.
  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("android.perfetto.FakeProducer");
  ds_config->set_target_buffer(0);

  base::TestTaskRunner task_runner;
  auto finish = task_runner.CreateCheckpoint("no.more.packets");
  // Wait for sentinel message from Producer, then signal no.more.packets.
  auto function = [&finish](std::vector<TracePacket> packets, bool has_more) {
    for (auto& p : packets) {
      p.Decode();
      if (p->test() == "end")
        finish();
    }
  };
  FakeConsumer consumer(trace_config, std::move(function), &task_runner);
  consumer.Connect(CONSUMER_SOCKET);
  task_runner.RunUntilCheckpoint("no.more.packets");
  return 0;
}

}  // namespace shm_fuzz
}  // namespace perfetto

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
}
<commit_msg>Change trace config to make fuzzer faster.<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stddef.h>
#include <stdint.h>
#include <unistd.h>

#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
#include "perfetto/base/utils.h"
#include "perfetto/ipc/host.h"
#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/producer.h"
#include "perfetto/tracing/core/trace_writer.h"
#include "perfetto/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/ipc/service_ipc_host.h"
#include "src/base/test/test_task_runner.h"
#include "test/fake_consumer.h"
#include "test/task_runner_thread.h"

#define PRODUCER_SOCKET "/tmp/perfetto-producer"
#define CONSUMER_SOCKET "/tmp/perfetto-consumer"

namespace perfetto {
namespace shm_fuzz {

// Fake producer writing a protozero message of data into shared memory
// buffer, followed by a sentinel message to signal completion to the
// consumer.
class FakeProducer : public Producer {
 public:
  FakeProducer(std::string name, const uint8_t* data, size_t size)
      : name_(std::move(name)), data_(data), size_(size) {}

  void Connect(const char* socket_name, base::TaskRunner* task_runner) {
    endpoint_ = ProducerIPCClient::Connect(socket_name, this, task_runner);
  }

  void OnConnect() override {
    DataSourceDescriptor descriptor;
    descriptor.set_name(name_);
    endpoint_->RegisterDataSource(descriptor,
                                  [this](DataSourceID id) { id_ = id; });
  }

  void OnDisconnect() override {}

  void CreateDataSourceInstance(
      DataSourceInstanceID,
      const DataSourceConfig& source_config) override {
    auto trace_writer = endpoint_->CreateTraceWriter(
        static_cast<BufferID>(source_config.target_buffer()));

    auto packet = trace_writer->NewTracePacket();
    packet->stream_writer_->WriteBytes(data_, size_);
    packet->Finalize();

    auto end_packet = trace_writer->NewTracePacket();
    end_packet->set_test("end");
    end_packet->Finalize();

    // Temporarily create a new packet to flush the final packet to the
    // consumer.
    // TODO(primiano): remove this hack once flushing the final packet is fixed.
    trace_writer->NewTracePacket();
  }

  void TearDownDataSourceInstance(DataSourceInstanceID) override {}

 private:
  const std::string name_;
  const uint8_t* data_;
  const size_t size_;
  DataSourceID id_ = 0;
  std::unique_ptr<Service::ProducerEndpoint> endpoint_;
};

class FakeProducerDelegate : public ThreadDelegate {
 public:
  FakeProducerDelegate(const uint8_t* data, size_t size)
      : data_(data), size_(size) {}
  ~FakeProducerDelegate() override = default;

  void Initialize(base::TaskRunner* task_runner) override {
    producer_.reset(
        new FakeProducer("android.perfetto.FakeProducer", data_, size_));
    producer_->Connect(PRODUCER_SOCKET, task_runner);
  }

 private:
  std::unique_ptr<FakeProducer> producer_;
  const uint8_t* data_;
  const size_t size_;
};

class ServiceDelegate : public ThreadDelegate {
 public:
  ServiceDelegate() = default;
  ~ServiceDelegate() override = default;
  void Initialize(base::TaskRunner* task_runner) override {
    svc_ = ServiceIPCHost::CreateInstance(task_runner);
    unlink(PRODUCER_SOCKET);
    unlink(CONSUMER_SOCKET);
    svc_->Start(PRODUCER_SOCKET, CONSUMER_SOCKET);
  }

 private:
  std::unique_ptr<ServiceIPCHost> svc_;
  base::ScopedFile producer_fd_;
  base::ScopedFile consumer_fd_;
};

int FuzzSharedMemory(const uint8_t* data, size_t size);

int FuzzSharedMemory(const uint8_t* data, size_t size) {
  TaskRunnerThread service_thread;
  service_thread.Start(std::unique_ptr<ServiceDelegate>(new ServiceDelegate()));

  TaskRunnerThread producer_thread;
  producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
      new FakeProducerDelegate(data, size)));

  // Setup the TraceConfig for the consumer.
  TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(4);
  trace_config.set_duration_ms(10);

  // Create the buffer for ftrace.
  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("android.perfetto.FakeProducer");
  ds_config->set_target_buffer(0);

  base::TestTaskRunner task_runner;
  auto finish = task_runner.CreateCheckpoint("no.more.packets");
  // Wait for sentinel message from Producer, then signal no.more.packets.
  auto function = [&finish](std::vector<TracePacket> packets, bool has_more) {
    for (auto& p : packets) {
      p.Decode();
      if (p->test() == "end")
        finish();
    }
  };
  FakeConsumer consumer(trace_config, std::move(function), &task_runner);
  consumer.Connect(CONSUMER_SOCKET);
  task_runner.RunUntilCheckpoint("no.more.packets");
  return 0;
}

}  // namespace shm_fuzz
}  // namespace perfetto

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
}
<|endoftext|>


<commit_before>/*******************************************************************************

 Module:       FGCoefficient.cpp
 Author:       Jon S. Berndt
 Date started: 12/28/98
 Purpose:      Encapsulates the stability derivative class FGCoefficient;
 Called by:    FGAircraft

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

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

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class models the stability derivative coefficient lookup tables or
equations. Note that the coefficients need not be calculated each delta-t.

Note that the values in a row which index into the table must be the same value
for each column of data, so the first column of numbers for each altitude are
seen to be equal, and there are the same number of values for each altitude.

See the header file FGCoefficient.h for the values of the identifiers.

HISTORY
--------------------------------------------------------------------------------
12/28/98   JSB   Created

********************************************************************************
INCLUDES
*******************************************************************************/

#include "FGCoefficient.h"
#include "FGState.h"
#include "FGFDMExec.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
{
  int r, c, start, end, n;
  float ftrashcan;
  string multparms;

  FDMExec     = fdex;
  State       = FDMExec->GetState();

  if (AC_cfg) {
    name = AC_cfg->GetValue("NAME");
    method = AC_cfg->GetValue("TYPE");

    AC_cfg->GetNextConfigLine();
    *AC_cfg >> description;

    cout << "   " << name << endl;
    cout << "   " << description << endl;
    cout << "   " << method << endl;

    if      (method == "EQUATION") type = EQUATION;
    else if (method == "TABLE")    type = TABLE;
    else if (method == "VECTOR")   type = VECTOR;
    else if (method == "VALUE")    type = VALUE;
    else                           type = UNKNOWN;

    if (type == VECTOR || type == TABLE) {
      *AC_cfg >> rows;
      cout << "   Rows: " << rows << " ";
      if (type == TABLE) {
        *AC_cfg >> columns;
        cout << "Cols: " << columns;
      }

      cout << endl;

      *AC_cfg >> multparms;
      LookupR = State->GetParameterIndex(multparms);
      cout << "   Row indexing parameter: " << multparms << endl;
    }

    if (type == TABLE) {
      *AC_cfg >> multparms;
      LookupC = State->GetParameterIndex(multparms);
      cout << "   Column indexing parameter: " << multparms << endl;
    }

    // Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
    // where each non-dimensionalizing parameter for this coefficient is
    // separated by a | character

    *AC_cfg >> multparms;

    end   = multparms.length();
    n     = multparms.find("|");
    start = 0;

    while (n < end && n >= 0) {
      n -= start;
      multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));
      start += n+1;
      n = multparms.find("|",start);
    }

    multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));

    // End of non-dimensionalizing parameter read-in

    switch(type) {
    case VALUE:
      *AC_cfg >> StaticValue;
      cout << "      Value = " << StaticValue << endl;
      break;
    case VECTOR:
      Allocate(rows,2);

      for (r=1;r<=rows;r++) {
        *AC_cfg >> Table3D[r][0];
        *AC_cfg >> Table3D[r][1];
      }

      for (r=1;r<=rows;r++) {
        cout << "	";
        for (c=0;c<columns;c++) {
          cout << Table3D[r][c] << "	";
        }
        cout << endl;
      }

      break;
    case TABLE:
      Allocate(rows, columns);

      Table3D[0][0] = 0.0;
      for (c=1;c<=columns;c++) {
        *AC_cfg >> Table3D[0][c];
        for (r=1;r<=rows;r++) {
          if ( c==1 ) *AC_cfg >> Table3D[r][0];
          else *AC_cfg >> ftrashcan;
          *AC_cfg >> Table3D[r][c];
        }
      }

      for (r=0;r<=rows;r++) {
        cout << "	";
        for (c=0;c<=columns;c++) {
          cout << Table3D[r][c] << "	";
        }
        cout << endl;
      }

      break;
    }
    AC_cfg->GetNextConfigLine();
  }
}

/******************************************************************************/

FGCoefficient::~FGCoefficient(void)
{
}

/******************************************************************************/

bool FGCoefficient::Allocate(int r, int c)
{
  rows = r;
  columns = c;
  Table3D = new float*[r+1];
  for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
  return true;
}

/******************************************************************************/

bool FGCoefficient::Allocate(int n)
{
  rows = n;
  columns = 0;
  Table2D = new float[n+1];
  return true;
}

/******************************************************************************/

float FGCoefficient::Value(float rVal, float cVal)
{
  float rFactor, cFactor, col1temp, col2temp, Value;
  int r, c, midx;

  if (rows < 2 || columns < 2) return 0.0;

  for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
  for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;

  c = c < 2 ? 2 : (c > columns ? columns : c);
  r = r < 2 ? 2 : (r > rows    ? rows    : r);

  rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
  cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);

  col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
  col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];

  SD = Value = col1temp + cFactor*(col2temp - col1temp);

  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);
  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::Value(float Val)
{
  float Factor, Value;
  int r, midx;

  if (rows < 2) return 0.0;

  for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
  r = r < 2 ? 2 : (r > rows    ? rows    : r);

  // make sure denominator below does not go to zero.
  if (Table3D[r][0] != Table3D[r-1][0]) {
    Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
  } else {
    Factor = 1.0;
  }

  SD = Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];

  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);
  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::Value(void)
{
	float Value;
	int midx;

	SD = Value = StaticValue;

  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);
  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::TotalValue()
{
  switch(type) {
  case 0:
    return -1;
  case 1:
    return (Value());
  case 2:
    return (Value(State->GetParameter(LookupR)));
  case 3:
    return (Value(State->GetParameter(LookupR),State->GetParameter(LookupC)));
  case 4:
    return 0.0;
  }
  return 0;
}

/******************************************************************************/

void FGCoefficient::DumpSD(void)
{
  cout << "   " << name << ": " << SD << endl;
}

/******************************************************************************/

<commit_msg>AKP Added handling for unimplented coeff types -- quiets compiler warning<commit_after>/*******************************************************************************

 Module:       FGCoefficient.cpp
 Author:       Jon S. Berndt
 Date started: 12/28/98
 Purpose:      Encapsulates the stability derivative class FGCoefficient;
 Called by:    FGAircraft

 ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------

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

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class models the stability derivative coefficient lookup tables or
equations. Note that the coefficients need not be calculated each delta-t.

Note that the values in a row which index into the table must be the same value
for each column of data, so the first column of numbers for each altitude are
seen to be equal, and there are the same number of values for each altitude.

See the header file FGCoefficient.h for the values of the identifiers.

HISTORY
--------------------------------------------------------------------------------
12/28/98   JSB   Created

********************************************************************************
INCLUDES
*******************************************************************************/

#include "FGCoefficient.h"
#include "FGState.h"
#include "FGFDMExec.h"

/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/

FGCoefficient::FGCoefficient(FGFDMExec* fdex, FGConfigFile* AC_cfg)
{
  int r, c, start, end, n;
  float ftrashcan;
  string multparms;

  FDMExec     = fdex;
  State       = FDMExec->GetState();

  if (AC_cfg) {
    name = AC_cfg->GetValue("NAME");
    method = AC_cfg->GetValue("TYPE");

    AC_cfg->GetNextConfigLine();
    *AC_cfg >> description;

    cout << "   " << name << endl;
    cout << "   " << description << endl;
    cout << "   " << method << endl;

    if      (method == "EQUATION") type = EQUATION;
    else if (method == "TABLE")    type = TABLE;
    else if (method == "VECTOR")   type = VECTOR;
    else if (method == "VALUE")    type = VALUE;
    else                           type = UNKNOWN;

    if (type == VECTOR || type == TABLE) {
      *AC_cfg >> rows;
      cout << "   Rows: " << rows << " ";
      if (type == TABLE) {
        *AC_cfg >> columns;
        cout << "Cols: " << columns;
      }

      cout << endl;

      *AC_cfg >> multparms;
      LookupR = State->GetParameterIndex(multparms);
      cout << "   Row indexing parameter: " << multparms << endl;
    }

    if (type == TABLE) {
      *AC_cfg >> multparms;
      LookupC = State->GetParameterIndex(multparms);
      cout << "   Column indexing parameter: " << multparms << endl;
    }

    // Here, read in the line of the form (e.g.) FG_MACH|FG_QBAR|FG_ALPHA
    // where each non-dimensionalizing parameter for this coefficient is
    // separated by a | character

    *AC_cfg >> multparms;

    end   = multparms.length();
    n     = multparms.find("|");
    start = 0;

    while (n < end && n >= 0) {
      n -= start;
      multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));
      start += n+1;
      n = multparms.find("|",start);
    }

    multipliers.push_back(State->GetParameterIndex(multparms.substr(start,n)));

    // End of non-dimensionalizing parameter read-in

    switch(type) {
    case VALUE:
      *AC_cfg >> StaticValue;
      cout << "      Value = " << StaticValue << endl;
      break;
    case VECTOR:
      Allocate(rows,2);

      for (r=1;r<=rows;r++) {
        *AC_cfg >> Table3D[r][0];
        *AC_cfg >> Table3D[r][1];
      }

      for (r=1;r<=rows;r++) {
        cout << "	";
        for (c=0;c<columns;c++) {
          cout << Table3D[r][c] << "	";
        }
        cout << endl;
      }

      break;
    case TABLE:
      Allocate(rows, columns);

      Table3D[0][0] = 0.0;
      for (c=1;c<=columns;c++) {
        *AC_cfg >> Table3D[0][c];
        for (r=1;r<=rows;r++) {
          if ( c==1 ) *AC_cfg >> Table3D[r][0];
          else *AC_cfg >> ftrashcan;
          *AC_cfg >> Table3D[r][c];
        }
      }

      for (r=0;r<=rows;r++) {
        cout << "	";
        for (c=0;c<=columns;c++) {
          cout << Table3D[r][c] << "	";
        }
        cout << endl;
      }

      break;
    case EQUATION:
    case UNKNOWN:
      cerr << "Unimplemented coefficient type: " << type << endl;
      break;
    }
    AC_cfg->GetNextConfigLine();
  }
}

/******************************************************************************/

FGCoefficient::~FGCoefficient(void)
{
}

/******************************************************************************/

bool FGCoefficient::Allocate(int r, int c)
{
  rows = r;
  columns = c;
  Table3D = new float*[r+1];
  for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
  return true;
}

/******************************************************************************/

bool FGCoefficient::Allocate(int n)
{
  rows = n;
  columns = 0;
  Table2D = new float[n+1];
  return true;
}

/******************************************************************************/

float FGCoefficient::Value(float rVal, float cVal)
{
  float rFactor, cFactor, col1temp, col2temp, Value;
  int r, c;
  unsigned midx;

  if (rows < 2 || columns < 2) return 0.0;

  for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
  for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;

  c = c < 2 ? 2 : (c > columns ? columns : c);
  r = r < 2 ? 2 : (r > rows    ? rows    : r);

  rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
  cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);

  col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
  col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];

  SD = Value = col1temp + cFactor*(col2temp - col1temp);

  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);
  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::Value(float Val)
{

  float Factor, Value;
  int r;
  unsigned midx;

  if (rows < 2) return 0.0;

  for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
  r = r < 2 ? 2 : (r > rows    ? rows    : r);

  // make sure denominator below does not go to zero.
  if (Table3D[r][0] != Table3D[r-1][0]) {
    Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
  } else {
    Factor = 1.0;
  }

  SD = Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);

  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::Value(void)
{
	float Value;
	unsigned midx;

	SD = Value = StaticValue;

  for (midx=0; midx < multipliers.size(); midx++) {
    Value *= State->GetParameter(multipliers[midx]);
  }

  return Value;
}

/******************************************************************************/

float FGCoefficient::TotalValue()
{
  switch(type) {
  case 0:
    return -1;
  case 1:
    return (Value());
  case 2:
    return (Value(State->GetParameter(LookupR)));
  case 3:
    return (Value(State->GetParameter(LookupR),State->GetParameter(LookupC)));
  case 4:
    return 0.0;
  }
  return 0;
}

/******************************************************************************/

void FGCoefficient::DumpSD(void)
{
  cout << "   " << name << ": " << SD << endl;
}

/******************************************************************************/

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stddef.h>
#include <stdint.h>
#include <unistd.h>

#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
#include "perfetto/base/utils.h"
#include "perfetto/ipc/host.h"
#include "perfetto/trace/test_event.pbzero.h"
#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/producer.h"
#include "perfetto/tracing/core/trace_writer.h"
#include "perfetto/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/ipc/service_ipc_host.h"
#include "src/base/test/test_task_runner.h"
#include "test/fake_consumer.h"
#include "test/task_runner_thread.h"
#include "test/task_runner_thread_delegates.h"

namespace perfetto {
namespace shm_fuzz {

static const char* kProducerSocket = tempnam("/tmp", "perfetto-producer");
static const char* kConsumerSocket = tempnam("/tmp", "perfetto-consumer");

// Fake producer writing a protozero message of data into shared memory
// buffer, followed by a sentinel message to signal completion to the
// consumer.
class FakeProducer : public Producer {
 public:
  FakeProducer(std::string name,
               const uint8_t* data,
               size_t size,
               std::function<void()> on_produced_and_committed)
      : name_(std::move(name)),
        data_(data),
        size_(size),
        on_produced_and_committed_(on_produced_and_committed) {}

  void Connect(const char* socket_name, base::TaskRunner* task_runner) {
    endpoint_ = ProducerIPCClient::Connect(
        socket_name, this, "android.perfetto.FakeProducer", task_runner);
  }

  void OnConnect() override {
    DataSourceDescriptor descriptor;
    descriptor.set_name(name_);
    endpoint_->RegisterDataSource(descriptor,
                                  [this](DataSourceID id) { id_ = id; });
  }

  void OnDisconnect() override {}

  void CreateDataSourceInstance(
      DataSourceInstanceID,
      const DataSourceConfig& source_config) override {
    auto trace_writer = endpoint_->CreateTraceWriter(
        static_cast<BufferID>(source_config.target_buffer()));
    {
      auto packet = trace_writer->NewTracePacket();
      packet->stream_writer_->WriteBytes(data_, size_);
    }
    trace_writer->Flush();

    {
      auto end_packet = trace_writer->NewTracePacket();
      end_packet->set_for_testing()->set_str("end");
    }
    trace_writer->Flush(on_produced_and_committed_);
  }

  void TearDownDataSourceInstance(DataSourceInstanceID) override {}
  void OnTracingStart() override {}
  void OnTracingStop() override {}

 private:
  const std::string name_;
  const uint8_t* data_;
  const size_t size_;
  DataSourceID id_ = 0;
  std::unique_ptr<Service::ProducerEndpoint> endpoint_;
  std::function<void()> on_produced_and_committed_;
};

class FakeProducerDelegate : public ThreadDelegate {
 public:
  FakeProducerDelegate(const uint8_t* data,
                       size_t size,
                       std::function<void()> on_produced_and_committed)
      : data_(data),
        size_(size),
        on_produced_and_committed_(on_produced_and_committed) {}
  ~FakeProducerDelegate() override = default;

  void Initialize(base::TaskRunner* task_runner) override {
    producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
                                     size_, on_produced_and_committed_));
    producer_->Connect(kProducerSocket, task_runner);
  }

 private:
  std::unique_ptr<FakeProducer> producer_;
  const uint8_t* data_;
  const size_t size_;
  std::function<void()> on_produced_and_committed_;
};

int FuzzSharedMemory(const uint8_t* data, size_t size);

int FuzzSharedMemory(const uint8_t* data, size_t size) {
  base::TestTaskRunner task_runner;

  TaskRunnerThread service_thread("perfetto.svc");
  service_thread.Start(std::unique_ptr<ServiceDelegate>(
      new ServiceDelegate(kProducerSocket, kConsumerSocket)));

  auto on_produced_and_committed =
      task_runner.CreateCheckpoint("produced.and.committed");
  auto posted_on_produced_and_committed = [&task_runner,
                                           &on_produced_and_committed] {
    task_runner.PostTask(on_produced_and_committed);
  };
  TaskRunnerThread producer_thread("perfetto.prd");
  producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
      new FakeProducerDelegate(data, size, posted_on_produced_and_committed)));

  // Setup the TraceConfig for the consumer.
  TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(8);

  // Create the buffer for the fake producer.
  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("android.perfetto.FakeProducer");
  ds_config->set_target_buffer(0);

  auto on_readback_complete = task_runner.CreateCheckpoint("readback.complete");
  auto on_consumer_data = [&on_readback_complete](
                              std::vector<TracePacket> packets, bool has_more) {
    for (auto& p : packets) {
      p.Decode();
      if (p->for_testing().str() == "end")
        on_readback_complete();
    }
  };

  auto on_connect = task_runner.CreateCheckpoint("consumer.connected");
  FakeConsumer consumer(trace_config, std::move(on_connect),
                        std::move(on_consumer_data), &task_runner);

  consumer.Connect(kConsumerSocket);
  task_runner.RunUntilCheckpoint("consumer.connected");

  consumer.EnableTracing();
  task_runner.RunUntilCheckpoint("produced.and.committed");

  consumer.ReadTraceData();
  task_runner.RunUntilCheckpoint("readback.complete");

  consumer.Disconnect();

  return 0;
}

}  // namespace shm_fuzz
}  // namespace perfetto

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
}
<commit_msg>perfetto: Fix fuzzer<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stddef.h>
#include <stdint.h>
#include <unistd.h>

#include "perfetto/base/logging.h"
#include "perfetto/base/task_runner.h"
#include "perfetto/base/utils.h"
#include "perfetto/ipc/host.h"
#include "perfetto/trace/test_event.pbzero.h"
#include "perfetto/trace/trace_packet.pb.h"
#include "perfetto/trace/trace_packet.pbzero.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/producer.h"
#include "perfetto/tracing/core/trace_writer.h"
#include "perfetto/tracing/ipc/producer_ipc_client.h"
#include "perfetto/tracing/ipc/service_ipc_host.h"
#include "src/base/test/test_task_runner.h"
#include "test/fake_consumer.h"
#include "test/task_runner_thread.h"
#include "test/task_runner_thread_delegates.h"

namespace perfetto {
namespace shm_fuzz {

static const char* kProducerSocket = tempnam("/tmp", "perfetto-producer");
static const char* kConsumerSocket = tempnam("/tmp", "perfetto-consumer");

// Fake producer writing a protozero message of data into shared memory
// buffer, followed by a sentinel message to signal completion to the
// consumer.
class FakeProducer : public Producer {
 public:
  FakeProducer(std::string name,
               const uint8_t* data,
               size_t size,
               std::function<void()> on_produced_and_committed)
      : name_(std::move(name)),
        data_(data),
        size_(size),
        on_produced_and_committed_(on_produced_and_committed) {}

  void Connect(const char* socket_name, base::TaskRunner* task_runner) {
    endpoint_ = ProducerIPCClient::Connect(
        socket_name, this, "android.perfetto.FakeProducer", task_runner);
  }

  void OnConnect() override {
    DataSourceDescriptor descriptor;
    descriptor.set_name(name_);
    endpoint_->RegisterDataSource(descriptor);
  }

  void OnDisconnect() override {}

  void CreateDataSourceInstance(
      DataSourceInstanceID,
      const DataSourceConfig& source_config) override {
    auto trace_writer = endpoint_->CreateTraceWriter(
        static_cast<BufferID>(source_config.target_buffer()));
    {
      auto packet = trace_writer->NewTracePacket();
      packet->stream_writer_->WriteBytes(data_, size_);
    }
    trace_writer->Flush();

    {
      auto end_packet = trace_writer->NewTracePacket();
      end_packet->set_for_testing()->set_str("end");
    }
    trace_writer->Flush(on_produced_and_committed_);
  }

  void TearDownDataSourceInstance(DataSourceInstanceID) override {}
  void OnTracingStart() override {}
  void OnTracingStop() override {}

 private:
  const std::string name_;
  const uint8_t* data_;
  const size_t size_;
  std::unique_ptr<Service::ProducerEndpoint> endpoint_;
  std::function<void()> on_produced_and_committed_;
};

class FakeProducerDelegate : public ThreadDelegate {
 public:
  FakeProducerDelegate(const uint8_t* data,
                       size_t size,
                       std::function<void()> on_produced_and_committed)
      : data_(data),
        size_(size),
        on_produced_and_committed_(on_produced_and_committed) {}
  ~FakeProducerDelegate() override = default;

  void Initialize(base::TaskRunner* task_runner) override {
    producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
                                     size_, on_produced_and_committed_));
    producer_->Connect(kProducerSocket, task_runner);
  }

 private:
  std::unique_ptr<FakeProducer> producer_;
  const uint8_t* data_;
  const size_t size_;
  std::function<void()> on_produced_and_committed_;
};

int FuzzSharedMemory(const uint8_t* data, size_t size);

int FuzzSharedMemory(const uint8_t* data, size_t size) {
  base::TestTaskRunner task_runner;

  TaskRunnerThread service_thread("perfetto.svc");
  service_thread.Start(std::unique_ptr<ServiceDelegate>(
      new ServiceDelegate(kProducerSocket, kConsumerSocket)));

  auto on_produced_and_committed =
      task_runner.CreateCheckpoint("produced.and.committed");
  auto posted_on_produced_and_committed = [&task_runner,
                                           &on_produced_and_committed] {
    task_runner.PostTask(on_produced_and_committed);
  };
  TaskRunnerThread producer_thread("perfetto.prd");
  producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
      new FakeProducerDelegate(data, size, posted_on_produced_and_committed)));

  // Setup the TraceConfig for the consumer.
  TraceConfig trace_config;
  trace_config.add_buffers()->set_size_kb(8);

  // Create the buffer for the fake producer.
  auto* ds_config = trace_config.add_data_sources()->mutable_config();
  ds_config->set_name("android.perfetto.FakeProducer");
  ds_config->set_target_buffer(0);

  auto on_readback_complete = task_runner.CreateCheckpoint("readback.complete");
  auto on_consumer_data = [&on_readback_complete](
                              std::vector<TracePacket> packets, bool has_more) {
    for (auto& p : packets) {
      p.Decode();
      if (p->for_testing().str() == "end")
        on_readback_complete();
    }
  };

  auto on_connect = task_runner.CreateCheckpoint("consumer.connected");
  FakeConsumer consumer(trace_config, std::move(on_connect),
                        std::move(on_consumer_data), &task_runner);

  consumer.Connect(kConsumerSocket);
  task_runner.RunUntilCheckpoint("consumer.connected");

  consumer.EnableTracing();
  task_runner.RunUntilCheckpoint("produced.and.committed");

  consumer.ReadTraceData();
  task_runner.RunUntilCheckpoint("readback.complete");

  consumer.Disconnect();

  return 0;
}

}  // namespace shm_fuzz
}  // namespace perfetto

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
}
<|endoftext|>


<commit_before>#include "App.h"

#include <sstream>

#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#endif

using fgui::Platform;
using fgui::DefaultPlatform;
using fgui::FComponent;
using fgui::FUI;
using fgui::FColoredRectangle;
using fgui::Dimension;
using fgui::Point;
using fgui::Color;
using fgui::Rect;

BMC_BEGIN

   App::App()
   : init_successful_(true),
   display_(NULL),
   queue_(NULL),
   ui_(NULL)
{
   al_set_org_name("Magic / More Magic");
   al_set_app_name("FGUI Demo");

   if (!al_init())
   {
      startupError("The Allegro engine failed to initialize properly!");
      return;
   }

   if (!al_install_keyboard())
      log_.log("Failed to install keyboard!\n");

   if (!al_install_mouse())
      log_.log("Failed to install mouse!\n");

   if (!initOpenGL())
   {
      startupError("There was a problem creating the OpenGL context!");
      return;
   }

   queue_ = al_create_event_queue();
   if (!queue_)
   {
      startupError("There was a problem creating the event queue!");
      return;
   }

   timer_ = al_create_timer(0.01);
   if (!timer_)
   {
      startupError("There was a problem creating the allegro timer!");
      return;
   }

   al_register_event_source(queue_, al_get_keyboard_event_source());
   al_register_event_source(queue_, al_get_mouse_event_source());
   al_register_event_source(queue_, al_get_display_event_source(display_));
   al_register_event_source(queue_, al_get_timer_event_source(timer_));

   initUI();
}

// attempt to create an openGL context with multisampling,
// and try one without multisampling if it fails.
bool App::initOpenGL()
{
   al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);

   al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE);
   al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);

   display_ = al_create_display(640, 480);
   if (!display_)
   {
      al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_DONTCARE);
      al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_DONTCARE);

      display_ = al_create_display(640, 480);
      if (!display_)
         return false;
   }

   glClearColor(0.75, 0.75, 0.75, 0);
   glEnable (GL_BLEND);
   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   return true;
}

void App::initUI()
{
   DefaultPlatform &dp = static_cast<DefaultPlatform&>(Platform::get());
   dp.setLogger(&log_);

   ui_ = new FUI();

   ui_->setMinimumSize(Dimension(100, 100));
   ui_->setMaximumSize(Dimension(800, 600));
   ui_->setPreferredSize(Dimension(400, 300));

   std::ostringstream oss;
   oss << ui_->getPreferredSize() << std::endl;
   log_.log(oss.str().c_str());

   ui_->setSize(Dimension(640, 480)); //ui_->getPreferredSize());

   FColoredRectangle *cr1 = new FColoredRectangle(Color(1, 0, 0), Color(0, 1, 0), Color(0, 0, 1), Color(1, 1, 0));

   ui_->addComponent(cr1);

   cr1->setPosition(Point(5, 10));
   cr1->setSize(Dimension(50, 25));

   ui_->uiSimulate(0);
}

void App::startupError(const char *msg)
{
   al_show_native_message_box(NULL, "Startup Error", "Error", msg, NULL, ALLEGRO_MESSAGEBOX_ERROR);
   init_successful_ = false;
}

App::~App()
{
   if (ui_ != NULL)
      delete ui_;

   al_destroy_event_queue(queue_);
   al_destroy_display(display_);
}

void App::setWindowTitle(const char *title)
{
   al_set_window_title(display_, title);
}

int App::run()
{
   if (!init_successful_)
      return -1;

   std::ostringstream oss;
   oss << "sizeof(FComponent): " << sizeof(FComponent) << std::endl;
   oss << "sizeof(FUI):        " << sizeof(FUI) << std::endl;

   log_.log(oss.str().c_str());

   ui_->logDebugRecursive();

   al_start_timer(timer_);

   while (true) {
      ALLEGRO_EVENT ae;
      bool windowResized = false;
      al_wait_for_event(queue_, &ae);
      do
      {
         switch (ae.type)
         {
            case ALLEGRO_EVENT_TIMER:
               ui_->uiSimulate(10);
               break;

            case ALLEGRO_EVENT_DISPLAY_CLOSE:
               return 0;

            case ALLEGRO_EVENT_DISPLAY_RESIZE:
               windowResized = true;
               break;

            case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
               ui_->uiActiveStatus(false);
               break;

            case ALLEGRO_EVENT_DISPLAY_SWITCH_IN:
               ui_->uiActiveStatus(true);
               break;

            case ALLEGRO_EVENT_KEY_DOWN:
               ui_->uiKeyState(ae.keyboard.keycode, true);

               if (ae.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
                  return 0;
               break;

            case ALLEGRO_EVENT_KEY_UP:
               ui_->uiKeyState(ae.keyboard.keycode, false);
               break;

            case ALLEGRO_EVENT_KEY_CHAR:
               if ((ae.keyboard.modifiers & (ALLEGRO_KEYMOD_CTRL | ALLEGRO_KEYMOD_ALT | ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN | ALLEGRO_KEYMOD_MENU | ALLEGRO_KEYMOD_COMMAND)) == 0)
                  ui_->uiCharacterEntry(ae.keyboard.unichar);
               break;

            case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
               ui_->uiMouseMove(Point(-9999, -9999));
               break;

            case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY:
            case ALLEGRO_EVENT_MOUSE_AXES:
            case ALLEGRO_EVENT_MOUSE_WARPED:
               ui_->uiMouseMove(Point(ae.mouse.x + 0.5f, ae.mouse.y + 0.5f));
               if (ae.mouse.dz != 0 || ae.mouse.dw != 0)
                  ui_->uiMouseWheel(ae.mouse.dz, ae.mouse.dw);
               break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
               ui_->uiMouseButton(ae.mouse.button, true);
               break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
               ui_->uiMouseButton(ae.mouse.button, false);
               break;
         }
      } while (al_get_next_event(queue_, &ae));

      if (windowResized)
      {
         if (ui_->uiResize(Dimension(ae.display.width, ae.display.height)))
            al_acknowledge_resize(display_);
         else
            al_resize_display(display_, ceil(ui_->getSize().width), ceil(ui_->getSize().height));
      }

      if (ui_->uiDrawRequested())
      {
         glClear(GL_COLOR_BUFFER_BIT);
         ui_->makeDirty(ui_->getAbsoluteRect());
         ui_->uiDraw();
         al_flip_display();
      }
   }

   return 0;
}

BMC_END

#ifdef WIN32

   int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   bmc::App a;
   return a.run();
}

#else

   int main(int argc, char** argv)
{
   bmc::App a;
   return a.run();
}

#endif<commit_msg>updated demo with more FColoredRectangles<commit_after>#include "App.h"

#include <sstream>

#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#endif

using fgui::Platform;
using fgui::DefaultPlatform;
using fgui::FComponent;
using fgui::FUI;
using fgui::FColoredRectangle;
using fgui::Dimension;
using fgui::Point;
using fgui::Color;
using fgui::Rect;

BMC_BEGIN

   App::App()
   : init_successful_(true),
   display_(NULL),
   queue_(NULL),
   ui_(NULL)
{
   al_set_org_name("Magic / More Magic");
   al_set_app_name("FGUI Demo");

   if (!al_init())
   {
      startupError("The Allegro engine failed to initialize properly!");
      return;
   }

   if (!al_install_keyboard())
      log_.log("Failed to install keyboard!\n");

   if (!al_install_mouse())
      log_.log("Failed to install mouse!\n");

   if (!initOpenGL())
   {
      startupError("There was a problem creating the OpenGL context!");
      return;
   }

   queue_ = al_create_event_queue();
   if (!queue_)
   {
      startupError("There was a problem creating the event queue!");
      return;
   }

   timer_ = al_create_timer(0.01);
   if (!timer_)
   {
      startupError("There was a problem creating the allegro timer!");
      return;
   }

   al_register_event_source(queue_, al_get_keyboard_event_source());
   al_register_event_source(queue_, al_get_mouse_event_source());
   al_register_event_source(queue_, al_get_display_event_source(display_));
   al_register_event_source(queue_, al_get_timer_event_source(timer_));

   initUI();
}

// attempt to create an openGL context with multisampling,
// and try one without multisampling if it fails.
bool App::initOpenGL()
{
   al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);

   al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE);
   al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);

   display_ = al_create_display(640, 480);
   if (!display_)
   {
      al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_DONTCARE);
      al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_DONTCARE);

      display_ = al_create_display(640, 480);
      if (!display_)
         return false;
   }

   glClearColor(0.75, 0.75, 0.75, 0);
   glEnable (GL_BLEND);
   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   return true;
}

void App::initUI()
{
   DefaultPlatform &dp = static_cast<DefaultPlatform&>(Platform::get());
   dp.setLogger(&log_);

   ui_ = new FUI();

   ui_->setMinimumSize(Dimension(100, 100));
   ui_->setMaximumSize(Dimension(800, 600));
   ui_->setPreferredSize(Dimension(400, 300));

   std::ostringstream oss;
   oss << ui_->getPreferredSize() << std::endl;
   log_.log(oss.str().c_str());

   ui_->setSize(Dimension(640, 480)); //ui_->getPreferredSize());

   FColoredRectangle *cr1 = new FColoredRectangle(Color(1, 0, 0, 0.5), Color(0, 1, 0, 0.5), Color(0, 0, 1, 0.5), Color(1, 1, 0, 0.5));
   FColoredRectangle *cr2 = new FColoredRectangle(Color(1, 0, 0, 0.5), Color(0, 1, 0, 0.5), Color(0, 0, 1, 0.5), Color(1, 1, 0, 0.5));
   FColoredRectangle *cr3 = new FColoredRectangle(Color(1, 0, 0, 0.5), Color(0, 1, 0, 0.5), Color(0, 0, 1, 0.5), Color(1, 1, 0, 0.5));
   FColoredRectangle *cr4 = new FColoredRectangle(Color(1, 0, 0, 0.5), Color(0, 1, 0, 0.5), Color(0, 0, 1, 0.5), Color(1, 1, 0, 0.5));

   ui_->addComponent(cr1);
   ui_->addComponent(cr2);
   ui_->addComponent(cr3);
   ui_->addComponent(cr4);

   cr1->setPosition(Point(5, 10));
   cr1->setSize(Dimension(200, 250));

   cr2->setPosition(Point(100, 10));
   cr2->setSize(Dimension(200, 250));

   cr3->setPosition(Point(50, 100));
   cr3->setSize(Dimension(200, 250));

   cr4->setPosition(Point(400, 0));
   cr4->setSize(Dimension(100, 125));

   ui_->uiSimulate(0);
}

void App::startupError(const char *msg)
{
   al_show_native_message_box(NULL, "Startup Error", "Error", msg, NULL, ALLEGRO_MESSAGEBOX_ERROR);
   init_successful_ = false;
}

App::~App()
{
   if (ui_ != NULL)
      delete ui_;

   al_destroy_event_queue(queue_);
   al_destroy_display(display_);
}

void App::setWindowTitle(const char *title)
{
   al_set_window_title(display_, title);
}

int App::run()
{
   if (!init_successful_)
      return -1;

   std::ostringstream oss;
   oss << "sizeof(FComponent): " << sizeof(FComponent) << std::endl;
   oss << "sizeof(FUI):        " << sizeof(FUI) << std::endl;

   log_.log(oss.str().c_str());

   ui_->logDebugRecursive();

   al_start_timer(timer_);

   while (true) {
      ALLEGRO_EVENT ae;
      bool windowResized = false;
      al_wait_for_event(queue_, &ae);
      do
      {
         switch (ae.type)
         {
            case ALLEGRO_EVENT_TIMER:
               ui_->uiSimulate(10);
               break;

            case ALLEGRO_EVENT_DISPLAY_CLOSE:
               return 0;

            case ALLEGRO_EVENT_DISPLAY_RESIZE:
               windowResized = true;
               break;

            case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
               ui_->uiActiveStatus(false);
               break;

            case ALLEGRO_EVENT_DISPLAY_SWITCH_IN:
               ui_->uiActiveStatus(true);
               break;

            case ALLEGRO_EVENT_KEY_DOWN:
               ui_->uiKeyState(ae.keyboard.keycode, true);

               if (ae.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
                  return 0;
               break;

            case ALLEGRO_EVENT_KEY_UP:
               ui_->uiKeyState(ae.keyboard.keycode, false);
               break;

            case ALLEGRO_EVENT_KEY_CHAR:
               if ((ae.keyboard.modifiers & (ALLEGRO_KEYMOD_CTRL | ALLEGRO_KEYMOD_ALT | ALLEGRO_KEYMOD_LWIN | ALLEGRO_KEYMOD_RWIN | ALLEGRO_KEYMOD_MENU | ALLEGRO_KEYMOD_COMMAND)) == 0)
                  ui_->uiCharacterEntry(ae.keyboard.unichar);
               break;

            case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
               ui_->uiMouseMove(Point(-9999, -9999));
               break;

            case ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY:
            case ALLEGRO_EVENT_MOUSE_AXES:
            case ALLEGRO_EVENT_MOUSE_WARPED:
               ui_->uiMouseMove(Point(ae.mouse.x + 0.5f, ae.mouse.y + 0.5f));
               if (ae.mouse.dz != 0 || ae.mouse.dw != 0)
                  ui_->uiMouseWheel(ae.mouse.dz, ae.mouse.dw);
               break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
               ui_->uiMouseButton(ae.mouse.button, true);
               break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
               ui_->uiMouseButton(ae.mouse.button, false);
               break;
         }
      } while (al_get_next_event(queue_, &ae));

      if (windowResized)
      {
         if (ui_->uiResize(Dimension(ae.display.width, ae.display.height)))
            al_acknowledge_resize(display_);
         else
            al_resize_display(display_, ceil(ui_->getSize().width), ceil(ui_->getSize().height));
      }

      if (ui_->uiDrawRequested())
      {
         glClear(GL_COLOR_BUFFER_BIT);
         ui_->makeDirty(ui_->getAbsoluteRect());
         ui_->uiDraw();
         al_flip_display();
      }
   }

   return 0;
}

BMC_END

#ifdef WIN32

   int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   bmc::App a;
   return a.run();
}

#else

   int main(int argc, char** argv)
{
   bmc::App a;
   return a.run();
}

#endif<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#ifndef STROKE_HPP
#define STROKE_HPP
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/enumeration.hpp>
// stl
#include <vector>

namespace mapnik
{
using std::pair;
using std::vector;
typedef vector<pair<double,double> > dash_array;

// if you add new tokens, don't forget to add them to the corresponding
// string array in the cpp file.
enum line_cap_enum
{
    BUTT_CAP,
    SQUARE_CAP,
    ROUND_CAP,
    line_cap_enum_MAX
};

DEFINE_ENUM( line_cap_e, line_cap_enum );

// if you add new tokens, don't forget to add them to the corresponding
// string array in the cpp file.
enum line_join_enum
{
    MITER_JOIN,
    MITER_REVERT_JOIN,
    ROUND_JOIN,
    BEVEL_JOIN,
    line_join_enum_MAX
};

DEFINE_ENUM( line_join_e, line_join_enum );

class MAPNIK_DECL stroke
{
    color c_;
    double width_;
    double opacity_; // 0.0 - 1.0
    line_cap_e  line_cap_;
    line_join_e line_join_;
    dash_array dash_;
    double dash_offset_;
    double gamma_;
public:
    explicit stroke();
    stroke(color const& c, double width=1.0);
    stroke(stroke const& other);
    stroke& operator=(const stroke& rhs);

    void set_color(const color& c);
    color const& get_color() const;

    double get_width() const;
    void set_width(double w);

    void set_opacity(double opacity);
    double get_opacity() const;

    void set_line_cap(line_cap_e line_cap);
    line_cap_e get_line_cap() const;

    void set_line_join(line_join_e line_join);
    line_join_e get_line_join() const;

    void set_gamma(double gamma);
    double get_gamma() const;

    void add_dash(double dash,double gap);
    bool has_dash() const;

    void set_dash_offset(double offset);
    double dash_offset() const;

    dash_array const& get_dash_array() const;

private:
    void swap(const stroke& other) throw();
};
}

#endif //STROKE_HPP
<commit_msg>avoid compiler warnings<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#ifndef STROKE_HPP
#define STROKE_HPP
// mapnik
#include <mapnik/color.hpp>
#include <mapnik/enumeration.hpp>
// stl
#include <vector>

namespace mapnik
{
using std::pair;
using std::vector;
typedef vector<pair<double,double> > dash_array;

// if you add new tokens, don't forget to add them to the corresponding
// string array in the cpp file.
enum line_cap_enum
{
    BUTT_CAP,
    SQUARE_CAP,
    ROUND_CAP,
    line_cap_enum_MAX
};

DEFINE_ENUM( line_cap_e, line_cap_enum );

// if you add new tokens, don't forget to add them to the corresponding
// string array in the cpp file.
enum line_join_enum
{
    MITER_JOIN,
    MITER_REVERT_JOIN,
    ROUND_JOIN,
    BEVEL_JOIN,
    line_join_enum_MAX
};

DEFINE_ENUM( line_join_e, line_join_enum );

class MAPNIK_DECL stroke
{
    color c_;
    double width_;
    double opacity_; // 0.0 - 1.0
    line_cap_e  line_cap_;
    line_join_e line_join_;
    double gamma_;
    dash_array dash_;
    double dash_offset_;
public:
    explicit stroke();
    stroke(color const& c, double width=1.0);
    stroke(stroke const& other);
    stroke& operator=(const stroke& rhs);

    void set_color(const color& c);
    color const& get_color() const;

    double get_width() const;
    void set_width(double w);

    void set_opacity(double opacity);
    double get_opacity() const;

    void set_line_cap(line_cap_e line_cap);
    line_cap_e get_line_cap() const;

    void set_line_join(line_join_e line_join);
    line_join_e get_line_join() const;

    void set_gamma(double gamma);
    double get_gamma() const;

    void add_dash(double dash,double gap);
    bool has_dash() const;

    void set_dash_offset(double offset);
    double dash_offset() const;

    dash_array const& get_dash_array() const;

private:
    void swap(const stroke& other) throw();
};
}

#endif //STROKE_HPP
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/PrimitiveEvaluator.h"

using namespace IECore;

PrimitiveEvaluator::CreatorMap &PrimitiveEvaluator::getCreateFns()
{
	static CreatorMap *g_createFns = new CreatorMap();
	assert( g_createFns );
	return *g_createFns;
}

void PrimitiveEvaluator::registerCreator( TypeId id, CreatorFn f )
{
	assert( f );

        CreatorMap &createFns = getCreateFns();

        assert( createFns.find( id ) == createFns.end() );

        createFns.insert( CreatorMap::value_type( id, f) );
}

PrimitiveEvaluatorPtr PrimitiveEvaluator::create( ConstPrimitivePtr primitive )
{
	assert( primitive );

        const CreatorMap &createFns = getCreateFns();

        CreatorMap::const_iterator it = createFns.find( primitive->typeId() );
        if (it == createFns.end())
        {
                return 0;
        }

        return (it->second)(primitive);
}

PrimitiveEvaluator::~PrimitiveEvaluator()
{
}

PrimitiveEvaluator::Result::~Result()
{
}
<commit_msg>Added assert<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/PrimitiveEvaluator.h"

using namespace IECore;

PrimitiveEvaluator::CreatorMap &PrimitiveEvaluator::getCreateFns()
{
	static CreatorMap *g_createFns = new CreatorMap();
	assert( g_createFns );
	return *g_createFns;
}

void PrimitiveEvaluator::registerCreator( TypeId id, CreatorFn f )
{
	assert( f );
	assert( f != &PrimitiveEvaluator::create );

        CreatorMap &createFns = getCreateFns();

        assert( createFns.find( id ) == createFns.end() );

        createFns.insert( CreatorMap::value_type( id, f) );
}

PrimitiveEvaluatorPtr PrimitiveEvaluator::create( ConstPrimitivePtr primitive )
{
	assert( primitive );

        const CreatorMap &createFns = getCreateFns();

        CreatorMap::const_iterator it = createFns.find( primitive->typeId() );
        if (it == createFns.end())
        {
                return 0;
        }

        return (it->second)(primitive);
}

PrimitiveEvaluator::~PrimitiveEvaluator()
{
}

PrimitiveEvaluator::Result::~Result()
{
}
<|endoftext|>


<commit_before>#ifndef ORIGEN_HPP_INCLUDED
#define ORIGEN_HPP_INCLUDED

#define ORIGEN_VERSION "0.10.1"

#ifndef debugger
#define debugger __asm__("int $3");
#endif

#include "origen/helpers.hpp"
#include "origen/site.hpp"
#include "origen/utils.hpp"

namespace Origen {

extern vector<Site> Sites;
Utils::Version version();
Site& site();
Site& site(int site);
extern bool invertFunctionalResults;
}
#endif
<commit_msg>Wrote new version in C++ code<commit_after>#ifndef ORIGEN_HPP_INCLUDED
#define ORIGEN_HPP_INCLUDED

#define ORIGEN_VERSION "0.11.0"

#ifndef debugger
#define debugger __asm__("int $3");
#endif

#include "origen/helpers.hpp"
#include "origen/site.hpp"
#include "origen/utils.hpp"

namespace Origen {

extern vector<Site> Sites;
Utils::Version version();
Site& site();
Site& site(int site);
extern bool invertFunctionalResults;
}
#endif
<|endoftext|>