<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#ifndef BENG_PROXY_STOCK_ITEM_HXX
#define BENG_PROXY_STOCK_ITEM_HXX

#include "util/Compiler.h"

#include <boost/intrusive/list.hpp>

#include <exception>

struct pool;
class Stock;
class StockGetHandler;

struct CreateStockItem {
    Stock &stock;
    StockGetHandler &handler;

    /**
     * Wrapper for Stock::GetName()
     */
    gcc_pure
    const char *GetStockName() const;

    /**
     * Announce that the creation of this item has failed.
     */
    void InvokeCreateError(std::exception_ptr ep);

    /**
     * Announce that the creation of this item has been aborted by the
     * caller.
     */
    void InvokeCreateAborted();
};

struct StockItem
    : boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

    Stock &stock;

    StockGetHandler &handler;

    /**
     * If true, then this object will never be reused.
     */
    bool fade = false;

    /**
     * Kludge: this flag is true if this item is idle and is not yet
     * in a "clean" state (e.g. a WAS process after STOP), and cannot
     * yet be reused.  It will be postponed until this flag is false
     * again.  TODO: replace this kludge.
     */
    bool unclean = false;

#ifndef NDEBUG
    bool is_idle = false;
#endif

    explicit StockItem(CreateStockItem c)
        :stock(c.stock), handler(c.handler) {}

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

    virtual ~StockItem();

    /**
     * Wrapper for Stock::GetName()
     */
    gcc_pure
    const char *GetStockName() const;

    /**
     * Return a busy item to the stock.  This is a wrapper for
     * Stock::Put().
     */
    void Put(bool destroy);

    /**
     * Prepare this item to be borrowed by a client.
     *
     * @return false when this item is defunct and shall be destroyed
     */
    virtual bool Borrow() = 0;

    /**
     * Return this borrowed item into the "idle" list.
     *
     * @return false when this item is defunct and shall not be reused
     * again; it will be destroyed by the caller
     */
    virtual bool Release() = 0;

    /**
     * Announce that the creation of this item has finished
     * successfully, and it is ready to be used.
     */
    void InvokeCreateSuccess();

    /**
     * Announce that the creation of this item has failed.
     */
    void InvokeCreateError(std::exception_ptr ep);

    /**
     * Announce that the creation of this item has been aborted by the
     * caller.
     */
    void InvokeCreateAborted();

    /**
     * Announce that the item has been disconnected by the peer while
     * it was idle.
     */
    void InvokeIdleDisconnect();
};

#endif
<commit_msg>stock/Item: reduce include bloat<commit_after>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * 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.
 *
 * 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
 * FOUNDATION 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.
 */

#ifndef BENG_PROXY_STOCK_ITEM_HXX
#define BENG_PROXY_STOCK_ITEM_HXX

#include "util/Compiler.h"

#include <boost/intrusive/list_hook.hpp>

#include <exception>

struct pool;
class Stock;
class StockGetHandler;

struct CreateStockItem {
    Stock &stock;
    StockGetHandler &handler;

    /**
     * Wrapper for Stock::GetName()
     */
    gcc_pure
    const char *GetStockName() const;

    /**
     * Announce that the creation of this item has failed.
     */
    void InvokeCreateError(std::exception_ptr ep);

    /**
     * Announce that the creation of this item has been aborted by the
     * caller.
     */
    void InvokeCreateAborted();
};

struct StockItem
    : boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

    Stock &stock;

    StockGetHandler &handler;

    /**
     * If true, then this object will never be reused.
     */
    bool fade = false;

    /**
     * Kludge: this flag is true if this item is idle and is not yet
     * in a "clean" state (e.g. a WAS process after STOP), and cannot
     * yet be reused.  It will be postponed until this flag is false
     * again.  TODO: replace this kludge.
     */
    bool unclean = false;

#ifndef NDEBUG
    bool is_idle = false;
#endif

    explicit StockItem(CreateStockItem c)
        :stock(c.stock), handler(c.handler) {}

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

    virtual ~StockItem();

    /**
     * Wrapper for Stock::GetName()
     */
    gcc_pure
    const char *GetStockName() const;

    /**
     * Return a busy item to the stock.  This is a wrapper for
     * Stock::Put().
     */
    void Put(bool destroy);

    /**
     * Prepare this item to be borrowed by a client.
     *
     * @return false when this item is defunct and shall be destroyed
     */
    virtual bool Borrow() = 0;

    /**
     * Return this borrowed item into the "idle" list.
     *
     * @return false when this item is defunct and shall not be reused
     * again; it will be destroyed by the caller
     */
    virtual bool Release() = 0;

    /**
     * Announce that the creation of this item has finished
     * successfully, and it is ready to be used.
     */
    void InvokeCreateSuccess();

    /**
     * Announce that the creation of this item has failed.
     */
    void InvokeCreateError(std::exception_ptr ep);

    /**
     * Announce that the creation of this item has been aborted by the
     * caller.
     */
    void InvokeCreateAborted();

    /**
     * Announce that the item has been disconnected by the peer while
     * it was idle.
     */
    void InvokeIdleDisconnect();
};

#endif
<|endoftext|>


<commit_before>
#include <stdio.h>

#include "scsi/config.h"

extern int glps_debug;

int main(int argc, char *argv[])
{
    FILE *in = stdin;
    if(argc>1) {
        in = fopen(argv[1], "r");
        if(!in) {
            fprintf(stderr, "Failed to open %s\n", argv[1]);
            return 2;
        }
    }

    glps_debug = 1;

    std::auto_ptr<Config> conf;

    try{
        GLPSParser P;
        conf.reset(P.parse(in));
        fprintf(stderr, "Parsing succeeds\n");
    }catch(std::exception& e) {
        fprintf(stderr, "Parse error: %s\n", e.what());
        fclose(in);
        return 1;
    }

    std::cerr<<"Generic AST:\n";
    std::cerr << *conf;
    std::cerr<<"GLPS:\n";
    GLPSPrint(std::cout, *conf);

    fprintf(stderr, "Done\n");
    fclose(in);
    return 0;
}
<commit_msg>missing include<commit_after>
#include <iostream>
#include <stdio.h>

#include "scsi/config.h"

extern int glps_debug;

int main(int argc, char *argv[])
{
    FILE *in = stdin;
    if(argc>1) {
        in = fopen(argv[1], "r");
        if(!in) {
            fprintf(stderr, "Failed to open %s\n", argv[1]);
            return 2;
        }
    }

    glps_debug = 1;

    std::auto_ptr<Config> conf;

    try{
        GLPSParser P;
        conf.reset(P.parse(in));
        fprintf(stderr, "Parsing succeeds\n");
    }catch(std::exception& e) {
        fprintf(stderr, "Parse error: %s\n", e.what());
        fclose(in);
        return 1;
    }

    std::cerr<<"Generic AST:\n";
    std::cerr << *conf;
    std::cerr<<"GLPS:\n";
    GLPSPrint(std::cout, *conf);

    fprintf(stderr, "Done\n");
    fclose(in);
    return 0;
}
<|endoftext|>


<commit_before>#include "gis.h"

using namespace std;

namespace cyclus {
namespace toolkit {

GIS::GIS() : latitude_(0), longitude_(0) {}

GIS::GIS(float decimal_lat, float decimal_lon) {
  latitude_ = SetPrecision(decimal_lat * 3600, 1);
  longitude_ = SetPrecision(decimal_lon * 3600, 1);
}

GIS::~GIS() {}

float GIS::get_latitude() const { return SetPrecision(latitude_ / 3600, 6); }

float GIS::get_longitude() const { return SetPrecision(longitude_ / 3600, 6); }

void GIS::set_latitude(float lat) { latitude_ = SetPrecision(lat * 3600, 1); }

void GIS::set_longitude(float lon) { longitude_ = SetPrecision(lon * 3600, 1); }

double GIS::Distance(GIS target) const {
  double curr_longitude = this->get_longitude() * M_PI / 180;
  double curr_latitude = this->get_latitude() * M_PI / 180;
  double target_longitude = target.get_longitude() * M_PI / 180;
  double target_latitude = target.get_latitude() * M_PI / 180;
  double dlong = target_longitude - curr_longitude;
  double dlat = target_latitude - curr_latitude;

  double temp =
      pow(sin(dlat / 2), 2) +
      pow(sin(dlong / 2), 2) * cos(curr_latitude) * cos(target_latitude);

  double temp2 = 2 * atan2(sqrt(temp), sqrt(1 - temp));
  return 6372.8 * temp2;  // 6372.8 is the radius of earth in KM
}

string GIS::ToString(int return_format) const {
  stringstream lat_string;
  stringstream lon_string;
  float lat = this->get_latitude();
  float lon = this->get_longitude();
  switch (return_format) {
    case 1:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
    case 2:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
    case 3:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
  }
  return lat_string.str() + lon_string.str() + "/";
}

float GIS::SetPrecision(float value, double precision) const {
  if (precision == 0) {
    return floor(value);
  }
  return (floor((value * pow(10, precision) + 0.5)) / pow(10, precision));
}

string GIS::ToStringHelperLat(int mode, float lat) const {
  stringstream lat_string;
  double lat_int;
  lat_string << ToStringHelper(lat);

  lat = modf(lat, &lat_int);
  if (((int)lat_int) / 10 == 0) {
    lat_string << "0";
  }
  switch (mode) {
    case 1:
      lat_string << setprecision(7) << fabs(lat_int + lat);
      break;
    case 2:
      lat_string << abs((int)lat_int) << ToStringHelperDM(lat);
      break;
    case 3:
      lat_string << abs((int)lat_int) << ToStringHelperDMS(lat);
      break;
  }
  return lat_string.str();
}

string GIS::ToStringHelperLon(int mode, float lon) const {
  stringstream lon_string;
  double lon_int;
  lon_string << ToStringHelper(lon);
  lon = modf(lon, &lon_int);
  if (((int)lon_int) / 100 == 0) {
    if (((int)lon_int) / 10 == 0) {
      lon_string << "0";
    }
    lon_string << "0";
  }
  switch (mode) {
    case 1:
      lon_string << setprecision(7) << fabs(lon_int + lon);
      break;
    case 2:
      lon_string << abs((int)lon_int) << ToStringHelperDM(lon);
      break;
    case 3:
      lon_string << abs((int)lon_int) << ToStringHelperDMS(lon);
      break;
  }
  return lon_string.str();
}

string GIS::ToStringHelper(float value) const {
  stringstream temp;
  if (value > 0) {
    temp << "+";
  } else {
    temp << "-";
  }
  return temp.str();
}

string GIS::ToStringHelperDM(float value) const {
  stringstream temp;
  value = fabs(value) * 60;
  if (((int)fabs(value)) / 10 == 0) {
    temp << "0";
  }
  temp << setprecision(5) << value;

  return temp.str();
}

string GIS::ToStringHelperDMS(float value) const {
  stringstream temp;
  double value_int;
  value = fabs(value) * 60;
  value = modf(value, &value_int);
  if (((int)value_int) / 10 == 0) {
    temp << "0";
  }
  temp << fabs(value_int);
  value = value * 60;
  if ((int)fabs(value) / 10 == 0) {
    temp << "0";
  }
  temp << setprecision(1) << fixed << value;

  return temp.str();
}

}  // namespace toolkit
}  // namespace cyclus
<commit_msg>Removed 'using namespace std' as required<commit_after>#include "gis.h"

namespace cyclus {
namespace toolkit {

GIS::GIS() : latitude_(0), longitude_(0) {}

GIS::GIS(float decimal_lat, float decimal_lon) {
  latitude_ = SetPrecision(decimal_lat * 3600, 1);
  longitude_ = SetPrecision(decimal_lon * 3600, 1);
}

GIS::~GIS() {}

float GIS::get_latitude() const { return SetPrecision(latitude_ / 3600, 6); }

float GIS::get_longitude() const { return SetPrecision(longitude_ / 3600, 6); }

void GIS::set_latitude(float lat) { latitude_ = SetPrecision(lat * 3600, 1); }

void GIS::set_longitude(float lon) { longitude_ = SetPrecision(lon * 3600, 1); }

double GIS::Distance(GIS target) const {
  double curr_longitude = this->get_longitude() * M_PI / 180;
  double curr_latitude = this->get_latitude() * M_PI / 180;
  double target_longitude = target.get_longitude() * M_PI / 180;
  double target_latitude = target.get_latitude() * M_PI / 180;
  double dlong = target_longitude - curr_longitude;
  double dlat = target_latitude - curr_latitude;

  double temp =
      pow(sin(dlat / 2), 2) +
      pow(sin(dlong / 2), 2) * cos(curr_latitude) * cos(target_latitude);

  double temp2 = 2 * atan2(sqrt(temp), sqrt(1 - temp));
  return 6372.8 * temp2;  // 6372.8 is the radius of earth in KM
}

std::string GIS::ToString(int return_format) const {
  std::stringstream lat_string;
  std::stringstream lon_string;
  float lat = this->get_latitude();
  float lon = this->get_longitude();
  switch (return_format) {
    case 1:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
    case 2:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
    case 3:
      lat_string << ToStringHelperLat(return_format, lat);
      lon_string << ToStringHelperLon(return_format, lon);
      break;
  }
  return lat_string.str() + lon_string.str() + "/";
}

float GIS::SetPrecision(float value, double precision) const {
  if (precision == 0) {
    return floor(value);
  }
  return (floor((value * pow(10, precision) + 0.5)) / pow(10, precision));
}

std::string GIS::ToStringHelperLat(int mode, float lat) const {
  std::stringstream lat_string;
  double lat_int;
  lat_string << ToStringHelper(lat);

  lat = modf(lat, &lat_int);
  if (((int)lat_int) / 10 == 0) {
    lat_string << "0";
  }
  switch (mode) {
    case 1:
      lat_string << std::setprecision(7) << fabs(lat_int + lat);
      break;
    case 2:
      lat_string << abs((int)lat_int) << ToStringHelperDM(lat);
      break;
    case 3:
      lat_string << abs((int)lat_int) << ToStringHelperDMS(lat);
      break;
  }
  return lat_string.str();
}

std::string GIS::ToStringHelperLon(int mode, float lon) const {
  std::stringstream lon_string;
  double lon_int;
  lon_string << ToStringHelper(lon);
  lon = modf(lon, &lon_int);
  if (((int)lon_int) / 100 == 0) {
    if (((int)lon_int) / 10 == 0) {
      lon_string << "0";
    }
    lon_string << "0";
  }
  switch (mode) {
    case 1:
      lon_string << std::setprecision(7) << fabs(lon_int + lon);
      break;
    case 2:
      lon_string << abs((int)lon_int) << ToStringHelperDM(lon);
      break;
    case 3:
      lon_string << abs((int)lon_int) << ToStringHelperDMS(lon);
      break;
  }
  return lon_string.str();
}

std::string GIS::ToStringHelper(float value) const {
  std::stringstream temp;
  if (value > 0) {
    temp << "+";
  } else {
    temp << "-";
  }
  return temp.str();
}

std::string GIS::ToStringHelperDM(float value) const {
  std::stringstream temp;
  value = fabs(value) * 60;
  if (((int)fabs(value)) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(5) << value;

  return temp.str();
}

std::string GIS::ToStringHelperDMS(float value) const {
  std::stringstream temp;
  double value_int;
  value = fabs(value) * 60;
  value = modf(value, &value_int);
  if (((int)value_int) / 10 == 0) {
    temp << "0";
  }
  temp << fabs(value_int);
  value = value * 60;
  if ((int)fabs(value) / 10 == 0) {
    temp << "0";
  }
  temp << std::setprecision(1) << std::fixed << value;

  return temp.str();
}

}  // namespace toolkit
}  // namespace cyclus
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file main.cxx
 *
 * A simple application to demonstrate asynchronous interfaces.
 *
 * @author Balazs Racz
 * @date 7 Dec 2013
 */

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include "os/os.h"
#include "can_frame.h"
#include "nmranet_config.h"

#include "nmranet/SimpleStack.hxx"
#include "nmranet/EventHandlerTemplates.hxx"
#ifdef TARGET_LPC11Cxx
#include "freertos_drivers/nxp/11cxx_async_can.hxx"
#endif

#ifdef BOARD_LAUNCHPAD_EK
#include "console/Console.hxx"
#endif

extern const nmranet::NodeID NODE_ID;

OVERRIDE_CONST(gc_generate_newlines, 1);

//OVERRIDE_CONST(can_tx_buffer_size, 2);
//OVERRIDE_CONST(can_rx_buffer_size, 1);

#ifdef BOARD_LAUNCHPAD_EK
OVERRIDE_CONST(main_thread_stack_size, 2500);
#elif defined(TARGET_LPC11Cxx)
OVERRIDE_CONST(main_thread_stack_size, 1200);
#endif

nmranet::SimpleCanStack stack(NODE_ID);

//static const uint64_t EVENT_ID = 0x0501010114FF2200ULL;
static const uint64_t EVENT_ID = 0x0502010202000000ULL;

class BlinkerFlow : public StateFlowBase
{
public:
    BlinkerFlow(nmranet::Node* node)
        : StateFlowBase(node->interface()),
          state_(1),
          bit_(node, EVENT_ID, EVENT_ID + 1, &state_, (uint8_t)1),
          producer_(&bit_),
          sleepData_(this)
    {
        start_flow(STATE(blinker));
    }

private:
    Action blinker()
    {
        state_ = !state_;
#ifdef __linux__
        LOG(INFO, "blink produce %d", state_);
#endif
        producer_.Update(&helper_, n_.reset(this));
        return wait_and_call(STATE(handle_sleep));
    }

    Action handle_sleep()
    {
        return sleep_and_call(&sleepData_, MSEC_TO_NSEC(1000), STATE(blinker));
    }

    uint8_t state_;
    nmranet::MemoryBit<uint8_t> bit_;
    nmranet::BitEventProducer producer_;
    nmranet::WriteHelper helper_;
    StateFlowTimer sleepData_;
    BarrierNotifiable n_;
};

extern "C" { void resetblink(uint32_t pattern); }

class LoggingBit: public nmranet::BitEventInterface
{
public:
    LoggingBit(uint64_t event_on, uint64_t event_off, const char* name)
        : BitEventInterface(event_on, event_off), name_(name), state_(false)
    {
    }

    virtual bool GetCurrentState()
    {
        return state_;
    }
    virtual void SetState(bool new_value)
    {
        state_ = new_value;
        //HASSERT(0);
#ifdef __linux__
        LOG(INFO, "bit %s set to %d", name_, state_);
#else
        resetblink(state_ ? 1 : 0);
#endif
    }

    virtual nmranet::Node* node()
    {
        return stack.node();
    }

private:
    const char* name_;
    bool state_;
};

BlinkerFlow blinker_flow(stack.node());

/** Entry point to application.
 * @param argc number of command line arguments
 * @param argv array of command line arguments
 * @return 0, should never return
 */
int appl_main(int argc, char* argv[])
{
#ifdef BOARD_LAUNCHPAD_EK
    new Console(true, -1);
#endif

#ifdef __linux__
    stack.print_all_packets();
    stack.start_tcp_hub_server(12021);
#elif defined(TARGET_LPC11Cxx)
    lpc11cxx::CreateCanDriver(stack.can_hub());
#elif defined(TARGET_PIC32MX)
    stack.add_can_port_blocking("/dev/can0");
#elif defined(__FreeRTOS__)
    stack.add_can_port_async("/dev/can0");
#else
#error Define how to connect to your CAN hardware.
#endif  // default target

    // Enable this to add sniffing through the usb or serial port.
#if defined(SNIFF_ON_USB)
    stack.add_gridconnect_port("/dev/serUSB0");
#endif
#if defined(SNIFF_ON_SERIAL)
    stack.add_gridconnect_port("/dev/ser0");
#endif

    LoggingBit logger(EVENT_ID, EVENT_ID + 1, "blinker");
    nmranet::BitEventConsumer consumer(&logger);

    stack.loop_executor();
    return 0;
}
<commit_msg>Implements the SNIP user description in async_blink for both the freertos and the linux targets.<commit_after>/** \copyright
 * Copyright (c) 2013, Balazs Racz
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file main.cxx
 *
 * A simple application to demonstrate asynchronous interfaces.
 *
 * @author Balazs Racz
 * @date 7 Dec 2013
 */

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include "os/os.h"
#include "can_frame.h"
#include "nmranet_config.h"

#include "os/TempFile.hxx"
#include "nmranet/SimpleStack.hxx"
#include "nmranet/SimpleNodeInfo.hxx"
#include "nmranet/EventHandlerTemplates.hxx"
#ifdef TARGET_LPC11Cxx
#include "freertos_drivers/nxp/11cxx_async_can.hxx"
#endif

#ifdef BOARD_LAUNCHPAD_EK
#include "console/Console.hxx"
#endif

extern const nmranet::NodeID NODE_ID;

OVERRIDE_CONST(gc_generate_newlines, 1);

//OVERRIDE_CONST(can_tx_buffer_size, 2);
//OVERRIDE_CONST(can_rx_buffer_size, 1);

#ifdef BOARD_LAUNCHPAD_EK
OVERRIDE_CONST(main_thread_stack_size, 2500);
#elif defined(TARGET_LPC11Cxx)
OVERRIDE_CONST(main_thread_stack_size, 1200);
#endif

nmranet::SimpleCanStack stack(NODE_ID);

#ifdef __FreeRTOS__
#include "freertos_drivers/common/RamDisk.hxx"

namespace nmranet
{
SimpleNodeDynamicValues snip_data{2, "Default user name",
                                  "Default user description"};
const char *const SNIP_DYNAMIC_FILENAME = "/etc/snip_user_data";
RamDisk g_snip_file(SNIP_DYNAMIC_FILENAME, &snip_data, false);
}

#else

static TempDir g_dir;
static const char SNIP_USER_NAME[] = "Default user name";
static const char SNIP_USER_DESCRIPTION[] = "Default user description";
namespace nmranet
{
static MockSNIPUserFile g_snip_file(g_dir, SNIP_USER_NAME,
                                    SNIP_USER_DESCRIPTION);
const char *const SNIP_DYNAMIC_FILENAME = MockSNIPUserFile::snip_user_file_path;
}
#endif

//static const uint64_t EVENT_ID = 0x0501010114FF2200ULL;
static const uint64_t EVENT_ID = 0x0502010202000000ULL;

class BlinkerFlow : public StateFlowBase
{
public:
    BlinkerFlow(nmranet::Node* node)
        : StateFlowBase(node->interface()),
          state_(1),
          bit_(node, EVENT_ID, EVENT_ID + 1, &state_, (uint8_t)1),
          producer_(&bit_),
          sleepData_(this)
    {
        start_flow(STATE(blinker));
    }

private:
    Action blinker()
    {
        state_ = !state_;
#ifdef __linux__
        LOG(INFO, "blink produce %d", state_);
#endif
        producer_.Update(&helper_, n_.reset(this));
        return wait_and_call(STATE(handle_sleep));
    }

    Action handle_sleep()
    {
        return sleep_and_call(&sleepData_, MSEC_TO_NSEC(1000), STATE(blinker));
    }

    uint8_t state_;
    nmranet::MemoryBit<uint8_t> bit_;
    nmranet::BitEventProducer producer_;
    nmranet::WriteHelper helper_;
    StateFlowTimer sleepData_;
    BarrierNotifiable n_;
};

extern "C" { void resetblink(uint32_t pattern); }

class LoggingBit: public nmranet::BitEventInterface
{
public:
    LoggingBit(uint64_t event_on, uint64_t event_off, const char* name)
        : BitEventInterface(event_on, event_off), name_(name), state_(false)
    {
    }

    virtual bool GetCurrentState()
    {
        return state_;
    }
    virtual void SetState(bool new_value)
    {
        state_ = new_value;
        //HASSERT(0);
#ifdef __linux__
        LOG(INFO, "bit %s set to %d", name_, state_);
#else
        resetblink(state_ ? 1 : 0);
#endif
    }

    virtual nmranet::Node* node()
    {
        return stack.node();
    }

private:
    const char* name_;
    bool state_;
};

BlinkerFlow blinker_flow(stack.node());

/** Entry point to application.
 * @param argc number of command line arguments
 * @param argv array of command line arguments
 * @return 0, should never return
 */
int appl_main(int argc, char* argv[])
{
#ifdef BOARD_LAUNCHPAD_EK
    new Console(true, -1);
#endif

#ifdef __linux__
    stack.print_all_packets();
    stack.start_tcp_hub_server(12021);
#elif defined(TARGET_LPC11Cxx)
    lpc11cxx::CreateCanDriver(stack.can_hub());
#elif defined(TARGET_PIC32MX)
    stack.add_can_port_blocking("/dev/can0");
#elif defined(__FreeRTOS__)
    stack.add_can_port_async("/dev/can0");
#else
#error Define how to connect to your CAN hardware.
#endif  // default target

    // Enable this to add sniffing through the usb or serial port.
#if defined(SNIFF_ON_USB)
    stack.add_gridconnect_port("/dev/serUSB0");
#endif
#if defined(SNIFF_ON_SERIAL)
    stack.add_gridconnect_port("/dev/ser0");
#endif

    LoggingBit logger(EVENT_ID, EVENT_ID + 1, "blinker");
    nmranet::BitEventConsumer consumer(&logger);

    stack.loop_executor();
    return 0;
}
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

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

#include <QWidget>
#include <QDropEvent>
#include <QtDBus/QtDBus>

#include <kaction.h>
#include <kactioncollection.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kicon.h>

#include <kcal/calendarlocal.h>
#include <kcal/icaldrag.h>

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kdepimprotocols.h>
#include <libkdepim/kvcarddrag.h>
#include <libkdepim/kpimprefs.h>

#include "core.h"

#include "todoplugin.h"
#include "todosummarywidget.h"
#include "korg_uniqueapp.h"
#include "calendarinterface.h"

typedef KGenericFactory< TodoPlugin, Kontact::Core > TodoPluginFactory;
K_EXPORT_COMPONENT_FACTORY( libkontact_todoplugin,
                            TodoPluginFactory( "kontact_todoplugin" ) )

TodoPlugin::TodoPlugin( Kontact::Core *core, const QStringList& )
  : Kontact::Plugin( core, core, "korganizer" ),
    mIface( 0 )
{
  setComponentData( TodoPluginFactory::componentData() );
  KIconLoader::global()->addAppDir("korganizer");

  KAction *action  = new KAction(KIcon("newtodo"), i18n("New To-do..."), this);
  actionCollection()->addAction("new_todo", action );
  action->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_T));
  connect(action, SIGNAL(triggered(bool)), SLOT( slotNewTodo() ));
  insertNewAction(action);

  KAction* syncAction = new KAction(KIcon("view-refresh"), i18n( "Synchronize To-do List" ), this);
  actionCollection()->addAction("todo_sync", syncAction);
  connect(action, SIGNAL(triggered(bool)), SLOT( slotSyncTodos()));
  insertSyncAction( syncAction );

  mUniqueAppWatcher = new Kontact::UniqueAppWatcher(
      new Kontact::UniqueAppHandlerFactory<KOrganizerUniqueAppHandler>(), this );
}

TodoPlugin::~TodoPlugin()
{
}

Kontact::Summary *TodoPlugin::createSummaryWidget( QWidget *parent )
{
  return new TodoSummaryWidget( this, parent );
}

KParts::ReadOnlyPart *TodoPlugin::createPart()
{
  KParts::ReadOnlyPart *part = loadPart();

  if ( !part )
    return 0;

#ifdef __GNUC__
  #warning "Once we have a running korganizer, make sure that this dbus call really does what it should! Where is it needed, anyway?"
#endif
  mIface = new OrgKdeKorganizerCalendarInterface( "org.kde.korganizer", "/Calendar", QDBusConnection::sessionBus(), this );

  return part;
}

void TodoPlugin::select()
{
  interface()->showTodoView();
}

QStringList TodoPlugin::invisibleToolbarActions() const
{
  QStringList invisible;
  invisible += "new_event";
  invisible += "new_todo";
  invisible += "new_journal";

  invisible += "view_day";
  invisible += "view_list";
  invisible += "view_workweek";
  invisible += "view_week";
  invisible += "view_nextx";
  invisible += "view_month";
  invisible += "view_journal";
  return invisible;
}

OrgKdeKorganizerCalendarInterface *TodoPlugin::interface()
{
  if ( !mIface ) {
    part();
  }
  Q_ASSERT( mIface );
  return mIface;
}

void TodoPlugin::slotNewTodo()
{
  interface()->openTodoEditor( "" );
}

void TodoPlugin::slotSyncTodos()
{
  QDBusMessage message = QDBusMessage::createSignal( "/Groupware", "org.kde.kmail", "triggerSync(QString)");
  message << QString( "Todo" );
  QDBusConnection::sessionBus().send( message );
}

bool TodoPlugin::createDBUSInterface( const QString& serviceType )
{
  kDebug(5602) << k_funcinfo << serviceType << endl;
#ifdef __GNUC__
  #warning "What is this needed for, and do we still need it with DBUS?"
#endif
  if ( serviceType == "DBUS/Organizer" || serviceType == "DBUS/Calendar" ) {
    if ( part() )
      return true;
  }

  return false;
}

bool TodoPlugin::canDecodeMimeData( const QMimeData *mimeData )
{
  return mimeData->hasText() || KPIM::MailList::canDecode( mimeData );
}

bool TodoPlugin::isRunningStandalone()
{
  return mUniqueAppWatcher->isRunningStandalone();
}

void TodoPlugin::processDropEvent( QDropEvent *event )
{
  const QMimeData *md = event->mimeData();

  if ( KVCardDrag::canDecode( md ) ) {
    KABC::Addressee::List contacts;

    KVCardDrag::fromMimeData( md, contacts );

    KABC::Addressee::List::Iterator it;

    QStringList attendees;
    for ( it = contacts.begin(); it != contacts.end(); ++it ) {
      QString email = (*it).fullEmail();
      if ( email.isEmpty() )
        attendees.append( (*it).realName() + "<>" );
      else
        attendees.append( email );
    }

    interface()->openTodoEditor( i18n( "Meeting" ), QString::null, QStringList(),
                                 attendees );
    return;
  }

  if ( KCal::ICalDrag::canDecode( event ) ) {
    KCal::CalendarLocal cal( KPimPrefs::timezone() );
    if ( KCal::ICalDrag::fromMimeData( event, &cal ) ) {
      KCal::Journal::List journals = cal.journals();
      if ( !journals.isEmpty() ) {
        event->accept();
        KCal::Journal *j = journals.first();
        interface()->openTodoEditor( i18n("Note: %1").arg( j->summary() ), j->description(), QString() );
        return;
      }
      // else fall through to text decoding
    }
  }

  if ( md->hasText() ) {
    QString text = md->text();
    interface()->openTodoEditor( text );
    return;
  }

  if ( KPIM::MailList::canDecode( md ) ) {
    KPIM::MailList mails = KPIM::MailList::fromMimeData( md );
    event->accept();
    if ( mails.count() != 1 ) {
      KMessageBox::sorry( core(),
                          i18n("Drops of multiple mails are not supported." ) );
    } else {
      KPIM::MailSummary mail = mails.first();
      QString txt = i18n("From: %1\nTo: %2\nSubject: %3", mail.from() ,
                      mail.to(), mail.subject() );
      QString uri = KDEPIMPROTOCOL_EMAIL +
                    QString::number( mail.serialNumber() ) + '/' +
                    mail.messageId();
      interface()->openTodoEditor( i18n("Mail: %1", mail.subject() ), txt,
                                   QStringList( uri ) );
    }
    return;
  }

  KMessageBox::sorry( core(), i18n("Cannot handle drop events of type '%1'.",
                                event->format() ) );
}

#include "todoplugin.moc"
<commit_msg>Fix i18n<commit_after>/*
    This file is part of Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

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

#include <QWidget>
#include <QDropEvent>
#include <QtDBus/QtDBus>

#include <kaction.h>
#include <kactioncollection.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kicon.h>

#include <kcal/calendarlocal.h>
#include <kcal/icaldrag.h>

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kdepimprotocols.h>
#include <libkdepim/kvcarddrag.h>
#include <libkdepim/kpimprefs.h>

#include "core.h"

#include "todoplugin.h"
#include "todosummarywidget.h"
#include "korg_uniqueapp.h"
#include "calendarinterface.h"

typedef KGenericFactory< TodoPlugin, Kontact::Core > TodoPluginFactory;
K_EXPORT_COMPONENT_FACTORY( libkontact_todoplugin,
                            TodoPluginFactory( "kontact_todoplugin" ) )

TodoPlugin::TodoPlugin( Kontact::Core *core, const QStringList& )
  : Kontact::Plugin( core, core, "korganizer" ),
    mIface( 0 )
{
  setComponentData( TodoPluginFactory::componentData() );
  KIconLoader::global()->addAppDir("korganizer");

  KAction *action  = new KAction(KIcon("newtodo"), i18n("New To-do..."), this);
  actionCollection()->addAction("new_todo", action );
  action->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_T));
  connect(action, SIGNAL(triggered(bool)), SLOT( slotNewTodo() ));
  insertNewAction(action);

  KAction* syncAction = new KAction(KIcon("view-refresh"), i18n( "Synchronize To-do List" ), this);
  actionCollection()->addAction("todo_sync", syncAction);
  connect(action, SIGNAL(triggered(bool)), SLOT( slotSyncTodos()));
  insertSyncAction( syncAction );

  mUniqueAppWatcher = new Kontact::UniqueAppWatcher(
      new Kontact::UniqueAppHandlerFactory<KOrganizerUniqueAppHandler>(), this );
}

TodoPlugin::~TodoPlugin()
{
}

Kontact::Summary *TodoPlugin::createSummaryWidget( QWidget *parent )
{
  return new TodoSummaryWidget( this, parent );
}

KParts::ReadOnlyPart *TodoPlugin::createPart()
{
  KParts::ReadOnlyPart *part = loadPart();

  if ( !part )
    return 0;

#ifdef __GNUC__
  #warning "Once we have a running korganizer, make sure that this dbus call really does what it should! Where is it needed, anyway?"
#endif
  mIface = new OrgKdeKorganizerCalendarInterface( "org.kde.korganizer", "/Calendar", QDBusConnection::sessionBus(), this );

  return part;
}

void TodoPlugin::select()
{
  interface()->showTodoView();
}

QStringList TodoPlugin::invisibleToolbarActions() const
{
  QStringList invisible;
  invisible += "new_event";
  invisible += "new_todo";
  invisible += "new_journal";

  invisible += "view_day";
  invisible += "view_list";
  invisible += "view_workweek";
  invisible += "view_week";
  invisible += "view_nextx";
  invisible += "view_month";
  invisible += "view_journal";
  return invisible;
}

OrgKdeKorganizerCalendarInterface *TodoPlugin::interface()
{
  if ( !mIface ) {
    part();
  }
  Q_ASSERT( mIface );
  return mIface;
}

void TodoPlugin::slotNewTodo()
{
  interface()->openTodoEditor( "" );
}

void TodoPlugin::slotSyncTodos()
{
  QDBusMessage message = QDBusMessage::createSignal( "/Groupware", "org.kde.kmail", "triggerSync(QString)");
  message << QString( "Todo" );
  QDBusConnection::sessionBus().send( message );
}

bool TodoPlugin::createDBUSInterface( const QString& serviceType )
{
  kDebug(5602) << k_funcinfo << serviceType << endl;
#ifdef __GNUC__
  #warning "What is this needed for, and do we still need it with DBUS?"
#endif
  if ( serviceType == "DBUS/Organizer" || serviceType == "DBUS/Calendar" ) {
    if ( part() )
      return true;
  }

  return false;
}

bool TodoPlugin::canDecodeMimeData( const QMimeData *mimeData )
{
  return mimeData->hasText() || KPIM::MailList::canDecode( mimeData );
}

bool TodoPlugin::isRunningStandalone()
{
  return mUniqueAppWatcher->isRunningStandalone();
}

void TodoPlugin::processDropEvent( QDropEvent *event )
{
  const QMimeData *md = event->mimeData();

  if ( KVCardDrag::canDecode( md ) ) {
    KABC::Addressee::List contacts;

    KVCardDrag::fromMimeData( md, contacts );

    KABC::Addressee::List::Iterator it;

    QStringList attendees;
    for ( it = contacts.begin(); it != contacts.end(); ++it ) {
      QString email = (*it).fullEmail();
      if ( email.isEmpty() )
        attendees.append( (*it).realName() + "<>" );
      else
        attendees.append( email );
    }

    interface()->openTodoEditor( i18n( "Meeting" ), QString::null, QStringList(),
                                 attendees );
    return;
  }

  if ( KCal::ICalDrag::canDecode( event ) ) {
    KCal::CalendarLocal cal( KPimPrefs::timezone() );
    if ( KCal::ICalDrag::fromMimeData( event, &cal ) ) {
      KCal::Journal::List journals = cal.journals();
      if ( !journals.isEmpty() ) {
        event->accept();
        KCal::Journal *j = journals.first();
        interface()->openTodoEditor( i18n("Note: %1", j->summary() ), j->description(), QString() );
        return;
      }
      // else fall through to text decoding
    }
  }

  if ( md->hasText() ) {
    QString text = md->text();
    interface()->openTodoEditor( text );
    return;
  }

  if ( KPIM::MailList::canDecode( md ) ) {
    KPIM::MailList mails = KPIM::MailList::fromMimeData( md );
    event->accept();
    if ( mails.count() != 1 ) {
      KMessageBox::sorry( core(),
                          i18n("Drops of multiple mails are not supported." ) );
    } else {
      KPIM::MailSummary mail = mails.first();
      QString txt = i18n("From: %1\nTo: %2\nSubject: %3", mail.from() ,
                      mail.to(), mail.subject() );
      QString uri = KDEPIMPROTOCOL_EMAIL +
                    QString::number( mail.serialNumber() ) + '/' +
                    mail.messageId();
      interface()->openTodoEditor( i18n("Mail: %1", mail.subject() ), txt,
                                   QStringList( uri ) );
    }
    return;
  }

  KMessageBox::sorry( core(), i18n("Cannot handle drop events of type '%1'.",
                                event->format() ) );
}

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


<commit_before>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * type_utils.hpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#pragma once

#include "constants.hpp"

#include <type_traits>

namespace bbb {
	template <typename T>
	using get_type = typename T::type;

	template <bool b, typename T = void>
	using enable_if = get_type<std::enable_if<b, T>>;

	template <typename T>
	constexpr bool is_const() {
		return std::is_const<T>::value;
	}

	template <typename T>
	constexpr bool is_number() {
		return std::is_arithmetic<T>::value;
	}

	template <typename T>
	constexpr bool is_integer() {
		return std::is_integral<T>::value;
	}

	template <typename T>
	constexpr bool is_float() {
		return std::is_floating_point<T>::value;
	}

	template <typename T>
	using remove_const_reference_if_number = get_type<std::conditional<
		is_number<T>(),
		get_type<std::remove_reference<
			get_type<std::remove_const<T>>
		>>,
		T
	>>;

	template <typename T>
	using add_const_reference_if_not_number = get_type<std::conditional<
		!is_number<T>(),
		get_type<std::add_const<
			get_type<std::add_lvalue_reference<T>>
		>>,
		T
	>>;
};<commit_msg>add function_traits<commit_after>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * type_utils.hpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#pragma once

#include "constants.hpp"

#include <type_traits>
#include <tuple>

namespace bbb {
	template <typename T>
	using get_type = typename T::type;

	template <bool b, typename T = void>
	using enable_if = get_type<std::enable_if<b, T>>;

	template <typename T>
	constexpr bool is_const() {
		return std::is_const<T>::value;
	}

	template <typename T>
	constexpr bool is_number() {
		return std::is_arithmetic<T>::value;
	}

	template <typename T>
	constexpr bool is_integer() {
		return std::is_integral<T>::value;
	}

	template <typename T>
	constexpr bool is_float() {
		return std::is_floating_point<T>::value;
	}

	template <typename T>
	using remove_const_reference_if_number = get_type<std::conditional<
		is_number<T>(),
		get_type<std::remove_reference<
			get_type<std::remove_const<T>>
		>>,
		T
	>>;

	template <typename T>
	using add_const_reference_if_not_number = get_type<std::conditional<
		!is_number<T>(),
		get_type<std::add_const<
			get_type<std::add_lvalue_reference<T>>
		>>,
		T
	>>;

	namespace function_traits {
		template <typename T>
		struct function_info : public function_info<decltype(&T::operator())> {};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...) const> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename ret, typename ... arguments>
		struct function_info<ret(*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template<typename T>
		using result_type = typename function_info<T>::result_type;
		template<typename T>
		using arguments_types_tuple = typename function_info<T>::arguments_types_tuple;
		template<typename T, std::size_t index>
		using argument_type = typename function_info<T>::template argument_type<index>;
		template<typename T>
		struct arity {
			static constexpr std::size_t value = function_info<T>::arity;
		};
	};
	using namespace function_traits;
};<|endoftext|>


<commit_before>#include <fstream>
#include <iomanip>
#include <iostream>

#include <prjxray/xilinx/xc7series/configuration_frame_address.h>

namespace xc7series = prjxray::xilinx::xc7series;

int main(int argc, char *argv[]) {
	std::istream * input_stream = &std::cin;
	if (argc > 1) {
		auto file_stream = std::ifstream(argv[1]);
		if (file_stream) {
			input_stream = &file_stream;
		}
	}

	for (uint32_t frame_address_raw;
	     (*input_stream) >> std::hex >> frame_address_raw;
	     ) {
		xc7series::ConfigurationFrameAddress frame_address(frame_address_raw);
		std::cout << "["
			  << std::hex << std::showbase << std::setw(10)
			  << frame_address_raw
			  << "] "
			  << (frame_address.is_bottom_half_rows() ?
				     "BOTTOM" : "TOP")
			  << " Row="
			  << std::setw(2) << std::dec
			  << static_cast<unsigned int>(frame_address.row_address())
			  << " Column="
			  << std::setw(2) << std::dec
			  << frame_address.column_address()
			  << " Minor="
			  << std::setw(2) << std::dec
			  << static_cast<unsigned int>(frame_address.minor_address())
			  << " Type="
			  << frame_address.block_type()
			  << std::endl;
	}

	return 0;
}
<commit_msg>frame_address_decoder: Autodetect input address base (oct, dec, hex)<commit_after>#include <fstream>
#include <iomanip>
#include <iostream>

#include <prjxray/xilinx/xc7series/configuration_frame_address.h>

namespace xc7series = prjxray::xilinx::xc7series;

int main(int argc, char *argv[]) {
	std::istream * input_stream = &std::cin;
	if (argc > 1) {
		auto file_stream = std::ifstream(argv[1]);
		if (file_stream) {
			input_stream = &file_stream;
		}
	}

	for (uint32_t frame_address_raw;
	     (*input_stream) >> std::setbase(0) >> frame_address_raw;
	     ) {
		xc7series::ConfigurationFrameAddress frame_address(frame_address_raw);
		std::cout << "["
			  << std::hex << std::showbase << std::setw(10)
			  << frame_address_raw
			  << "] "
			  << (frame_address.is_bottom_half_rows() ?
				     "BOTTOM" : "TOP")
			  << " Row="
			  << std::setw(2) << std::dec
			  << static_cast<unsigned int>(frame_address.row_address())
			  << " Column="
			  << std::setw(2) << std::dec
			  << frame_address.column_address()
			  << " Minor="
			  << std::setw(2) << std::dec
			  << static_cast<unsigned int>(frame_address.minor_address())
			  << " Type="
			  << frame_address.block_type()
			  << std::endl;
	}

	return 0;
}
<|endoftext|>


<commit_before>/** @file

    Plugin to perform background fetches of certain content that would
    otherwise not be cached. For example, Range: requests / responses.

    @section license License

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
#include <stdio.h>
#include <ts/ts.h>
#include <ts/apidefs.h>
#include <openssl/ssl.h>
#include <string>
#include <map>
#include <string.h>

using namespace std;

const char* PLUGIN_NAME = "sni_proto_nego";
const int MAX_BUFFER_SIZE = 1024;
const int MAX_FILE_PATH_SIZE = 1024;
const unsigned int MAX_PROTO_LIST_LEN = 100;
const unsigned int MAX_PROTO_NAME_LEN = 255;

typedef struct {
  bool enableNpn;
  unsigned int npn_proto_list_count;
  unsigned char npn_proto_list [MAX_PROTO_LIST_LEN] [MAX_PROTO_NAME_LEN];
} SNIProtoConfig;

typedef map<string, SNIProtoConfig> stringMap;
static  stringMap _sniProtoMap;

static
bool read_config(char* config_file) {
  char file_path[MAX_FILE_PATH_SIZE];
  TSFile file;
  if (config_file == NULL) {
    TSError("invalid config file");
    return false;
  }
  TSDebug(PLUGIN_NAME, "trying to open config file in this path: %s", file_path);
  file = TSfopen(config_file, "r");
  if (file == NULL) {
    snprintf(file_path, sizeof(file_path), "%s/%s", TSInstallDirGet(), config_file);
    file = TSfopen(file_path, "r");
    if (file == NULL) {
      TSError("Failed to open config file %s", config_file);
      return false;
    }
  }
  char buffer[MAX_BUFFER_SIZE];
  memset(buffer, 0, sizeof(buffer));
  while (TSfgets(file, buffer, sizeof(buffer) - 1) != NULL) {
    char *eol = 0;
    // make sure line was not bigger than buffer
    if ((eol = strchr(buffer, '\n')) == NULL && (eol = strstr(buffer, "\r\n")) == NULL) {
      TSError("sni_proto_nego line too long, did not get a good line in cfg, skipping, line: %s", buffer);
      memset(buffer, 0, sizeof(buffer));
      continue;
    }
    // make sure line has something useful on it
    if (eol - buffer < 2 || buffer[0] == '#') {
      memset(buffer, 0, sizeof(buffer));
      continue;
    }
    char* cfg = strtok(buffer, "\n\r\n");

    if (cfg != NULL) {
        TSDebug(PLUGIN_NAME, "setting SniProto based on string: %s", cfg);

        char* domain = strtok(buffer, " ");
        SNIProtoConfig sniProtoConfig = {1, 1};

        if (domain) {
          if ((*domain == '*') && (domain+1) && (*(domain+1)=='.')) {
            domain += 2;
            if (domain == NULL) {
              continue;
            }
          }
          char* sni_proto_config = strtok (NULL, " ");
          if (sni_proto_config) {
            sniProtoConfig.enableNpn = atoi(sni_proto_config);
            TSDebug(PLUGIN_NAME, "npn_proto_config %d", sniProtoConfig.enableNpn);
            sni_proto_config = strtok (NULL, " ");
            // now get the npn proto advertisment list
            sni_proto_config = strtok (NULL, " ");
            sniProtoConfig.npn_proto_list_count = 0;
            while (sni_proto_config != NULL) {
              char* proto = strtok(NULL, "|");
              if ((proto == NULL) ||
                  (sniProtoConfig.npn_proto_list_count >= MAX_PROTO_LIST_LEN) ||
                  (strlen(proto) >= MAX_PROTO_NAME_LEN)) {
                break;
              }
              _TSstrlcpy((char*)sniProtoConfig.npn_proto_list[sniProtoConfig.npn_proto_list_count++], proto, (strlen(proto) + 1));
            }
          }
          _sniProtoMap.insert(make_pair(domain, sniProtoConfig));
        }

        memset(buffer, 0, sizeof(buffer));
    }
  }

  TSfclose(file);

  TSDebug(PLUGIN_NAME, "Done parsing config");

  return true;
}

static void
init_sni_callback(void *sslNetVC)
{
  TSVConn ssl_vc = reinterpret_cast<TSVConn>(sslNetVC);
  TSSslConnection sslobj = TSVConnSSLConnectionGet(ssl_vc);
  SSL *ssl = reinterpret_cast<SSL *>(sslobj);
  const char *serverName = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
  SSL_CTX * ctx = SSL_get_SSL_CTX(ssl);

  if (serverName == NULL) {
    TSDebug(PLUGIN_NAME, "invalid ssl netVC %p, servername %s for ssl obj %p", sslNetVC, serverName, ssl);
    return;
  }

  TSDebug(PLUGIN_NAME, "ssl netVC %p, servername %s for ssl obj %p", sslNetVC, serverName, ssl);

  stringMap::iterator it;
  it=_sniProtoMap.find(serverName);

  // check for wild-card domains
  if(it==_sniProtoMap.end()) {
    char* domain = strstr((char*)serverName, ".");
    if (domain && (domain+1)) {
      it=_sniProtoMap.find(domain+1);
    }
  }

  if (it!=_sniProtoMap.end()) {
    SNIProtoConfig sniProtoConfig = it->second;
    if (!sniProtoConfig.enableNpn) {
      TSDebug(PLUGIN_NAME, "disabling NPN for serverName %s", serverName);
      SSL_CTX_set_next_protos_advertised_cb(ctx, NULL, NULL);
    } else {
      TSDebug(PLUGIN_NAME, "setting NPN advertised list for %s", serverName);
      TSSslAdvertiseProtocolSet(ssl_vc, (const unsigned char **)sniProtoConfig.npn_proto_list, sniProtoConfig.npn_proto_list_count);
    }
  } else {
    TSDebug(PLUGIN_NAME, "setting NPN advertised list for %s", serverName);
    TSSslAdvertiseProtocolSet(ssl_vc, NULL, 0);
  }
}

int
SSLSniInitCallbackHandler(TSCont cont, TSEvent id, void* sslNetVC) {
  (void) cont;
  TSDebug(PLUGIN_NAME, "SSLSniInitCallbackHandler with id %d", id);
  switch (id) {
  case TS_SSL_SNI_HOOK:
      {
        init_sni_callback(sslNetVC);
      }
      break;

  default:
    TSDebug(PLUGIN_NAME, "Unexpected event %d", id);
    break;
  }

  return TS_EVENT_NONE;
}

void
TSPluginInit(int argc, const char *argv[])
{
  (void) argc;
  TSPluginRegistrationInfo info;

  info.plugin_name = (char *)("sni_proto_nego");
  info.vendor_name = (char *)("ats");

  if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
    TSError("Plugin registration failed.");
  }

  char* config_file = (char*)"conf/sni_proto_nego/sni_proto_nego.config";

  if (argc >= 2) {
    config_file = (char*)argv[1];
  }

  if (!read_config(config_file)) {
    TSDebug(PLUGIN_NAME, "nothing to do..");
    return;
  }

  TSCont cont = TSContCreate(SSLSniInitCallbackHandler, NULL);
  TSHttpHookAdd(TS_SSL_SNI_HOOK, cont);
}
<commit_msg>fix build error<commit_after>/** @file

    Plugin to perform background fetches of certain content that would
    otherwise not be cached. For example, Range: requests / responses.

    @section license License

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
#include <stdio.h>
#include <ts/ts.h>
#include <openssl/ssl.h>
#include <string>
#include <map>
#include <string.h>

using namespace std;

const char* PLUGIN_NAME = "sni_proto_nego";
const int MAX_BUFFER_SIZE = 1024;
const int MAX_FILE_PATH_SIZE = 1024;
const unsigned int MAX_PROTO_LIST_LEN = 100;
const unsigned int MAX_PROTO_NAME_LEN = 255;

typedef struct {
  bool enableNpn;
  unsigned int npn_proto_list_count;
  unsigned char npn_proto_list [MAX_PROTO_LIST_LEN] [MAX_PROTO_NAME_LEN];
} SNIProtoConfig;

typedef map<string, SNIProtoConfig> stringMap;
static  stringMap _sniProtoMap;

static
bool read_config(char* config_file) {
  char file_path[MAX_FILE_PATH_SIZE];
  TSFile file;
  if (config_file == NULL) {
    TSError("invalid config file");
    return false;
  }
  TSDebug(PLUGIN_NAME, "trying to open config file in this path: %s", file_path);
  file = TSfopen(config_file, "r");
  if (file == NULL) {
    snprintf(file_path, sizeof(file_path), "%s/%s", TSInstallDirGet(), config_file);
    file = TSfopen(file_path, "r");
    if (file == NULL) {
      TSError("Failed to open config file %s", config_file);
      return false;
    }
  }
  char buffer[MAX_BUFFER_SIZE];
  memset(buffer, 0, sizeof(buffer));
  while (TSfgets(file, buffer, sizeof(buffer) - 1) != NULL) {
    char *eol = 0;
    // make sure line was not bigger than buffer
    if ((eol = strchr(buffer, '\n')) == NULL && (eol = strstr(buffer, "\r\n")) == NULL) {
      TSError("sni_proto_nego line too long, did not get a good line in cfg, skipping, line: %s", buffer);
      memset(buffer, 0, sizeof(buffer));
      continue;
    }
    // make sure line has something useful on it
    if (eol - buffer < 2 || buffer[0] == '#') {
      memset(buffer, 0, sizeof(buffer));
      continue;
    }
    char* cfg = strtok(buffer, "\n\r\n");

    if (cfg != NULL) {
        TSDebug(PLUGIN_NAME, "setting SniProto based on string: %s", cfg);

        char* domain = strtok(buffer, " ");
        SNIProtoConfig sniProtoConfig = {1, 1};

        if (domain) {
          if ((*domain == '*') && (domain+1) && (*(domain+1)=='.')) {
            domain += 2;
            if (domain == NULL) {
              continue;
            }
          }
          char* sni_proto_config = strtok (NULL, " ");
          if (sni_proto_config) {
            sniProtoConfig.enableNpn = atoi(sni_proto_config);
            TSDebug(PLUGIN_NAME, "npn_proto_config %d", sniProtoConfig.enableNpn);
            sni_proto_config = strtok (NULL, " ");
            // now get the npn proto advertisment list
            sni_proto_config = strtok (NULL, " ");
            sniProtoConfig.npn_proto_list_count = 0;
            while (sni_proto_config != NULL) {
              char* proto = strtok(NULL, "|");
              if ((proto == NULL) ||
                  (sniProtoConfig.npn_proto_list_count >= MAX_PROTO_LIST_LEN) ||
                  (strlen(proto) >= MAX_PROTO_NAME_LEN)) {
                break;
              }
              _TSstrlcpy((char*)sniProtoConfig.npn_proto_list[sniProtoConfig.npn_proto_list_count++], proto, (strlen(proto) + 1));
            }
          }
          _sniProtoMap.insert(make_pair(domain, sniProtoConfig));
        }

        memset(buffer, 0, sizeof(buffer));
    }
  }

  TSfclose(file);

  TSDebug(PLUGIN_NAME, "Done parsing config");

  return true;
}

static void
init_sni_callback(void *sslNetVC)
{
  TSVConn ssl_vc = reinterpret_cast<TSVConn>(sslNetVC);
  TSSslConnection sslobj = TSVConnSSLConnectionGet(ssl_vc);
  SSL *ssl = reinterpret_cast<SSL *>(sslobj);
  const char *serverName = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
  SSL_CTX * ctx = SSL_get_SSL_CTX(ssl);

  if (serverName == NULL) {
    TSDebug(PLUGIN_NAME, "invalid ssl netVC %p, servername %s for ssl obj %p", sslNetVC, serverName, ssl);
    return;
  }

  TSDebug(PLUGIN_NAME, "ssl netVC %p, servername %s for ssl obj %p", sslNetVC, serverName, ssl);

  stringMap::iterator it;
  it=_sniProtoMap.find(serverName);

  // check for wild-card domains
  if(it==_sniProtoMap.end()) {
    char* domain = strstr((char*)serverName, ".");
    if (domain && (domain+1)) {
      it=_sniProtoMap.find(domain+1);
    }
  }

  if (it!=_sniProtoMap.end()) {
    SNIProtoConfig sniProtoConfig = it->second;
    if (!sniProtoConfig.enableNpn) {
      TSDebug(PLUGIN_NAME, "disabling NPN for serverName %s", serverName);
      SSL_CTX_set_next_protos_advertised_cb(ctx, NULL, NULL);
    } else {
      TSDebug(PLUGIN_NAME, "setting NPN advertised list for %s", serverName);
      TSSslAdvertiseProtocolSet(ssl_vc, (const unsigned char **)sniProtoConfig.npn_proto_list, sniProtoConfig.npn_proto_list_count);
    }
  } else {
    TSDebug(PLUGIN_NAME, "setting NPN advertised list for %s", serverName);
    TSSslAdvertiseProtocolSet(ssl_vc, NULL, 0);
  }
}

int
SSLSniInitCallbackHandler(TSCont /* cont */, TSEvent /* id */, void* sslNetVC) {
  init_sni_callback(sslNetVC);
  return TS_EVENT_NONE;
}

void
TSPluginInit(int argc, const char *argv[])
{
  (void) argc;
  TSPluginRegistrationInfo info;

  info.plugin_name = (char *)("sni_proto_nego");
  info.vendor_name = (char *)("ats");

  if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
    TSError("Plugin registration failed.");
  }

  char* config_file = (char*)"conf/sni_proto_nego/sni_proto_nego.config";

  if (argc >= 2) {
    config_file = (char*)argv[1];
  }

  if (!read_config(config_file)) {
    TSDebug(PLUGIN_NAME, "nothing to do..");
    return;
  }

  TSCont cont = TSContCreate(SSLSniInitCallbackHandler, NULL);
  TSHttpHookAdd(TS_SSL_SNI_HOOK, cont);
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, 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 Willow Garage, Inc. nor the names of its
 *     contributors 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.
 *
 * $Id$
 *
 */

#ifndef PCL_SURFACE_IMPL_CONVEX_HULL_H_
#define PCL_SURFACE_IMPL_CONVEX_HULL_H_

#include "pcl/surface/convex_hull.h"
#include "pcl/common/common.h"
#include "pcl/registration/transforms.h"

#ifndef _WIN32
  #if defined(__cplusplus)
  extern "C"
  {
  #endif
#  include <stdio.h>
#  include <stdlib.h>
#  include "qhull/qhull.h"
#  include "qhull/mem.h"
#  include "qhull/qset.h"
#  include "qhull/geom.h"
#  include "qhull/merge.h"
#  include "qhull/poly.h"
#  include "qhull/io.h"
#  include "qhull/stat.h"
  #if defined(__cplusplus)
  }
  #endif
#else
#  include <stdio.h>
#  include <stdlib.h>
#  include "libqhull/qhull.h"
#  include "libqhull/mem.h"
#  include "libqhull/qset.h"
#  include "libqhull/geom.h"
#  include "libqhull/merge.h"
#  include "libqhull/poly.h"
#  include "libqhull/io.h"
#  include "libqhull/stat.h"
#endif

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::performReconstruction (PointCloud &hull,
                                                  std::vector<pcl::Vertices> &polygons,
                                                  bool fill_polygon_data)
{
  // FInd the principal directions
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;
  compute3DCentroid (*input_, *indices_, xyz_centroid);
  computeCovarianceMatrix (*input_, *indices_, xyz_centroid, covariance_matrix);
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  Eigen::Affine3f transform1;
  transform1.setIdentity ();
  int dim = 3;

  if (eigen_values[0] / eigen_values[2] < 1.0e-5)
  {
    // We have points laying on a plane, using 2d convex hull
    // Compute transformation bring eigen_vectors.col(i) to z-axis

    eigen_vectors.col (2) = eigen_vectors.col (0).cross (eigen_vectors.col (1));
    eigen_vectors.col (1) = eigen_vectors.col (2).cross (eigen_vectors.col (0));

    transform1 (0, 2) = eigen_vectors (0, 0);
    transform1 (1, 2) = eigen_vectors (1, 0);
    transform1 (2, 2) = eigen_vectors (2, 0);

    transform1 (0, 1) = eigen_vectors (0, 1);
    transform1 (1, 1) = eigen_vectors (1, 1);
    transform1 (2, 1) = eigen_vectors (2, 1);
    transform1 (0, 0) = eigen_vectors (0, 2);
    transform1 (1, 0) = eigen_vectors (1, 2);
    transform1 (2, 0) = eigen_vectors (2, 2);

    transform1 = transform1.inverse ();
    dim = 2;
  }
  else
    transform1.setIdentity ();

  PointCloud cloud_transformed;
  pcl::demeanPointCloud (*input_, *indices_, xyz_centroid, cloud_transformed);
  pcl::transformPointCloud (cloud_transformed, cloud_transformed, transform1);

  // True if qhull should free points in qh_freeqhull() or reallocation
  boolT ismalloc = True;
  // option flags for qhull, see qh_opt.htm
  char flags[] = "qhull Tc";
  // output from qh_produce_output(), use NULL to skip qh_produce_output()
  FILE *outfile = NULL;
  // error messages from qhull code
  FILE *errfile = stderr;
  // 0 if no error from qhull
  int exitcode;

  // Array of coordinates for each point
  coordT *points = (coordT *)calloc (cloud_transformed.points.size () * dim, sizeof (coordT));

  for (size_t i = 0; i < cloud_transformed.points.size (); ++i)
  {
    points[i * dim + 0] = (coordT)cloud_transformed.points[i].x;
    points[i * dim + 1] = (coordT)cloud_transformed.points[i].y;

    if (dim > 2)
      points[i * dim + 2] = (coordT)cloud_transformed.points[i].z;
  }

  // Compute convex hull
  exitcode = qh_new_qhull (dim, cloud_transformed.points.size (), points, ismalloc, flags, outfile, errfile);

  if (exitcode != 0) {
     PCL_ERROR("ERROR: qhull was unable to compute a convex hull for the given point cloud");

     //check if it fails because of NaN values...
     if (!cloud_transformed.is_dense) {

       PCL_WARN("Checking for Nans");

       bool NaNvalues = false;
       for (size_t i = 0; i < cloud_transformed.size (); ++i)
         {
           if (!pcl_isfinite (cloud_transformed.points[i].x)
               ||
               !pcl_isfinite (cloud_transformed.points[i].y)
               ||
               !pcl_isfinite (cloud_transformed.points[i].z)) {
             NaNvalues = true;
             break;
           }
         }

       if (NaNvalues)
         PCL_ERROR("ERROR: point cloud contains NaN values, consider running pcl::PassThrough filter first to remove NaNs.");

     }

     hull.points.resize (0);
     hull.width = hull.height = 0;
     polygons.resize (0);
     return;
  }

  qh_triangulate ();

  int num_facets = qh num_facets;

  int num_vertices = qh num_vertices;
  hull.points.resize (num_vertices);

  vertexT *vertex;
  int i = 0;
  // Max vertex id
  int max_vertex_id = -1;
  FORALLvertices
  {
    if ((int)vertex->id > max_vertex_id)
      max_vertex_id = vertex->id;
  }

  ++max_vertex_id;
  std::vector<int> qhid_to_pcidx (max_vertex_id);

  FORALLvertices
  {
    // Add vertices to hull point_cloud
    hull.points[i].x = vertex->point[0];
    hull.points[i].y = vertex->point[1];

    if (dim>2)
    hull.points[i].z = vertex->point[2];
    else
    hull.points[i].z = 0;

    qhid_to_pcidx[vertex->id] = i; // map the vertex id of qhull to the point cloud index
    ++i;
  }

  if (fill_polygon_data)
  {
    if (dim == 3)
    {
      polygons.resize (num_facets);
      int dd = 0;

      facetT *facet;
      FORALLfacets
      {
        polygons[dd].vertices.resize (3);

        // Needed by FOREACHvertex_i_
        int vertex_n, vertex_i;
        FOREACHvertex_i_((*facet).vertices)
          //facet_vertices.vertices.push_back (qhid_to_pcidx[vertex->id]);
          polygons[dd].vertices[vertex_i] = qhid_to_pcidx[vertex->id];

        ++dd;
      }
    }
    else
    {
      // dim=2, we want to return just a polygon with all vertices sorted
      // so that they form a non-intersecting polygon...
      // this can be moved to the upper loop probably and here just
      // the sorting + populate

      Eigen::Vector4f centroid;
      pcl::compute3DCentroid (hull, centroid);
      centroid[3] = 0;
      polygons.resize (1);

      int num_vertices = qh num_vertices, dd = 0;

      // Copy all vertices
      std::vector<std::pair<int, Eigen::Vector4f>, Eigen::aligned_allocator<std::pair<int, Eigen::Vector4f> > > idx_points (num_vertices);

      FORALLvertices
      {
        idx_points[dd].first = qhid_to_pcidx[vertex->id];
        idx_points[dd].second = hull.points[idx_points[dd].first].getVector4fMap () - centroid;
        ++dd;
      }

      // Sort idx_points
      std::sort (idx_points.begin (), idx_points.end (), comparePoints2D);
      polygons[0].vertices.resize (idx_points.size () + 1);

      //Sort also points...
      PointCloud hull_sorted;
      hull_sorted.points.resize (hull.points.size ());

      for (size_t j = 0; j < idx_points.size (); ++j)
        hull_sorted.points[j] = hull.points[idx_points[j].first];

      hull.points = hull_sorted.points;

      // Populate points
      for (size_t j = 0; j < idx_points.size (); ++j)
        polygons[0].vertices[j] = j;

      polygons[0].vertices[idx_points.size ()] = 0;
    }
  }
  else
  {
    if (dim == 2)
    {
      // We want to sort the points
      Eigen::Vector4f centroid;
      pcl::compute3DCentroid (hull, centroid);
      centroid[3] = 0;
      polygons.resize (1);

      int num_vertices = qh num_vertices, dd = 0;

      // Copy all vertices
      std::vector<std::pair<int, Eigen::Vector4f>, Eigen::aligned_allocator<std::pair<int, Eigen::Vector4f> > > idx_points (num_vertices);

      FORALLvertices
      {
        idx_points[dd].first = qhid_to_pcidx[vertex->id];
        idx_points[dd].second = hull.points[idx_points[dd].first].getVector4fMap () - centroid;
        ++dd;
      }

      // Sort idx_points
      std::sort (idx_points.begin (), idx_points.end (), comparePoints2D);

      //Sort also points...
      PointCloud hull_sorted;
      hull_sorted.points.resize (hull.points.size ());

      for (size_t j = 0; j < idx_points.size (); ++j)
        hull_sorted.points[j] = hull.points[idx_points[j].first];

      hull.points = hull_sorted.points;
    }
  }

  // Deallocates memory (also the points)
  qh_freeqhull (!qh_ALL);
  fclose (errfile);

  // Rotate the hull point cloud by transform's inverse
  // If the input point cloud has been rotated
  if (dim == 2)
  {
    Eigen::Affine3f transInverse = transform1.inverse ();
    pcl::transformPointCloud (hull, hull, transInverse);
  }

  xyz_centroid[0] = -xyz_centroid[0];
  xyz_centroid[1] = -xyz_centroid[1];
  xyz_centroid[2] = -xyz_centroid[2];
  pcl::demeanPointCloud (hull, xyz_centroid, hull);

  hull.width = hull.points.size ();
  hull.height = 1;
  hull.is_dense = true;
}

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::reconstruct (PointCloud &output)
{
  output.header = input_->header;
  if (!initCompute ())
  {
    output.points.clear ();
    return;
  }

  // Perform the actual surface reconstruction
  std::vector<pcl::Vertices> polygons;
  performReconstruction (output, polygons, false);

  output.width = output.points.size ();
  output.height = 1;
  output.is_dense = true;

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::reconstruct (PointCloud &points,
                                        std::vector<pcl::Vertices> &polygons)
{
  points.header = input_->header;
  if (!initCompute ())
  {
    points.points.clear ();
    return;
  }

  // Perform the actual surface reconstruction
  performReconstruction (points, polygons, true);

  points.width = points.points.size ();
  points.height = 1;
  points.is_dense = true;

  deinitCompute ();
}

#define PCL_INSTANTIATE_ConvexHull(T) template class pcl::ConvexHull<T>;

#endif    // PCL_SURFACE_IMPL_CONVEX_HULL_H_
<commit_msg>fix stderr, reported by mfallon on irc<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, 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 Willow Garage, Inc. nor the names of its
 *     contributors 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.
 *
 * $Id$
 *
 */

#ifndef PCL_SURFACE_IMPL_CONVEX_HULL_H_
#define PCL_SURFACE_IMPL_CONVEX_HULL_H_

#include "pcl/surface/convex_hull.h"
#include "pcl/common/common.h"
#include "pcl/registration/transforms.h"

#ifndef _WIN32
  #if defined(__cplusplus)
  extern "C"
  {
  #endif
#  include <stdio.h>
#  include <stdlib.h>
#  include "qhull/qhull.h"
#  include "qhull/mem.h"
#  include "qhull/qset.h"
#  include "qhull/geom.h"
#  include "qhull/merge.h"
#  include "qhull/poly.h"
#  include "qhull/io.h"
#  include "qhull/stat.h"
  #if defined(__cplusplus)
  }
  #endif
#else
#  include <stdio.h>
#  include <stdlib.h>
#  include "libqhull/qhull.h"
#  include "libqhull/mem.h"
#  include "libqhull/qset.h"
#  include "libqhull/geom.h"
#  include "libqhull/merge.h"
#  include "libqhull/poly.h"
#  include "libqhull/io.h"
#  include "libqhull/stat.h"
#endif

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::performReconstruction (PointCloud &hull,
                                                  std::vector<pcl::Vertices> &polygons,
                                                  bool fill_polygon_data)
{
  // FInd the principal directions
  EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  Eigen::Vector4f xyz_centroid;
  compute3DCentroid (*input_, *indices_, xyz_centroid);
  computeCovarianceMatrix (*input_, *indices_, xyz_centroid, covariance_matrix);
  EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  EIGEN_ALIGN16 Eigen::Matrix3f eigen_vectors;
  pcl::eigen33 (covariance_matrix, eigen_vectors, eigen_values);

  Eigen::Affine3f transform1;
  transform1.setIdentity ();
  int dim = 3;

  if (eigen_values[0] / eigen_values[2] < 1.0e-5)
  {
    // We have points laying on a plane, using 2d convex hull
    // Compute transformation bring eigen_vectors.col(i) to z-axis

    eigen_vectors.col (2) = eigen_vectors.col (0).cross (eigen_vectors.col (1));
    eigen_vectors.col (1) = eigen_vectors.col (2).cross (eigen_vectors.col (0));

    transform1 (0, 2) = eigen_vectors (0, 0);
    transform1 (1, 2) = eigen_vectors (1, 0);
    transform1 (2, 2) = eigen_vectors (2, 0);

    transform1 (0, 1) = eigen_vectors (0, 1);
    transform1 (1, 1) = eigen_vectors (1, 1);
    transform1 (2, 1) = eigen_vectors (2, 1);
    transform1 (0, 0) = eigen_vectors (0, 2);
    transform1 (1, 0) = eigen_vectors (1, 2);
    transform1 (2, 0) = eigen_vectors (2, 2);

    transform1 = transform1.inverse ();
    dim = 2;
  }
  else
    transform1.setIdentity ();

  PointCloud cloud_transformed;
  pcl::demeanPointCloud (*input_, *indices_, xyz_centroid, cloud_transformed);
  pcl::transformPointCloud (cloud_transformed, cloud_transformed, transform1);

  // True if qhull should free points in qh_freeqhull() or reallocation
  boolT ismalloc = True;
  // option flags for qhull, see qh_opt.htm
  char flags[] = "qhull Tc";
  // output from qh_produce_output(), use NULL to skip qh_produce_output()
  FILE *outfile = NULL;
  // error messages from qhull code
  FILE *errfile = stderr;
  // 0 if no error from qhull
  int exitcode;

  // Array of coordinates for each point
  coordT *points = (coordT *)calloc (cloud_transformed.points.size () * dim, sizeof (coordT));

  for (size_t i = 0; i < cloud_transformed.points.size (); ++i)
  {
    points[i * dim + 0] = (coordT)cloud_transformed.points[i].x;
    points[i * dim + 1] = (coordT)cloud_transformed.points[i].y;

    if (dim > 2)
      points[i * dim + 2] = (coordT)cloud_transformed.points[i].z;
  }

  // Compute convex hull
  exitcode = qh_new_qhull (dim, cloud_transformed.points.size (), points, ismalloc, flags, outfile, errfile);

  if (exitcode != 0) {
     PCL_ERROR("ERROR: qhull was unable to compute a convex hull for the given point cloud");

     //check if it fails because of NaN values...
     if (!cloud_transformed.is_dense) {

       PCL_WARN("Checking for Nans");

       bool NaNvalues = false;
       for (size_t i = 0; i < cloud_transformed.size (); ++i)
         {
           if (!pcl_isfinite (cloud_transformed.points[i].x)
               ||
               !pcl_isfinite (cloud_transformed.points[i].y)
               ||
               !pcl_isfinite (cloud_transformed.points[i].z)) {
             NaNvalues = true;
             break;
           }
         }

       if (NaNvalues)
         PCL_ERROR("ERROR: point cloud contains NaN values, consider running pcl::PassThrough filter first to remove NaNs.");

     }

     hull.points.resize (0);
     hull.width = hull.height = 0;
     polygons.resize (0);
     return;
  }

  qh_triangulate ();

  int num_facets = qh num_facets;

  int num_vertices = qh num_vertices;
  hull.points.resize (num_vertices);

  vertexT *vertex;
  int i = 0;
  // Max vertex id
  int max_vertex_id = -1;
  FORALLvertices
  {
    if ((int)vertex->id > max_vertex_id)
      max_vertex_id = vertex->id;
  }

  ++max_vertex_id;
  std::vector<int> qhid_to_pcidx (max_vertex_id);

  FORALLvertices
  {
    // Add vertices to hull point_cloud
    hull.points[i].x = vertex->point[0];
    hull.points[i].y = vertex->point[1];

    if (dim>2)
    hull.points[i].z = vertex->point[2];
    else
    hull.points[i].z = 0;

    qhid_to_pcidx[vertex->id] = i; // map the vertex id of qhull to the point cloud index
    ++i;
  }

  if (fill_polygon_data)
  {
    if (dim == 3)
    {
      polygons.resize (num_facets);
      int dd = 0;

      facetT *facet;
      FORALLfacets
      {
        polygons[dd].vertices.resize (3);

        // Needed by FOREACHvertex_i_
        int vertex_n, vertex_i;
        FOREACHvertex_i_((*facet).vertices)
          //facet_vertices.vertices.push_back (qhid_to_pcidx[vertex->id]);
          polygons[dd].vertices[vertex_i] = qhid_to_pcidx[vertex->id];

        ++dd;
      }
    }
    else
    {
      // dim=2, we want to return just a polygon with all vertices sorted
      // so that they form a non-intersecting polygon...
      // this can be moved to the upper loop probably and here just
      // the sorting + populate

      Eigen::Vector4f centroid;
      pcl::compute3DCentroid (hull, centroid);
      centroid[3] = 0;
      polygons.resize (1);

      int num_vertices = qh num_vertices, dd = 0;

      // Copy all vertices
      std::vector<std::pair<int, Eigen::Vector4f>, Eigen::aligned_allocator<std::pair<int, Eigen::Vector4f> > > idx_points (num_vertices);

      FORALLvertices
      {
        idx_points[dd].first = qhid_to_pcidx[vertex->id];
        idx_points[dd].second = hull.points[idx_points[dd].first].getVector4fMap () - centroid;
        ++dd;
      }

      // Sort idx_points
      std::sort (idx_points.begin (), idx_points.end (), comparePoints2D);
      polygons[0].vertices.resize (idx_points.size () + 1);

      //Sort also points...
      PointCloud hull_sorted;
      hull_sorted.points.resize (hull.points.size ());

      for (size_t j = 0; j < idx_points.size (); ++j)
        hull_sorted.points[j] = hull.points[idx_points[j].first];

      hull.points = hull_sorted.points;

      // Populate points
      for (size_t j = 0; j < idx_points.size (); ++j)
        polygons[0].vertices[j] = j;

      polygons[0].vertices[idx_points.size ()] = 0;
    }
  }
  else
  {
    if (dim == 2)
    {
      // We want to sort the points
      Eigen::Vector4f centroid;
      pcl::compute3DCentroid (hull, centroid);
      centroid[3] = 0;
      polygons.resize (1);

      int num_vertices = qh num_vertices, dd = 0;

      // Copy all vertices
      std::vector<std::pair<int, Eigen::Vector4f>, Eigen::aligned_allocator<std::pair<int, Eigen::Vector4f> > > idx_points (num_vertices);

      FORALLvertices
      {
        idx_points[dd].first = qhid_to_pcidx[vertex->id];
        idx_points[dd].second = hull.points[idx_points[dd].first].getVector4fMap () - centroid;
        ++dd;
      }

      // Sort idx_points
      std::sort (idx_points.begin (), idx_points.end (), comparePoints2D);

      //Sort also points...
      PointCloud hull_sorted;
      hull_sorted.points.resize (hull.points.size ());

      for (size_t j = 0; j < idx_points.size (); ++j)
        hull_sorted.points[j] = hull.points[idx_points[j].first];

      hull.points = hull_sorted.points;
    }
  }

  // Deallocates memory (also the points)
  qh_freeqhull (!qh_ALL);

  // Rotate the hull point cloud by transform's inverse
  // If the input point cloud has been rotated
  if (dim == 2)
  {
    Eigen::Affine3f transInverse = transform1.inverse ();
    pcl::transformPointCloud (hull, hull, transInverse);
  }

  xyz_centroid[0] = -xyz_centroid[0];
  xyz_centroid[1] = -xyz_centroid[1];
  xyz_centroid[2] = -xyz_centroid[2];
  pcl::demeanPointCloud (hull, xyz_centroid, hull);

  hull.width = hull.points.size ();
  hull.height = 1;
  hull.is_dense = true;
}

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::reconstruct (PointCloud &output)
{
  output.header = input_->header;
  if (!initCompute ())
  {
    output.points.clear ();
    return;
  }

  // Perform the actual surface reconstruction
  std::vector<pcl::Vertices> polygons;
  performReconstruction (output, polygons, false);

  output.width = output.points.size ();
  output.height = 1;
  output.is_dense = true;

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////
template<typename PointInT> void
pcl::ConvexHull<PointInT>::reconstruct (PointCloud &points,
                                        std::vector<pcl::Vertices> &polygons)
{
  points.header = input_->header;
  if (!initCompute ())
  {
    points.points.clear ();
    return;
  }

  // Perform the actual surface reconstruction
  performReconstruction (points, polygons, true);

  points.width = points.points.size ();
  points.height = 1;
  points.is_dense = true;

  deinitCompute ();
}

#define PCL_INSTANTIATE_ConvexHull(T) template class pcl::ConvexHull<T>;

#endif    // PCL_SURFACE_IMPL_CONVEX_HULL_H_
<|endoftext|>


<commit_before>#include "SoloFeature.h"
#include "serviceFuns.cpp"
#include <math.h>

void SoloFeature::cellFiltering()
{

    if (pSolo.cellFilter.type[0]=="None" ||  nCB<1)
        return;
    if (featureType!=SoloFeatureTypes::Gene && featureType!=SoloFeatureTypes::GeneFull && featureType!=-1) {
        return;
    };

    //simple filtering first
    nUMIperCBsorted=nUMIperCB;
    qsort(nUMIperCBsorted.data(), nCB, sizeof(uint32), funCompareNumbersReverse<uint32>); //sort by gene number

    uint32 nUMImax=0, nUMImin=0;
    if (pSolo.cellFilter.type[0]=="TopCells") {
        nUMImin = nUMIperCBsorted[max(nCB-1,pSolo.cellFilter.topCells)];
    } else {//other filtering types require simple filtering first
        //find robust max
        uint32 maxind=int(round(pSolo.cellFilter.knee.nExpectedCells*(1.0-pSolo.cellFilter.knee.maxPercentile)));//cell number for robust max
        nUMImax = nUMIperCBsorted[min(nCB-1,maxind)];//robust estimate of the max UMI
        nUMImin = int(round(nUMImax/pSolo.cellFilter.knee.maxMinRatio));
    };
    nUMImin=max(nUMImin,(uint32) 1);//cannot be zero

    filteredCells.nCellsSimple=0;
    cellFilterVec.resize(nCB,false);
    for (uint32 icb=0; icb<nCB; icb++) {
        if (nUMIperCB[icb]>=nUMImin) {
            cellFilterVec[icb]=true;
            filteredCells.nCellsSimple++;
        };
    };

    P.inOut->logMain << "cellFiltering: simple: nUMImax="<< nUMImax <<"; nUMImin="<< nUMImin <<"; nCellsSimple="<< filteredCells.nCellsSimple <<endl;

    if (pSolo.cellFilter.type[0]=="EmptyDrops_CR") {
        emptyDrops_CR();
    };

    //filtering is done: cellFilterVec=true for kept cells, calculate statistics
    memset(&filteredCells,0,sizeof(filteredCells)); //init to 0 all stats

    bool *geneDetected = new bool[featuresNumber];
    memset((void*) geneDetected, 0, featuresNumber);

    for (uint32 icb=0; icb<nCB; icb++) {
        if (cellFilterVec[icb]) {

            filteredCells.nCells++;

            filteredCells.nUMIinCells += nUMIperCB[icb];

            filteredCells.nGeneInCells += nGenePerCB[icb];
            filteredCells.nGenePerCell.push_back(nGenePerCB[icb]);

            filteredCells.nReadInCells += nReadPerCB[icb];
            filteredCells.nReadPerCell.push_back(nReadPerCB[icb]);

            for (uint32 ig=0; ig<nGenePerCB[icb]; ig++) {
                uint32 indG1=countCellGeneUMIindex[icb]+ig*countMatStride;
                geneDetected[countCellGeneUMI[indG1]]=true;
            };
        };
    };

    if (filteredCells.nCells==0) {//all stats were already set to 0
        return;
    };

    filteredCells.nGeneDetected=0;
    for (uint32 ii=0; ii<featuresNumber; ii++) {
        if (geneDetected[ii])
            filteredCells.nGeneDetected++;
    };

    filteredCells.meanUMIperCell = filteredCells.nUMIinCells / filteredCells.nCells;
    filteredCells.meanReadPerCell = filteredCells.nReadInCells / filteredCells.nCells;
    filteredCells.meanGenePerCell = filteredCells.nGeneInCells / filteredCells.nCells;

    sort(filteredCells.nReadPerCell.begin(), filteredCells.nReadPerCell.end());
    sort(filteredCells.nGenePerCell.begin(), filteredCells.nGenePerCell.end());

    filteredCells.medianUMIperCell = nUMIperCBsorted[filteredCells.nCells/2];
    filteredCells.medianGenePerCell = filteredCells.nGenePerCell[filteredCells.nCells/2];
    filteredCells.medianReadPerCell = filteredCells.nReadPerCell[filteredCells.nCells/2];

    outputResults(true, outputPrefix + "filtered/");

    return;
};
<commit_msg>Update SoloFeature_cellFiltering.cpp<commit_after>#include "SoloFeature.h"
#include "serviceFuns.cpp"
#include <math.h>

void SoloFeature::cellFiltering()
{

    if (pSolo.cellFilter.type[0]=="None" ||  nCB<1)
        return;
    if (featureType!=SoloFeatureTypes::Gene && featureType!=SoloFeatureTypes::GeneFull && featureType!=-1) {
        return;
    };

    //simple filtering first
    nUMIperCBsorted=nUMIperCB;
    qsort(nUMIperCBsorted.data(), nCB, sizeof(uint32), funCompareNumbersReverse<uint32>); //sort by gene number

    uint32 nUMImax=0, nUMImin=0;
    if (pSolo.cellFilter.type[0]=="TopCells") {
        nUMImin = nUMIperCBsorted[min(nCB-1,pSolo.cellFilter.topCells)];
    } else {//other filtering types require simple filtering first
        //find robust max
        uint32 maxind=int(round(pSolo.cellFilter.knee.nExpectedCells*(1.0-pSolo.cellFilter.knee.maxPercentile)));//cell number for robust max
        nUMImax = nUMIperCBsorted[min(nCB-1,maxind)];//robust estimate of the max UMI
        nUMImin = int(round(nUMImax/pSolo.cellFilter.knee.maxMinRatio));
    };
    nUMImin=max(nUMImin,(uint32) 1);//cannot be zero

    filteredCells.nCellsSimple=0;
    cellFilterVec.resize(nCB,false);
    for (uint32 icb=0; icb<nCB; icb++) {
        if (nUMIperCB[icb]>=nUMImin) {
            cellFilterVec[icb]=true;
            filteredCells.nCellsSimple++;
        };
    };

    P.inOut->logMain << "cellFiltering: simple: nUMImax="<< nUMImax <<"; nUMImin="<< nUMImin <<"; nCellsSimple="<< filteredCells.nCellsSimple <<endl;

    if (pSolo.cellFilter.type[0]=="EmptyDrops_CR") {
        emptyDrops_CR();
    };

    //filtering is done: cellFilterVec=true for kept cells, calculate statistics
    memset(&filteredCells,0,sizeof(filteredCells)); //init to 0 all stats

    bool *geneDetected = new bool[featuresNumber];
    memset((void*) geneDetected, 0, featuresNumber);

    for (uint32 icb=0; icb<nCB; icb++) {
        if (cellFilterVec[icb]) {

            filteredCells.nCells++;

            filteredCells.nUMIinCells += nUMIperCB[icb];

            filteredCells.nGeneInCells += nGenePerCB[icb];
            filteredCells.nGenePerCell.push_back(nGenePerCB[icb]);

            filteredCells.nReadInCells += nReadPerCB[icb];
            filteredCells.nReadPerCell.push_back(nReadPerCB[icb]);

            for (uint32 ig=0; ig<nGenePerCB[icb]; ig++) {
                uint32 indG1=countCellGeneUMIindex[icb]+ig*countMatStride;
                geneDetected[countCellGeneUMI[indG1]]=true;
            };
        };
    };

    if (filteredCells.nCells==0) {//all stats were already set to 0
        return;
    };

    filteredCells.nGeneDetected=0;
    for (uint32 ii=0; ii<featuresNumber; ii++) {
        if (geneDetected[ii])
            filteredCells.nGeneDetected++;
    };

    filteredCells.meanUMIperCell = filteredCells.nUMIinCells / filteredCells.nCells;
    filteredCells.meanReadPerCell = filteredCells.nReadInCells / filteredCells.nCells;
    filteredCells.meanGenePerCell = filteredCells.nGeneInCells / filteredCells.nCells;

    sort(filteredCells.nReadPerCell.begin(), filteredCells.nReadPerCell.end());
    sort(filteredCells.nGenePerCell.begin(), filteredCells.nGenePerCell.end());

    filteredCells.medianUMIperCell = nUMIperCBsorted[filteredCells.nCells/2];
    filteredCells.medianGenePerCell = filteredCells.nGenePerCell[filteredCells.nCells/2];
    filteredCells.medianReadPerCell = filteredCells.nReadPerCell[filteredCells.nCells/2];

    outputResults(true, outputPrefix + "filtered/");

    return;
};
<|endoftext|>