<commit_before>#ifndef __AXIS_HPP
#define __AXIS_HPP

#ifndef __ODRIVE_MAIN_HPP
#error "This file should not be included directly. Include odrive_main.hpp instead."
#endif

// Warning: Do not reorder these enum values.
// The state machine uses ">" comparision on them.
enum AxisState_t {
    AXIS_STATE_UNDEFINED = 0,           //<! will fall through to idle
    AXIS_STATE_IDLE = 1,                //<! disable PWM and do nothing
    AXIS_STATE_STARTUP_SEQUENCE = 2, //<! the actual sequence is defined by the config.startup_... flags
    AXIS_STATE_FULL_CALIBRATION_SEQUENCE = 3,   //<! run all calibration procedures, then idle
    AXIS_STATE_MOTOR_CALIBRATION = 4,   //<! run motor calibration
    AXIS_STATE_SENSORLESS_CONTROL = 5,  //<! run sensorless calibration
    AXIS_STATE_ENCODER_INDEX_SEARCH = 6, //<! run encoder index search
    AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7, //<! run encoder offset calibration
    AXIS_STATE_CLOSED_LOOP_CONTROL = 8  //<! run closed loop control
};

struct AxisConfig_t {
    bool startup_motor_calibration = false;   //<! run motor calibration at startup, skip otherwise
    bool startup_encoder_index_search = false; //<! run encoder index search after startup, skip otherwise
                                               // this only has an effect if encoder.config.use_index is also true
    bool startup_encoder_offset_calibration = false; //<! run encoder offset calibration after startup, skip otherwise
    bool startup_closed_loop_control = false; //<! enable closed loop control after calibration/startup
    bool startup_sensorless_control = false; //<! enable sensorless control after calibration/startup
    bool enable_step_dir = true; //<! enable step/dir input after calibration
                                 //   For M0 this has no effect if enable_uart is true

    float counts_per_step = 2.0f;
    float dc_bus_brownout_trip_level = 8.0f; //<! [V] voltage at which the motor stops operating

    // Spinup settings
    float ramp_up_time = 0.4f;            // [s]
    float ramp_up_distance = 4 * M_PI;    // [rad]
    float spin_up_current = 10.0f;        // [A]
    float spin_up_acceleration = 400.0f;  // [rad/s^2]
    float spin_up_target_vel = 400.0f;    // [rad/s]
};

class Axis {
public:
    enum Error_t {
        ERROR_NO_ERROR = 0x00,
        ERROR_INVALID_STATE = 0x01, //<! an invalid state was requested
        ERROR_DC_BUS_UNDER_VOLTAGE = 0x02,
        ERROR_DC_BUS_OVER_VOLTAGE = 0x04,
        ERROR_CURRENT_MEASUREMENT_TIMEOUT = 0x08,
        ERROR_MOTOR_DISARMED = 0x10, //<! the motor was unexpectedly disarmed
        ERROR_MOTOR_FAILED = 0x20,
        ERROR_SENSORLESS_ESTIMATOR_FAILED = 0x40,
        ERROR_ENCODER_FAILED = 0x80,
        ERROR_CONTROLLER_FAILED = 0x100,
        ERROR_POS_CTRL_DURING_SENSORLESS = 0x200,
    };

    enum thread_signals {
        M_SIGNAL_PH_CURRENT_MEAS = 1u << 0
    };

    Axis(const AxisHardwareConfig_t& hw_config,
            AxisConfig_t& config,
            Encoder& encoder,
            SensorlessEstimator& sensorless_estimator,
            Controller& controller,
            Motor& motor);

    void setup();
    void start_thread();
    void signal_current_meas();
    bool wait_for_current_meas();

    void step_cb();
    void set_step_dir_enabled(bool enable);

    bool check_DRV_fault();
    bool check_PSU_brownout();
    bool do_checks();

    // @brief Runs the specified update handler at the frequency of the current measurements.
    //
    // The loop runs until one of the following conditions:
    //  - update_handler returns false
    //  - the current measurement times out
    //  - the health checks fail (brownout, driver fault line)
    //  - update_handler doesn't update the modulation timings in time
    //    This criterion is ignored if current_state is AXIS_STATE_IDLE
    //
    // If update_handler is going to update the motor timings, you must call motor.arm()
    // shortly before this function.
    //
    // If the function returns, it is guaranteed that error is non-zero, except if the cause
    // for the exit was a negative return value of update_handler or an external
    // state change request (requested_state != AXIS_STATE_DONT_CARE).
    // Under all exit conditions the motor is disarmed and the brake current set to zero.
    // Furthermore, if the update_handler does not set the phase voltages in time, they will
    // go to zero.
    //
    // @tparam T Must be a callable type that takes no arguments and returns a bool
    template<typename T>
    void run_control_loop(const T& update_handler) {
        while (requested_state_ == AXIS_STATE_UNDEFINED) {
            if ((current_state_ != AXIS_STATE_IDLE) && (motor_.armed_state_ == Motor::ARMED_STATE_DISARMED)) {
                // motor got disarmed in something other than the idle loop
                error_ |= ERROR_MOTOR_DISARMED;
                break;
            }
            if (motor_.error_ != Motor::ERROR_NO_ERROR) {
                error_ |= ERROR_MOTOR_FAILED;
                break;
            }

            if (!do_checks()) // error set during function call
                break;

            if (!update_handler()) // error set during function call
                break;

            // Check we meet deadlines after queueing
            ++loop_counter_;

            // Wait until the current measurement interrupt fires
            if (!wait_for_current_meas()) {
                // maybe the interrupt handler is dead, let's be
                // safe and float the phases
                safety_critical_disarm_motor_pwm(motor_);
                update_brake_current();
                error_ |= ERROR_CURRENT_MEASUREMENT_TIMEOUT;
                break;
            }
        }
    }

    bool run_sensorless_spin_up();
    bool run_sensorless_control_loop();
    bool run_closed_loop_control_loop();
    bool run_idle_loop();

    void run_state_machine_loop();

    const AxisHardwareConfig_t& hw_config_;
    AxisConfig_t& config_;

    Encoder& encoder_;
    SensorlessEstimator& sensorless_estimator_;
    Controller& controller_;
    Motor& motor_;

    osThreadId thread_id_;
    volatile bool thread_id_valid_ = false;

    // variables exposed on protocol
    Error_t error_ = ERROR_NO_ERROR;
    bool enable_step_dir_ = false; // auto enabled after calibration, based on config.enable_step_dir
    AxisState_t requested_state_ = AXIS_STATE_STARTUP_SEQUENCE;
    AxisState_t task_chain_[10] = { AXIS_STATE_UNDEFINED };
    AxisState_t& current_state_ = task_chain_[0];
    uint32_t loop_counter_ = 0;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("error", &error_),
            make_protocol_property("enable_step_dir", &enable_step_dir_),
            make_protocol_ro_property("current_state", &current_state_),
            make_protocol_property("requested_state", &requested_state_),
            make_protocol_ro_property("loop_counter", &loop_counter_),
            make_protocol_object("config",
                make_protocol_property("startup_motor_calibration", &config_.startup_motor_calibration),
                make_protocol_property("startup_encoder_index_search", &config_.startup_encoder_index_search),
                make_protocol_property("startup_encoder_offset_calibration", &config_.startup_encoder_offset_calibration),
                make_protocol_property("startup_closed_loop_control", &config_.startup_closed_loop_control),
                make_protocol_property("startup_sensorless_control", &config_.startup_sensorless_control),
                make_protocol_property("enable_step_dir", &config_.enable_step_dir),
                make_protocol_property("counts_per_step", &config_.counts_per_step),
                make_protocol_property("dc_bus_brownout_trip_level", &config_.dc_bus_brownout_trip_level),
                make_protocol_property("ramp_up_time", &config_.ramp_up_time),
                make_protocol_property("ramp_up_distance", &config_.ramp_up_distance),
                make_protocol_property("spin_up_current", &config_.spin_up_current),
                make_protocol_property("spin_up_acceleration", &config_.spin_up_acceleration),
                make_protocol_property("spin_up_target_vel", &config_.spin_up_target_vel)
            ),
            make_protocol_object("motor", motor_.make_protocol_definitions()),
            make_protocol_object("controller", controller_.make_protocol_definitions()),
            make_protocol_object("encoder", encoder_.make_protocol_definitions()),
            make_protocol_object("sensorless_estimator", sensorless_estimator_.make_protocol_definitions())
        );
    }
};

DEFINE_ENUM_FLAG_OPERATORS(Axis::Error_t)

#endif /* __AXIS_HPP */
<commit_msg>add Axis::ERROR_BRAKE_RESISTOR_DISARMED<commit_after>#ifndef __AXIS_HPP
#define __AXIS_HPP

#ifndef __ODRIVE_MAIN_HPP
#error "This file should not be included directly. Include odrive_main.hpp instead."
#endif

// Warning: Do not reorder these enum values.
// The state machine uses ">" comparision on them.
enum AxisState_t {
    AXIS_STATE_UNDEFINED = 0,           //<! will fall through to idle
    AXIS_STATE_IDLE = 1,                //<! disable PWM and do nothing
    AXIS_STATE_STARTUP_SEQUENCE = 2, //<! the actual sequence is defined by the config.startup_... flags
    AXIS_STATE_FULL_CALIBRATION_SEQUENCE = 3,   //<! run all calibration procedures, then idle
    AXIS_STATE_MOTOR_CALIBRATION = 4,   //<! run motor calibration
    AXIS_STATE_SENSORLESS_CONTROL = 5,  //<! run sensorless calibration
    AXIS_STATE_ENCODER_INDEX_SEARCH = 6, //<! run encoder index search
    AXIS_STATE_ENCODER_OFFSET_CALIBRATION = 7, //<! run encoder offset calibration
    AXIS_STATE_CLOSED_LOOP_CONTROL = 8  //<! run closed loop control
};

struct AxisConfig_t {
    bool startup_motor_calibration = false;   //<! run motor calibration at startup, skip otherwise
    bool startup_encoder_index_search = false; //<! run encoder index search after startup, skip otherwise
                                               // this only has an effect if encoder.config.use_index is also true
    bool startup_encoder_offset_calibration = false; //<! run encoder offset calibration after startup, skip otherwise
    bool startup_closed_loop_control = false; //<! enable closed loop control after calibration/startup
    bool startup_sensorless_control = false; //<! enable sensorless control after calibration/startup
    bool enable_step_dir = true; //<! enable step/dir input after calibration
                                 //   For M0 this has no effect if enable_uart is true

    float counts_per_step = 2.0f;
    float dc_bus_brownout_trip_level = 8.0f; //<! [V] voltage at which the motor stops operating

    // Spinup settings
    float ramp_up_time = 0.4f;            // [s]
    float ramp_up_distance = 4 * M_PI;    // [rad]
    float spin_up_current = 10.0f;        // [A]
    float spin_up_acceleration = 400.0f;  // [rad/s^2]
    float spin_up_target_vel = 400.0f;    // [rad/s]
};

class Axis {
public:
    enum Error_t {
        ERROR_NO_ERROR = 0x00,
        ERROR_INVALID_STATE = 0x01, //<! an invalid state was requested
        ERROR_DC_BUS_UNDER_VOLTAGE = 0x02,
        ERROR_DC_BUS_OVER_VOLTAGE = 0x04,
        ERROR_CURRENT_MEASUREMENT_TIMEOUT = 0x08,
        ERROR_BRAKE_RESISTOR_DISARMED = 0x10, //<! the brake resistor was unexpectedly disarmed
        ERROR_MOTOR_DISARMED = 0x20, //<! the motor was unexpectedly disarmed
        ERROR_MOTOR_FAILED = 0x40,
        ERROR_SENSORLESS_ESTIMATOR_FAILED = 0x80,
        ERROR_ENCODER_FAILED = 0x100,
        ERROR_CONTROLLER_FAILED = 0x200,
        ERROR_POS_CTRL_DURING_SENSORLESS = 0x400,
    };

    enum thread_signals {
        M_SIGNAL_PH_CURRENT_MEAS = 1u << 0
    };

    Axis(const AxisHardwareConfig_t& hw_config,
            AxisConfig_t& config,
            Encoder& encoder,
            SensorlessEstimator& sensorless_estimator,
            Controller& controller,
            Motor& motor);

    void setup();
    void start_thread();
    void signal_current_meas();
    bool wait_for_current_meas();

    void step_cb();
    void set_step_dir_enabled(bool enable);

    bool check_DRV_fault();
    bool check_PSU_brownout();
    bool do_checks();

    // @brief Runs the specified update handler at the frequency of the current measurements.
    //
    // The loop runs until one of the following conditions:
    //  - update_handler returns false
    //  - the current measurement times out
    //  - the health checks fail (brownout, driver fault line)
    //  - update_handler doesn't update the modulation timings in time
    //    This criterion is ignored if current_state is AXIS_STATE_IDLE
    //
    // If update_handler is going to update the motor timings, you must call motor.arm()
    // shortly before this function.
    //
    // If the function returns, it is guaranteed that error is non-zero, except if the cause
    // for the exit was a negative return value of update_handler or an external
    // state change request (requested_state != AXIS_STATE_DONT_CARE).
    // Under all exit conditions the motor is disarmed and the brake current set to zero.
    // Furthermore, if the update_handler does not set the phase voltages in time, they will
    // go to zero.
    //
    // @tparam T Must be a callable type that takes no arguments and returns a bool
    template<typename T>
    void run_control_loop(const T& update_handler) {
        while (requested_state_ == AXIS_STATE_UNDEFINED) {
            if (!brake_resistor_armed_) {
                error_ |= ERROR_BRAKE_RESISTOR_DISARMED;
                break;
            }
            if ((current_state_ != AXIS_STATE_IDLE) && (motor_.armed_state_ == Motor::ARMED_STATE_DISARMED)) {
                // motor got disarmed in something other than the idle loop
                error_ |= ERROR_MOTOR_DISARMED;
                break;
            }
            if (motor_.error_ != Motor::ERROR_NO_ERROR) {
                error_ |= ERROR_MOTOR_FAILED;
                break;
            }

            if (!do_checks()) // error set during function call
                break;

            if (!update_handler()) // error set during function call
                break;

            // Check we meet deadlines after queueing
            ++loop_counter_;

            // Wait until the current measurement interrupt fires
            if (!wait_for_current_meas()) {
                // maybe the interrupt handler is dead, let's be
                // safe and float the phases
                safety_critical_disarm_motor_pwm(motor_);
                update_brake_current();
                error_ |= ERROR_CURRENT_MEASUREMENT_TIMEOUT;
                break;
            }
        }
    }

    bool run_sensorless_spin_up();
    bool run_sensorless_control_loop();
    bool run_closed_loop_control_loop();
    bool run_idle_loop();

    void run_state_machine_loop();

    const AxisHardwareConfig_t& hw_config_;
    AxisConfig_t& config_;

    Encoder& encoder_;
    SensorlessEstimator& sensorless_estimator_;
    Controller& controller_;
    Motor& motor_;

    osThreadId thread_id_;
    volatile bool thread_id_valid_ = false;

    // variables exposed on protocol
    Error_t error_ = ERROR_NO_ERROR;
    bool enable_step_dir_ = false; // auto enabled after calibration, based on config.enable_step_dir
    AxisState_t requested_state_ = AXIS_STATE_STARTUP_SEQUENCE;
    AxisState_t task_chain_[10] = { AXIS_STATE_UNDEFINED };
    AxisState_t& current_state_ = task_chain_[0];
    uint32_t loop_counter_ = 0;

    // Communication protocol definitions
    auto make_protocol_definitions() {
        return make_protocol_member_list(
            make_protocol_property("error", &error_),
            make_protocol_property("enable_step_dir", &enable_step_dir_),
            make_protocol_ro_property("current_state", &current_state_),
            make_protocol_property("requested_state", &requested_state_),
            make_protocol_ro_property("loop_counter", &loop_counter_),
            make_protocol_object("config",
                make_protocol_property("startup_motor_calibration", &config_.startup_motor_calibration),
                make_protocol_property("startup_encoder_index_search", &config_.startup_encoder_index_search),
                make_protocol_property("startup_encoder_offset_calibration", &config_.startup_encoder_offset_calibration),
                make_protocol_property("startup_closed_loop_control", &config_.startup_closed_loop_control),
                make_protocol_property("startup_sensorless_control", &config_.startup_sensorless_control),
                make_protocol_property("enable_step_dir", &config_.enable_step_dir),
                make_protocol_property("counts_per_step", &config_.counts_per_step),
                make_protocol_property("dc_bus_brownout_trip_level", &config_.dc_bus_brownout_trip_level),
                make_protocol_property("ramp_up_time", &config_.ramp_up_time),
                make_protocol_property("ramp_up_distance", &config_.ramp_up_distance),
                make_protocol_property("spin_up_current", &config_.spin_up_current),
                make_protocol_property("spin_up_acceleration", &config_.spin_up_acceleration),
                make_protocol_property("spin_up_target_vel", &config_.spin_up_target_vel)
            ),
            make_protocol_object("motor", motor_.make_protocol_definitions()),
            make_protocol_object("controller", controller_.make_protocol_definitions()),
            make_protocol_object("encoder", encoder_.make_protocol_definitions()),
            make_protocol_object("sensorless_estimator", sensorless_estimator_.make_protocol_definitions())
        );
    }
};

DEFINE_ENUM_FLAG_OPERATORS(Axis::Error_t)

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


<commit_before>/*

DAcase2.c

This program connects to the DAQ data source passed as argument
and populates local "./result.txt" file with the ids of events received
during the run.

The program exits when being asked to shut down (daqDA_checkshutdown)
or End of Run event.

Messages on stdout are exported to DAQ log system.

contact: alice-datesupport@cern.ch

*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSCalibHistoProducer.h"
#include "AliPHOSRawDecoderv1.h"
#include "AliCaloAltroMapping.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* open result file */
  FILE *fp=NULL;
  fp=fopen("./result.txt","a");
  if (fp==NULL) {
    printf("Failed to open file\n");
    return -1;
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = gSystem->Getenv("ALICE_ROOT");
  path += "/PHOS/mapping/RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("DA example case2 monitoring program started\n");

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;

  AliPHOSDA1 da1(2); // DA1 (Calibration DA) for module2

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t gain = -1;
  Int_t X = -1;
  Int_t Z = -1;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {
      fprintf(fp,"Run #%lu, event size: %lu, BC:%u, Orbit:%u, Period:%u\n",
	  (unsigned long)event->eventRunNb,
        (unsigned long)event->eventSize,
        EVENT_ID_GET_BUNCH_CROSSING(event->eventId),
        EVENT_ID_GET_ORBIT(event->eventId),
        EVENT_ID_GET_PERIOD(event->eventId)
      );

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    e[iX][iZ][iGain] = 0.;
	    t[iX][iZ][iGain] = 0.;
	  }
	}
      }

      rawReader = new AliRawReaderDate((void*)event);
      AliPHOSRawDecoderv1 dc(rawReader,mapping);
      dc.SubtractPedestals(kTRUE);
      dc.SetOldRCUFormat(kTRUE);

      while(dc.NextDigit()) {

	X = dc.GetRow() - 1;
	Z = dc.GetColumn() - 1;

	if(dc.IsLowGain()) gain = 0;
	else
	  gain = 1;

	e[X][Z][gain] = dc.GetEnergy();
	t[X][Z][gain] = dc.GetTime();

      }

      da1.FillHistograms(e,t);
      //da1.UpdateHistoFile();

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* write report */
  fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result file */
  fclose(fp);

  return status;
}
<commit_msg>.h file name corrected.<commit_after>/*

DAcase2.c

This program connects to the DAQ data source passed as argument
and populates local "./result.txt" file with the ids of events received
during the run.

The program exits when being asked to shut down (daqDA_checkshutdown)
or End of Run event.

Messages on stdout are exported to DAQ log system.

contact: alice-datesupport@cern.ch

*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSDA1.h"
#include "AliPHOSRawDecoderv1.h"
#include "AliCaloAltroMapping.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* open result file */
  FILE *fp=NULL;
  fp=fopen("./result.txt","a");
  if (fp==NULL) {
    printf("Failed to open file\n");
    return -1;
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = gSystem->Getenv("ALICE_ROOT");
  path += "/PHOS/mapping/RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("DA example case2 monitoring program started\n");

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;

  AliPHOSDA1 da1(2); // DA1 (Calibration DA) for module2

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t gain = -1;
  Int_t X = -1;
  Int_t Z = -1;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {
      fprintf(fp,"Run #%lu, event size: %lu, BC:%u, Orbit:%u, Period:%u\n",
	  (unsigned long)event->eventRunNb,
        (unsigned long)event->eventSize,
        EVENT_ID_GET_BUNCH_CROSSING(event->eventId),
        EVENT_ID_GET_ORBIT(event->eventId),
        EVENT_ID_GET_PERIOD(event->eventId)
      );

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    e[iX][iZ][iGain] = 0.;
	    t[iX][iZ][iGain] = 0.;
	  }
	}
      }

      rawReader = new AliRawReaderDate((void*)event);
      AliPHOSRawDecoderv1 dc(rawReader,mapping);
      dc.SubtractPedestals(kTRUE);
      dc.SetOldRCUFormat(kTRUE);

      while(dc.NextDigit()) {

	X = dc.GetRow() - 1;
	Z = dc.GetColumn() - 1;

	if(dc.IsLowGain()) gain = 0;
	else
	  gain = 1;

	e[X][Z][gain] = dc.GetEnergy();
	t[X][Z][gain] = dc.GetTime();

      }

      da1.FillHistograms(e,t);
      //da1.UpdateHistoFile();

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* write report */
  fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result file */
  fclose(fp);

  return status;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkRotationFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkRotationFilter.h"

#include "vtkCellData.h"
#include "vtkGenericCell.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkUnstructuredGrid.h"
#include "vtkMath.h"

vtkCxxRevisionMacro(vtkRotationFilter, "1.7");
vtkStandardNewMacro(vtkRotationFilter);

//---------------------------------------------------------------------------
vtkRotationFilter::vtkRotationFilter()
{
  this->Axis = 2;
  this->CopyInput = 0;
  this->Center[0] = this->Center[1] = this->Center[2] = 0;
  this->NumberOfCopies = 0;
  this->Angle = 0;
}

//---------------------------------------------------------------------------
vtkRotationFilter::~vtkRotationFilter()
{
}

//---------------------------------------------------------------------------
void vtkRotationFilter::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Axis: " << this->Axis << endl;
  os << indent << "CopyInput: " << this->CopyInput << endl;
  os << indent << "Center: (" << this->Center[0] << "," << this->Center[1]
               << "," << this->Center[2] << ")" << endl;
  os << indent << "NumberOfCopies: " << this->NumberOfCopies << endl;
  os << indent << "Angle: " << this->Angle << endl;
}

//---------------------------------------------------------------------------
int vtkRotationFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkIdType i;
  vtkPointData *inPD = input->GetPointData();
  vtkPointData *outPD = output->GetPointData();
  vtkCellData *inCD = input->GetCellData();
  vtkCellData *outCD = output->GetCellData();

  if (!this->GetNumberOfCopies())
    {
    vtkErrorMacro("No number of copy set!");
    return 1;
    }

  double tuple[3];
  vtkPoints *outPoints;
  double point[3], center[3];
  int ptId, cellId, j, k;
  vtkGenericCell *cell = vtkGenericCell::New();
  vtkIdList *ptIds = vtkIdList::New();

  outPoints = vtkPoints::New();

  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();

  if (this->CopyInput)
    {
    outPoints->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
    output->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
    }
  else
    {
    outPoints->Allocate( this->GetNumberOfCopies() * numPts);
    output->Allocate( this->GetNumberOfCopies() * numPts);
    }

  outPD->CopyAllocate(inPD);
  outCD->CopyAllocate(inCD);

  vtkDataArray *inPtVectors, *outPtVectors, *inPtNormals, *outPtNormals;
  vtkDataArray *inCellVectors, *outCellVectors, *inCellNormals;
  vtkDataArray *outCellNormals;

  inPtVectors = inPD->GetVectors();
  outPtVectors = outPD->GetVectors();
  inPtNormals = inPD->GetNormals();
  outPtNormals = outPD->GetNormals();
  inCellVectors = inCD->GetVectors();
  outCellVectors = outCD->GetVectors();
  inCellNormals = inCD->GetNormals();
  outCellNormals = outCD->GetNormals();

  // Copy first points.
  if (this->CopyInput)
    {
    for (i = 0; i < numPts; i++)
      {
      input->GetPoint(i, point);
      ptId = outPoints->InsertNextPoint(point);
      outPD->CopyData(inPD, i, ptId);
      }
    }

  // Rotate points.
  double angle = this->GetAngle()*vtkMath::DegreesToRadians();
  this->GetCenter(center);
  switch (this->Axis)
    {
    case USE_X:
      for (k = 0; k < this->GetNumberOfCopies(); k++)
        {
         for (i = 0; i < numPts; i++)
           {
           input->GetPoint(i, point);
           ptId =
             outPoints->InsertNextPoint((point[0]-center[0]),
                                        (point[1]-center[1])*cos(angle*(1+k)) - (point[2]-center[2])*sin(angle*(1+k)),
                                        (point[1]-center[1])*sin(angle*(1+k)) + (point[2]-center[2])*cos(angle*(1+k)));
           outPD->CopyData(inPD, i, ptId);
           if (inPtVectors)
             {
             inPtVectors->GetTuple(i, tuple);
             outPtVectors->SetTuple(ptId, tuple);
             }
           if (inPtNormals)
             {
             inPtNormals->GetTuple(i, tuple);
            outPtNormals->SetTuple(ptId, tuple);
             }
           }
        }
    break;

    case USE_Y:
      for (k = 0; k < this->GetNumberOfCopies(); k++)
        {
         for (i = 0; i < numPts; i++)
           {
           input->GetPoint(i, point);
           ptId =
             outPoints->InsertNextPoint((point[0]-center[0])*cos(angle*(1+k)) + (point[2]-center[2])*sin(angle*(1+k)),
                                        (point[1]-center[1]),
                                       -(point[0]-center[0])*sin(angle*(1+k)) + (point[2]-center[2])*cos(angle*(1+k)));
           outPD->CopyData(inPD, i, ptId);
           if (inPtVectors)
             {
             inPtVectors->GetTuple(i, tuple);
             outPtVectors->SetTuple(ptId, tuple);
             }
           if (inPtNormals)
             {
             inPtNormals->GetTuple(i, tuple);
             outPtNormals->SetTuple(ptId, tuple);
            }
           }
        }
    break;

    case USE_Z:
      for (k = 0; k < this->GetNumberOfCopies(); k++)
        {
        for (i = 0; i < numPts; i++)
           {
          input->GetPoint(i, point);
          ptId =
            outPoints->InsertNextPoint( (point[0]-center[0])*cos(angle*(1+k)) - (point[1]-center[1])*sin(angle*(1+k)),
                                        (point[0]-center[0])*sin(angle*(1+k)) + (point[1]-center[1])*cos(angle*(1+k)),
                                        (point[2]-center[2]));
          outPD->CopyData(inPD, i, ptId);
          if (inPtVectors)
            {
            inPtVectors->GetTuple(i, tuple);
            outPtVectors->SetTuple(ptId, tuple);
            }
           if (inPtNormals)
             {
             inPtNormals->GetTuple(i, tuple);
             outPtNormals->SetTuple(ptId, tuple);
             }
           }
        }
      break;
    }

  int numCellPts,  cellType;
  vtkIdType *newCellPts;
  vtkIdList *cellPts;

  // Copy original cells.
  if (this->CopyInput)
    {
    for (i = 0; i < numCells; i++)
      {
      input->GetCellPoints(i, ptIds);
      output->InsertNextCell(input->GetCellType(i), ptIds);
      outCD->CopyData(inCD, i, i);
      }
    }

  // Generate rotated cells.
  for (k = 0; k < this->GetNumberOfCopies(); k++)
    {
    for (i = 0; i < numCells; i++)
      {
       input->GetCellPoints(i, ptIds);
       input->GetCell(i, cell);
       numCellPts = cell->GetNumberOfPoints();
       cellType = cell->GetCellType();
       cellPts = cell->GetPointIds();
      // Triangle strips with even number of triangles have
      // to be handled specially. A degenerate triangle is
      // introduce to flip all the triangles properly.
      if (cellType == VTK_TRIANGLE_STRIP && numCellPts % 2 == 0)
        {
        numCellPts++;
        newCellPts = new vtkIdType[numCellPts];
         newCellPts[0] = cellPts->GetId(0) + numPts;
        newCellPts[1] = cellPts->GetId(2) + numPts;
        newCellPts[2] = cellPts->GetId(1) + numPts;
        newCellPts[3] = cellPts->GetId(2) + numPts;
        for (j = 4; j < numCellPts; j++)
          {
          newCellPts[j] = cellPts->GetId(j-1) + numPts*k;
          if (this->CopyInput)
            {
            newCellPts[j] += numPts;
            }
          }
        }
      else
        {
        newCellPts = new vtkIdType[numCellPts];
        for (j = numCellPts-1; j >= 0; j--)
          {
          newCellPts[numCellPts-1-j] = cellPts->GetId(j) + numPts*k;
           if (this->CopyInput)
            {
             newCellPts[numCellPts-1-j] += numPts;
            }
          }
        }
      cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
      delete [] newCellPts;
      outCD->CopyData(inCD, i, cellId);
      if (inCellVectors)
        {
        inCellVectors->GetTuple(i, tuple);
        outCellVectors->SetTuple(cellId, tuple);
        }
      if (inCellNormals)
        {
        inCellNormals->GetTuple(i, tuple);
        outCellNormals->SetTuple(cellId, tuple);
        }
      }
    }

  cell->Delete();
  ptIds->Delete();
  output->SetPoints(outPoints);
  outPoints->Delete();
  output->CheckAttributes();

  return 1;
}

int vtkRotationFilter::FillInputPortInformation(int, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  return 1;
}
<commit_msg>ENH: Reworking of Rotation filter by J.Favre at cscs.ch. Change all hardwired transformation code to use vtkTransform<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRotationFilter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkRotationFilter.h"

#include "vtkCellData.h"
#include "vtkGenericCell.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkUnstructuredGrid.h"
#include "vtkMath.h"
#include "vtkTransform.h"

vtkCxxRevisionMacro(vtkRotationFilter, "1.8");
vtkStandardNewMacro(vtkRotationFilter);

//---------------------------------------------------------------------------
vtkRotationFilter::vtkRotationFilter()
{
  this->Axis = 2;
  this->CopyInput = 0;
  this->Center[0] = this->Center[1] = this->Center[2] = 0;
  this->NumberOfCopies = 0;
  this->Angle = 0;
}

//---------------------------------------------------------------------------
vtkRotationFilter::~vtkRotationFilter()
{
}

//---------------------------------------------------------------------------
void vtkRotationFilter::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Axis: " << this->Axis << endl;
  os << indent << "CopyInput: " << this->CopyInput << endl;
  os << indent << "Center: (" << this->Center[0] << "," << this->Center[1]
               << "," << this->Center[2] << ")" << endl;
  os << indent << "NumberOfCopies: " << this->NumberOfCopies << endl;
  os << indent << "Angle: " << this->Angle << endl;
}

//---------------------------------------------------------------------------
int vtkRotationFilter::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkIdType i;
  vtkPointData *inPD = input->GetPointData();
  vtkPointData *outPD = output->GetPointData();
  vtkCellData *inCD = input->GetCellData();
  vtkCellData *outCD = output->GetCellData();

  if (!this->GetNumberOfCopies())
    {
    vtkErrorMacro("No number of copy set!");
    return 1;
    }

  double tuple[3];
  vtkPoints *outPoints;
  double point[3], center[3], negativCenter[3];
  int ptId, cellId, j, k;
  vtkGenericCell *cell = vtkGenericCell::New();
  vtkIdList *ptIds = vtkIdList::New();

  outPoints = vtkPoints::New();

  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();

  if (this->CopyInput)
    {
    outPoints->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
    output->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
    }
  else
    {
    outPoints->Allocate( this->GetNumberOfCopies() * numPts);
    output->Allocate( this->GetNumberOfCopies() * numPts);
    }

  outPD->CopyAllocate(inPD);
  outCD->CopyAllocate(inCD);

  vtkDataArray *inPtVectors, *outPtVectors, *inPtNormals, *outPtNormals;
  vtkDataArray *inCellVectors, *outCellVectors, *inCellNormals;
  vtkDataArray *outCellNormals;

  inPtVectors = inPD->GetVectors();
  outPtVectors = outPD->GetVectors();
  inPtNormals = inPD->GetNormals();
  outPtNormals = outPD->GetNormals();
  inCellVectors = inCD->GetVectors();
  outCellVectors = outCD->GetVectors();
  inCellNormals = inCD->GetNormals();
  outCellNormals = outCD->GetNormals();

  // Copy first points.
  if (this->CopyInput)
    {
    for (i = 0; i < numPts; i++)
      {
      input->GetPoint(i, point);
      ptId = outPoints->InsertNextPoint(point);
      outPD->CopyData(inPD, i, ptId);
      }
    }
  vtkTransform *localTransform = vtkTransform::New();
  // Rotate points.
  // double angle = this->GetAngle()*vtkMath::DegreesToRadians();
  this->GetCenter(center);
  negativCenter[0] = -center[0];
  negativCenter[1] = -center[1];
  negativCenter[2] = -center[2];

  for (k = 0; k < this->GetNumberOfCopies(); k++)
   {
   localTransform->Identity();
   localTransform->Translate(center);
   switch (this->Axis)
    {
     case USE_X:
        localTransform->RotateX((k+1)*this->GetAngle());
     break;

     case USE_Y:
        localTransform->RotateY((k+1)*this->GetAngle());
     break;

     case USE_Z:
        localTransform->RotateZ((k+1)*this->GetAngle());
     break;
     }
   localTransform->Translate(negativCenter);
   for (i = 0; i < numPts; i++)
    {
    input->GetPoint(i, point);
    localTransform->TransformPoint(point, point);
    ptId = outPoints->InsertNextPoint(point);
    outPD->CopyData(inPD, i, ptId);
    if (inPtVectors)
      {
      inPtVectors->GetTuple(i, tuple);
      outPtVectors->SetTuple(ptId, tuple);
      }
    if (inPtNormals)
      {
      //inPtNormals->GetTuple(i, tuple);
      //outPtNormals->SetTuple(ptId, tuple);
      }
    }
   }

  localTransform->Delete();

  int numCellPts,  cellType;
  vtkIdType *newCellPts;
  vtkIdList *cellPts;

  // Copy original cells.
  if (this->CopyInput)
    {
    for (i = 0; i < numCells; i++)
      {
      input->GetCellPoints(i, ptIds);
      output->InsertNextCell(input->GetCellType(i), ptIds);
      outCD->CopyData(inCD, i, i);
      }
    }

  // Generate rotated cells.
  for (k = 0; k < this->GetNumberOfCopies(); k++)
    {
    for (i = 0; i < numCells; i++)
      {
       input->GetCellPoints(i, ptIds);
       input->GetCell(i, cell);
       numCellPts = cell->GetNumberOfPoints();
       cellType = cell->GetCellType();
       cellPts = cell->GetPointIds();
      // Triangle strips with even number of triangles have
      // to be handled specially. A degenerate triangle is
      // introduce to flip all the triangles properly.
      if (cellType == VTK_TRIANGLE_STRIP && numCellPts % 2 == 0)
        {
        cerr << "Here\n";
        }
      else
        {cerr << "celltype " << cellType << " numCellPts " << numCellPts << "\n";
        newCellPts = new vtkIdType[numCellPts];
        //for (j = numCellPts-1; j >= 0; j--)
        for (j = 0; j < numCellPts; j++)
          {
          //newCellPts[numCellPts-1-j] = cellPts->GetId(j) + numPts*k;
          newCellPts[j] = cellPts->GetId(j) + numPts*k;
           if (this->CopyInput)
            {
             //newCellPts[numCellPts-1-j] += numPts;
             newCellPts[j] += numPts;
            }
          }
        }
      cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
      delete [] newCellPts;
      outCD->CopyData(inCD, i, cellId);
      if (inCellVectors)
        {
        inCellVectors->GetTuple(i, tuple);
        outCellVectors->SetTuple(cellId, tuple);
        }
      if (inCellNormals)
        {
        //inCellNormals->GetTuple(i, tuple);
        //outCellNormals->SetTuple(cellId, tuple);
        }
      }
    }

  cell->Delete();
  ptIds->Delete();
  output->SetPoints(outPoints);
  outPoints->Delete();
  output->CheckAttributes();

  return 1;
}

int vtkRotationFilter::FillInputPortInformation(int, vtkInformation *info)
{
  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
  return 1;
}
<|endoftext|>


<commit_before>/// \file PasskeySetup.cpp
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "PasswordSafe.h"
#include "corelib/PWCharPool.h" // for CheckPassword()
#include "ThisMfcApp.h"
#include "corelib/PwsPlatform.h"

#if defined(POCKET_PC)
  #include "pocketpc/resource.h"
  #include "pocketpc/PocketPC.h"
#else
  #include "resource.h"
#endif

#include "corelib/util.h"

#include "PasskeySetup.h"
#include "PwFont.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//-----------------------------------------------------------------------------
CPasskeySetup::CPasskeySetup(CWnd* pParent)
   : super(CPasskeySetup::IDD, pParent)
{
   m_passkey = _T("");
   m_verify = _T("");
}

BOOL CPasskeySetup::OnInitDialog()
{
   CDialog::OnInitDialog();
   SetPasswordFont(GetDlgItem(IDC_PASSKEY));
   SetPasswordFont(GetDlgItem(IDC_VERIFY));

   return TRUE;
}

void CPasskeySetup::DoDataExchange(CDataExchange* pDX)
{
   super::DoDataExchange(pDX);
   DDX_Text(pDX, IDC_PASSKEY, (CString &)m_passkey);
   DDX_Text(pDX, IDC_VERIFY, (CString &)m_verify);
}

BEGIN_MESSAGE_MAP(CPasskeySetup, super)
   ON_BN_CLICKED(ID_HELP, OnHelp)
#if defined(POCKET_PC)
   ON_EN_SETFOCUS(IDC_PASSKEY, OnPasskeySetfocus)
   ON_EN_SETFOCUS(IDC_VERIFY, OnPasskeySetfocus)
   ON_EN_KILLFOCUS(IDC_PASSKEY, OnPasskeyKillfocus)
   ON_EN_KILLFOCUS(IDC_VERIFY, OnPasskeyKillfocus)
#endif
END_MESSAGE_MAP()

void CPasskeySetup::OnCancel()
{
   super::OnCancel();
}

void CPasskeySetup::OnOK()
{
   UpdateData(TRUE);
   if (m_passkey != m_verify)
   {
      AfxMessageBox(_T("The two entries do not match."));
      ((CEdit*)GetDlgItem(IDC_VERIFY))->SetFocus();
      return;
   }

   if (m_passkey.IsEmpty())
   {
      AfxMessageBox(_T("Please enter a key and verify it."));
      ((CEdit*)GetDlgItem(IDC_PASSKEY))->SetFocus();
      return;
   }
   // Accept weak passwords in debug build, to make it easier to test
   // Reject weak passwords in Release (prior to 3.02, we allowed the
   // user to accept a weak password if she insisted).
   // DK - I think this is wrong, so I have put it back in a different form.
#ifndef _DEBUG
	CMyString errmess;
	if (!CPasswordCharPool::CheckPassword(m_passkey, errmess)) {
		CString msg(_T("Weak passphrase:\n\n"));
		msg += CString(errmess);
		if (m_bAllowWeakPassphrases) {
			msg += _T("\n\nAccept it anyway?");
			int rc = AfxMessageBox(msg, MB_YESNO | MB_ICONSTOP);
			if (rc == IDNO)
				return;
		} else {
			AfxMessageBox(msg, MB_ICONSTOP);
			return;
		}
	}
#endif

   super::OnOK();
}

void CPasskeySetup::OnHelp()
{
#if defined(POCKET_PC)
	CreateProcess( _T("PegHelp.exe"), _T("pws_ce_help.html#newdatabase"), NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL );
#else
   //WinHelp(0x20084, HELP_CONTEXT);
   ::HtmlHelp(NULL,
              "pwsafe.chm::/html/create_new_db.html",
              HH_DISPLAY_TOPIC, 0);
#endif
}

#if defined(POCKET_PC)
/************************************************************************/
/* Restore the state of word completion when the password field loses   */
/* focus.                                                               */
/************************************************************************/
void CPasskeySetup::OnPasskeyKillfocus()
{
	EnableWordCompletion( m_hWnd );
}

/************************************************************************/
/* When the password field is activated, pull up the SIP and disable    */
/* word completion.                                                     */
/************************************************************************/
void CPasskeySetup::OnPasskeySetfocus()
{
	DisableWordCompletion( m_hWnd );
}
#endif

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
<commit_msg>Allowunstrong master passphrases after due warning.<commit_after>/// \file PasskeySetup.cpp
//-----------------------------------------------------------------------------

#include "stdafx.h"
#include "PasswordSafe.h"
#include "corelib/PWCharPool.h" // for CheckPassword()
#include "ThisMfcApp.h"
#include "corelib/PwsPlatform.h"

#if defined(POCKET_PC)
  #include "pocketpc/resource.h"
  #include "pocketpc/PocketPC.h"
#else
  #include "resource.h"
#endif

#include "corelib/util.h"

#include "PasskeySetup.h"
#include "PwFont.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//-----------------------------------------------------------------------------
CPasskeySetup::CPasskeySetup(CWnd* pParent)
   : super(CPasskeySetup::IDD, pParent)
{
   m_passkey = _T("");
   m_verify = _T("");
}

BOOL CPasskeySetup::OnInitDialog()
{
   CDialog::OnInitDialog();
   SetPasswordFont(GetDlgItem(IDC_PASSKEY));
   SetPasswordFont(GetDlgItem(IDC_VERIFY));

   return TRUE;
}

void CPasskeySetup::DoDataExchange(CDataExchange* pDX)
{
   super::DoDataExchange(pDX);
   DDX_Text(pDX, IDC_PASSKEY, (CString &)m_passkey);
   DDX_Text(pDX, IDC_VERIFY, (CString &)m_verify);
}

BEGIN_MESSAGE_MAP(CPasskeySetup, super)
   ON_BN_CLICKED(ID_HELP, OnHelp)
#if defined(POCKET_PC)
   ON_EN_SETFOCUS(IDC_PASSKEY, OnPasskeySetfocus)
   ON_EN_SETFOCUS(IDC_VERIFY, OnPasskeySetfocus)
   ON_EN_KILLFOCUS(IDC_PASSKEY, OnPasskeyKillfocus)
   ON_EN_KILLFOCUS(IDC_VERIFY, OnPasskeyKillfocus)
#endif
END_MESSAGE_MAP()

void CPasskeySetup::OnCancel()
{
   super::OnCancel();
}

void CPasskeySetup::OnOK()
{
  UpdateData(TRUE);
  if (m_passkey != m_verify)
    {
      AfxMessageBox(_T("The two entries do not match."));
      ((CEdit*)GetDlgItem(IDC_VERIFY))->SetFocus();
      return;
    }

  if (m_passkey.IsEmpty())
    {
      AfxMessageBox(_T("Please enter a key and verify it."));
      ((CEdit*)GetDlgItem(IDC_PASSKEY))->SetFocus();
      return;
    }
  // Vox populi vox dei - folks want the ability to use a weak
  // passphrase, best we can do is warn them...
  // If someone want to build a version that insists on proper
  // passphrases, then just uncomment the following line
  //#define PWS_FORCE_STRONG_PASSPHRASE
#ifndef _DEBUG // for debug, we want no checks at all, to save time
  CMyString errmess;
  if (!CPasswordCharPool::CheckPassword(m_passkey, errmess)) {
    CString msg(_T("Weak passphrase:\n\n"));
    msg += CString(errmess);
#ifndef PWS_FORCE_STRONG_PASSPHRASE
    msg += _T("\nUse it anyway?");
    int rc = AfxMessageBox(msg, MB_YESNO | MB_ICONSTOP);
    if (rc == IDNO)
      return;
#else
    msg += _T("\nPlease try another");
    AfxMessageBox(msg, MB_OK | MB_ICONSTOP);
    return
#endif // PWS_FORCE_STRONG_PASSPHRASE
  }
#endif

  super::OnOK();
}

void CPasskeySetup::OnHelp()
{
#if defined(POCKET_PC)
	CreateProcess( _T("PegHelp.exe"), _T("pws_ce_help.html#newdatabase"), NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL );
#else
   //WinHelp(0x20084, HELP_CONTEXT);
   ::HtmlHelp(NULL,
              "pwsafe.chm::/html/create_new_db.html",
              HH_DISPLAY_TOPIC, 0);
#endif
}

#if defined(POCKET_PC)
/************************************************************************/
/* Restore the state of word completion when the password field loses   */
/* focus.                                                               */
/************************************************************************/
void CPasskeySetup::OnPasskeyKillfocus()
{
	EnableWordCompletion( m_hWnd );
}

/************************************************************************/
/* When the password field is activated, pull up the SIP and disable    */
/* word completion.                                                     */
/************************************************************************/
void CPasskeySetup::OnPasskeySetfocus()
{
	DisableWordCompletion( m_hWnd );
}
#endif

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
<|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "cinder/MotionManager.h"
#include "cinder/Capture.h"
#include "cinder/Log.h"

#include "GridMesh.h"
#include "CameraLandscape.h"
#include "GridTexture.h"
#include "TimeGrid.h"
#include "Landscape.h"
#include "Constants.h"

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

struct TouchInfo {
	uint32_t  id;
	vec2			previous;
	vec2			position;
};

class GridSpaceApp : public App {
public:
	void setup() override;
	void touchesBegan( TouchEvent event ) override;
	void touchesMoved( TouchEvent event ) override;
	void touchesEnded( TouchEvent event ) override;

	void pinchStart();
	void pinchUpdate();
	void pinchEnd();

	void update() override;
	void draw() override;

private:
	GridMesh				mesh;
	/*
	CameraLandscape cameraLandscape;
	TimeGrid				timeGrid;
	*/
	CaptureRef			capture;
	CameraPersp			camera;
	GridTextureRef	gridTexture;
	Landscape				landscape;

	bool						doDrawDebug = false;

	vector<TouchInfo> touches;
	ci::vec3					cameraOffset;
};

void GridSpaceApp::setup()
{
	mesh.setup();

	MotionManager::enable();

	GLint size;
	glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );
	CI_LOG_I( "Max texture size: " << size );

	auto target = vec3( 50, 5, 50 );
	camera.lookAt( vec3( 0 ), target, vec3( 0, 1, 0 ) );
	camera.setPerspective( 80, getWindowAspectRatio(), 0.1f, 1000 );

	try {
		auto front_facing_camera = ([] {
			auto &devices = Capture::getDevices();
			auto first_device = devices.front();
			for( auto device : devices ) {
				if( device->isFrontFacing() ) {
					return device;
				}
			}
			return first_device;
		}());

		capture = Capture::create( 480, 360, front_facing_camera );
		capture->start();
		const auto divisions = 8;
		const auto size = divisions * capture->getSize();
		gridTexture = make_shared<GridTexture>( size.x, size.y, divisions );
	}
	catch( ci::Exception &exc ) {
		CI_LOG_E( "Error using device camera: " << exc.what() );
	}

	landscape.setup();
	/*
	cameraLandscape.setup( gridTexture->getBlurredTexture() );
	timeGrid.setup( gridTexture->getTexture() );
	*/
}

void GridSpaceApp::touchesBegan( TouchEvent event )
{
	for( auto &t : event.getTouches() ) {
		touches.push_back( { t.getId(), t.getPos(), t.getPos() } );
	}

	if( touches.size() == 2 ) {
		pinchStart();
	}
}

void GridSpaceApp::touchesMoved( TouchEvent event )
{
	for( auto &t : event.getTouches() ) {
		for( auto &s : touches ) {
			if( s.id == t.getId() ) {
				s.previous = s.position;
				s.position = t.getPos();
			}
		}
	}

	if( touches.size() == 2 ) {
		pinchUpdate();
	}
}

void GridSpaceApp::touchesEnded( TouchEvent event )
{
	touches.erase( std::remove_if( touches.begin(), touches.end(), [&event] (const TouchInfo &s) {
		for( auto &t : event.getTouches() ) {
			if (t.getId() == s.id) {
				return true;
			}
		}
		return false;
	}), touches.end() );
}

void GridSpaceApp::pinchStart()
{
}

void GridSpaceApp::pinchUpdate()
{
	auto base = distance(touches.at( 0 ).previous, touches.at( 1 ).previous);
	auto current = distance(touches.at( 0 ).position, touches.at( 1 ).position);

	auto delta = current - base;
	if( isfinite( delta ) )
	{
		auto ray = camera.getViewDirection();
		cameraOffset += delta * ray * 0.01f;
	}
}

void GridSpaceApp::update()
{
	auto l = length(cameraOffset);
	auto maximum = 3.0f;
	if( l > maximum ) {
		cameraOffset *= (maximum / l);
	}
	camera.setEyePoint( cameraOffset );

	if( MotionManager::isDataAvailable() ) {
		auto r = MotionManager::getRotation();
		camera.setOrientation( r );
	}

	if( capture->checkNewFrame() ) {
		gridTexture->update( *capture->getSurface() );
	}
}

void GridSpaceApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
	gl::enableDepthRead();
	gl::enableDepthWrite();

	gl::setMatrices( camera );
	// TODO: bind both blurred and normal texture and avoid rebinding textures elsewhere.
	gl::ScopedTextureBind tex0( gridTexture->getTexture(), 0 );
	gl::ScopedTextureBind tex1( gridTexture->getBlurredTexture(), 1 );

	landscape.draw( gridTexture->getCurrentIndex() );
	/*
	timeGrid.draw( gridTexture->getCurrentIndex() );
	cameraLandscape.draw( gridTexture->getCurrentIndex() );
	*/
	mesh.draw( gridTexture->getCurrentIndex() );

	if( doDrawDebug )
	{
		if( gridTexture->getTexture() )
		{
			auto size = vec2(getWindowSize()) * vec2(1.0, 0.5);
			gl::ScopedMatrices mat;
			gl::setMatricesWindow( app::getWindowSize() );
			gl::draw( gridTexture->getTexture(), Rectf( vec2(0), size ) );

			gl::translate( size * vec2(0, 1) );
			gl::draw( gridTexture->getBlurredTexture(), Rectf( vec2(0), size ) );
		}
	}

}

CINDER_APP( GridSpaceApp, RendererGl )
<commit_msg>Don't draw cross mesh.<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "cinder/MotionManager.h"
#include "cinder/Capture.h"
#include "cinder/Log.h"

#include "GridMesh.h"
#include "CameraLandscape.h"
#include "GridTexture.h"
#include "TimeGrid.h"
#include "Landscape.h"
#include "Constants.h"

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

struct TouchInfo {
	uint32_t  id;
	vec2			previous;
	vec2			position;
};

class GridSpaceApp : public App {
public:
	void setup() override;
	void touchesBegan( TouchEvent event ) override;
	void touchesMoved( TouchEvent event ) override;
	void touchesEnded( TouchEvent event ) override;

	void pinchStart();
	void pinchUpdate();
	void pinchEnd();

	void update() override;
	void draw() override;

private:
	GridMesh				mesh;
	/*
	CameraLandscape cameraLandscape;
	TimeGrid				timeGrid;
	*/
	CaptureRef			capture;
	CameraPersp			camera;
	GridTextureRef	gridTexture;
	Landscape				landscape;

	bool						doDrawDebug = false;

	vector<TouchInfo> touches;
	ci::vec3					cameraOffset;
};

void GridSpaceApp::setup()
{

	MotionManager::enable();

	GLint size;
	glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );
	CI_LOG_I( "Max texture size: " << size );

	auto target = vec3( 50, 5, 50 );
	camera.lookAt( vec3( 0 ), target, vec3( 0, 1, 0 ) );
	camera.setPerspective( 80, getWindowAspectRatio(), 0.1f, 1000 );

	try {
		auto front_facing_camera = ([] {
			auto &devices = Capture::getDevices();
			auto first_device = devices.front();
			for( auto device : devices ) {
				if( device->isFrontFacing() ) {
					return device;
				}
			}
			return first_device;
		}());

		capture = Capture::create( 480, 360, front_facing_camera );
		capture->start();
		const auto divisions = 8;
		const auto size = divisions * capture->getSize();
		gridTexture = make_shared<GridTexture>( size.x, size.y, divisions );
	}
	catch( ci::Exception &exc ) {
		CI_LOG_E( "Error using device camera: " << exc.what() );
	}

	landscape.setup();
	/*
	cameraLandscape.setup( gridTexture->getBlurredTexture() );
	timeGrid.setup( gridTexture->getTexture() );
	mesh.setup();
	*/
}

void GridSpaceApp::touchesBegan( TouchEvent event )
{
	for( auto &t : event.getTouches() ) {
		touches.push_back( { t.getId(), t.getPos(), t.getPos() } );
	}

	if( touches.size() == 2 ) {
		pinchStart();
	}
}

void GridSpaceApp::touchesMoved( TouchEvent event )
{
	for( auto &t : event.getTouches() ) {
		for( auto &s : touches ) {
			if( s.id == t.getId() ) {
				s.previous = s.position;
				s.position = t.getPos();
			}
		}
	}

	if( touches.size() == 2 ) {
		pinchUpdate();
	}
}

void GridSpaceApp::touchesEnded( TouchEvent event )
{
	touches.erase( std::remove_if( touches.begin(), touches.end(), [&event] (const TouchInfo &s) {
		for( auto &t : event.getTouches() ) {
			if (t.getId() == s.id) {
				return true;
			}
		}
		return false;
	}), touches.end() );
}

void GridSpaceApp::pinchStart()
{
}

void GridSpaceApp::pinchUpdate()
{
	auto base = distance(touches.at( 0 ).previous, touches.at( 1 ).previous);
	auto current = distance(touches.at( 0 ).position, touches.at( 1 ).position);

	auto delta = current - base;
	if( isfinite( delta ) )
	{
		auto ray = camera.getViewDirection();
		cameraOffset += delta * ray * 0.01f;
	}
}

void GridSpaceApp::update()
{
	auto l = length(cameraOffset);
	auto maximum = 3.0f;
	if( l > maximum ) {
		cameraOffset *= (maximum / l);
	}
	camera.setEyePoint( cameraOffset );

	if( MotionManager::isDataAvailable() ) {
		auto r = MotionManager::getRotation();
		camera.setOrientation( r );
	}

	if( capture->checkNewFrame() ) {
		gridTexture->update( *capture->getSurface() );
	}
}

void GridSpaceApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
	gl::enableDepthRead();
	gl::enableDepthWrite();

	gl::setMatrices( camera );
	// TODO: bind both blurred and normal texture and avoid rebinding textures elsewhere.
	gl::ScopedTextureBind tex0( gridTexture->getTexture(), 0 );
	gl::ScopedTextureBind tex1( gridTexture->getBlurredTexture(), 1 );

	landscape.draw( gridTexture->getCurrentIndex() );
	/*
	timeGrid.draw( gridTexture->getCurrentIndex() );
	cameraLandscape.draw( gridTexture->getCurrentIndex() );
	mesh.draw( gridTexture->getCurrentIndex() );
	*/

	if( doDrawDebug )
	{
		if( gridTexture->getTexture() )
		{
			auto size = vec2(getWindowSize()) * vec2(1.0, 0.5);
			gl::ScopedMatrices mat;
			gl::setMatricesWindow( app::getWindowSize() );
			gl::draw( gridTexture->getTexture(), Rectf( vec2(0), size ) );

			gl::translate( size * vec2(0, 1) );
			gl::draw( gridTexture->getBlurredTexture(), Rectf( vec2(0), size ) );
		}
	}

}

CINDER_APP( GridSpaceApp, RendererGl )
<|endoftext|>


<commit_before>#include "RGBColor.h"

RGBColor::RGBColor()
  : r(.0f), g(.0f), b(.0f) {

}

RGBColor::RGBColor(const float red, const float green, const float blue)
  : r(red), g(green), b(blue) {

}

RGBColor::~RGBColor() {
  r = .0f;
  g = .0f;
  b = .0f;
}<commit_msg>Added constructor with a single value<commit_after>#include "RGBColor.h"

RGBColor::RGBColor()
  : r(.0f), g(.0f), b(.0f) {

}

RGBColor::RGBColor(const float rgb)
  : r(rgb), g(rgb), b (rgb) {

}

RGBColor::RGBColor(const float red, const float green, const float blue)
  : r(red), g(green), b(blue) {

}

RGBColor::~RGBColor() {
  r = .0f;
  g = .0f;
  b = .0f;
}<|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "GridMesh.h"
#include "cinder/MotionManager.h"

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

class GridSpaceApp : public App {
public:
	void setup() override;
	void mouseDown( MouseEvent event ) override;
	void update() override;
	void draw() override;
private:
	GridMesh				mesh;
	CameraPersp			camera;
	const ci::vec3	target = vec3( 50, 5, 50 );
};

void GridSpaceApp::setup()
{
	mesh.setup();
	MotionManager::enable();

	camera.lookAt( vec3( 0 ), target, vec3( 0, 1, 0 ) );
	camera.setPerspective( 60, getWindowAspectRatio(), 0.1f, 1000 );
}

void GridSpaceApp::mouseDown( MouseEvent event )
{
}

void GridSpaceApp::update()
{
	if( MotionManager::isDataAvailable() ) {
		auto rotated_target = MotionManager::getRotationMatrix() * vec4( target, 0 );
		camera.lookAt( vec3( 0 ), vec3( rotated_target ), vec3( 0, 1, 0 ) );
	}
}

void GridSpaceApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
	gl::enableDepthRead();
	gl::enableDepthWrite();

	gl::setMatrices( camera );
	mesh.draw();

	gl::setMatricesWindowPersp( getWindowSize() );
	gl::translate( vec3( getWindowCenter(), 0 ) );
	gl::rotate( MotionManager::getRotation() );

	gl::drawVector( vec3( 0 ), target );
	gl::scale( vec3( 50 ) );
	gl::drawCoordinateFrame();
}

CINDER_APP( GridSpaceApp, RendererGl )
<commit_msg>Camera::setOrientation works nicely.<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"

#include "GridMesh.h"
#include "cinder/MotionManager.h"

using namespace ci;
using namespace ci::app;
using namespace std;

using namespace soso;

class GridSpaceApp : public App {
public:
	void setup() override;
	void mouseDown( MouseEvent event ) override;
	void update() override;
	void draw() override;
private:
	GridMesh				mesh;
	CameraPersp			camera;
	const ci::vec3	target = vec3( 50, 5, 50 );
};

void GridSpaceApp::setup()
{
	mesh.setup();
	MotionManager::enable();

	camera.lookAt( vec3( 0 ), target, vec3( 0, 1, 0 ) );
	camera.setPerspective( 60, getWindowAspectRatio(), 0.1f, 1000 );
}

void GridSpaceApp::mouseDown( MouseEvent event )
{
}

void GridSpaceApp::update()
{
	if( MotionManager::isDataAvailable() ) {
		auto r = MotionManager::getRotation();
		camera.setOrientation( r );
	}
}

void GridSpaceApp::draw()
{
	gl::clear( Color( 0, 0, 0 ) );
	gl::enableDepthRead();
	gl::enableDepthWrite();

	gl::setMatrices( camera );
	mesh.draw();

	gl::setMatricesWindowPersp( getWindowSize() );
	gl::translate( vec3( getWindowCenter(), 0 ) );
	gl::rotate( MotionManager::getRotation() );
	gl::drawCube( vec3( 0 ), vec3( 50, 100, 5 ) );

	gl::scale( vec3( 50 ) );
	gl::drawCoordinateFrame();
}

CINDER_APP( GridSpaceApp, RendererGl )
<|endoftext|>


<commit_before>/**
 * @file mega/posix/drivenotifyposix.cpp
 * @brief Mega SDK various utilities and helper classes
 *
 * (c) 2013-2020 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#ifdef USE_DRIVE_NOTIFICATIONS

#include "mega/drivenotify.h"
#include <libudev.h> // Ubuntu: sudo apt-get install libudev-dev
#include <mntent.h>
#include <cstring>
#include <chrono>

namespace mega {

//
// DriveNotifyPosix
/////////////////////////////////////////////

bool DriveNotifyPosix::notifierSetup()
{
    // init udev resource
    mUdev = udev_new();
    if (!mUdev)  return false;  // is udevd daemon running?

    // init udev monitor
    mUdevMon = udev_monitor_new_from_netlink(mUdev, "udev");
    if (!mUdevMon)
    {
        udev_unref(mUdev);
        mUdev = nullptr;
        return false;
    }

    cacheMountedPartitions();

    // On unix systems you need to define your udev rules to allow notifications for
    // your device.
    //
    // i.e. on Ubuntu create file "100-megasync-udev.rules" either in
    // /etc/udev/rules.d/        OR
    // /usr/lib/udev/rules.d/
    // and add line:
    // SUBSYSTEM=="block", ATTRS{idDevtype}=="partition"
    udev_monitor_filter_add_match_subsystem_devtype(mUdevMon, "block", "partition");
    udev_monitor_enable_receiving(mUdevMon);

    return true;
}

void DriveNotifyPosix::notifierTeardown()
{
    // release udev monitor
    if (mUdevMon)
    {
        udev_monitor_filter_remove(mUdevMon);
        udev_monitor_unref(mUdevMon);
        mUdevMon = nullptr;
    }

    // release udev resource
    if (mUdev)
    {
        udev_unref(mUdev);
        mUdev = nullptr;
    }

    mMounted.clear();
}

void DriveNotifyPosix::doInThread()
{
    int fd = udev_monitor_get_fd(mUdevMon);
    while (!shouldStop())
    {
        // use a blocking call, with a timeout, to check for device events
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);

        timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 250 * 1000; // 250ms

        int ret = select(fd+1, &fds, nullptr, nullptr, &tv);
        if (ret <= 0 || !FD_ISSET(fd, &fds))  continue;

        // get any [dis]connected device
        udev_device* dev = udev_monitor_receive_device(mUdevMon);
        if (dev)
        {
            evaluateDevice(dev);

            udev_device_unref(dev);
        }
    }
}

void DriveNotifyPosix::evaluateDevice(udev_device* dev)  // dev must Not be null
{
    // filter "partition" events
    const char* devtype = udev_device_get_devtype(dev); // "partition"
    if(strcmp(devtype, "partition"))  return;

    // filter "add"/"remove" actions
    const char* action = udev_device_get_action(dev); // "add" / "remove"
    bool added = !strcmp(action, "add");
    bool removed = !added && !strcmp(action, "remove");
    if (!(added || removed))  return; // ignore other possible actions

    // get device location
    const char* devNode = udev_device_get_devnode(dev); // "/dev/sda1"
    if (!devNode)  return; // did something go wrong?

    const std::string& devNodeStr(devNode);

    // gather drive info
    DriveInfo drvInfo;
    drvInfo.connected = added;

    // get the mount point
    if (removed)
    {
        // get it from the cache, because it will have already been removed from
        // the relevant locations by the time getMountPoint() will attempt to read it
        drvInfo.mountPoint = mMounted[devNodeStr];
        mMounted.erase(devNodeStr); // remove from cache
    }
    else // added
    {
        // reading it might happen before the relevant locations have been updated,
        // so allow retrying a few times, say at 100ms intervals
        for (int i = 0; i < 5; ++i)
        {
            drvInfo.mountPoint = getMountPoint(devNodeStr);

            if (!drvInfo.mountPoint.empty())
            {
                mMounted[devNodeStr] = drvInfo.mountPoint; // cache it
                break;
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    // send notification
    if (!drvInfo.mountPoint.empty())
    {
        add(std::move(drvInfo));
    }
}

std::string DriveNotifyPosix::getMountPoint(const std::string& device)
{
    std::string mountPoint;

    // go to all mounts
    FILE* fsMounts = setmntent("/proc/mounts", "r");
    if (!fsMounts) // this should never happen
    {
        // make another attempt
        fsMounts = setmntent("/etc/mtab", "r");
        if (!fsMounts)  return mountPoint;
    }

    // search mount point for the current device
    for (mntent* mnt = getmntent(fsMounts); mnt; mnt = getmntent(fsMounts))
    {
        if (device == mnt->mnt_fsname)
        {
            mountPoint = mnt->mnt_dir;
            break;
        }
    }

    endmntent(fsMounts); // closes the file descriptor

    return mountPoint;
}

void DriveNotifyPosix::cacheMountedPartitions()
{
    // enumerate all mounted partitions
    udev_enumerate* enumerate = udev_enumerate_new(mUdev);

    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_add_match_property(enumerate, "DEVTYPE", "partition");
    udev_enumerate_scan_devices(enumerate);

    udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    udev_list_entry *entry;

    udev_list_entry_foreach(entry, devices) // for loop
    {
        // get a partition
        const char* entryName = udev_list_entry_get_name(entry);
        udev_device* blockDev = udev_device_new_from_syspath(mUdev, entryName);
        if (!blockDev)  continue;

        // filter only removable ones
        if (isRemovable(blockDev))
        {
            // get partition node
            const char* devNode = udev_device_get_devnode(blockDev); // "/dev/sda1"

            // cache mount point
            std::string mountPoint = getMountPoint(devNode);
            if (!mountPoint.empty())
            {
                mMounted[devNode] = mountPoint;
            }
        }

        udev_device_unref(blockDev);
    }

    udev_enumerate_unref(enumerate);
}

bool DriveNotifyPosix::isRemovable(udev_device* part)
{
    udev_device* parent = udev_device_get_parent(part); // do not unref this one!
    if (!parent)  return false;

    const char* removable = udev_device_get_sysattr_value(parent, "removable");
    return removable && !strcmp(removable, "1");
}

} // namespace

#endif // USE_DRIVE_NOTIFICATIONS
<commit_msg>Add null pointer checks<commit_after>/**
 * @file mega/posix/drivenotifyposix.cpp
 * @brief Mega SDK various utilities and helper classes
 *
 * (c) 2013-2020 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#ifdef USE_DRIVE_NOTIFICATIONS

#include "mega/drivenotify.h"
#include <libudev.h> // Ubuntu: sudo apt-get install libudev-dev
#include <mntent.h>
#include <cstring>
#include <chrono>

namespace mega {

//
// DriveNotifyPosix
/////////////////////////////////////////////

bool DriveNotifyPosix::notifierSetup()
{
    // init udev resource
    mUdev = udev_new();
    if (!mUdev)  return false;  // is udevd daemon running?

    // init udev monitor
    mUdevMon = udev_monitor_new_from_netlink(mUdev, "udev");
    if (!mUdevMon)
    {
        udev_unref(mUdev);
        mUdev = nullptr;
        return false;
    }

    cacheMountedPartitions();

    // On unix systems you need to define your udev rules to allow notifications for
    // your device.
    //
    // i.e. on Ubuntu create file "100-megasync-udev.rules" either in
    // /etc/udev/rules.d/        OR
    // /usr/lib/udev/rules.d/
    // and add line:
    // SUBSYSTEM=="block", ATTRS{idDevtype}=="partition"
    udev_monitor_filter_add_match_subsystem_devtype(mUdevMon, "block", "partition");
    udev_monitor_enable_receiving(mUdevMon);

    return true;
}

void DriveNotifyPosix::notifierTeardown()
{
    // release udev monitor
    if (mUdevMon)
    {
        udev_monitor_filter_remove(mUdevMon);
        udev_monitor_unref(mUdevMon);
        mUdevMon = nullptr;
    }

    // release udev resource
    if (mUdev)
    {
        udev_unref(mUdev);
        mUdev = nullptr;
    }

    mMounted.clear();
}

void DriveNotifyPosix::doInThread()
{
    int fd = udev_monitor_get_fd(mUdevMon);
    while (!shouldStop())
    {
        // use a blocking call, with a timeout, to check for device events
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(fd, &fds);

        timeval tv;
        tv.tv_sec = 0;
        tv.tv_usec = 250 * 1000; // 250ms

        int ret = select(fd+1, &fds, nullptr, nullptr, &tv);
        if (ret <= 0 || !FD_ISSET(fd, &fds))  continue;

        // get any [dis]connected device
        udev_device* dev = udev_monitor_receive_device(mUdevMon);
        if (dev)
        {
            evaluateDevice(dev);

            udev_device_unref(dev);
        }
    }
}

void DriveNotifyPosix::evaluateDevice(udev_device* dev)  // dev must Not be null
{
    // filter "partition" events
    const char* devtype = udev_device_get_devtype(dev); // "partition"
    if (!devtype || strcmp(devtype, "partition"))  return;

    // filter "add"/"remove" actions
    const char* action = udev_device_get_action(dev); // "add" / "remove"
    bool added = action && !strcmp(action, "add");
    bool removed = action && !added && !strcmp(action, "remove");
    if (!(added || removed))  return; // ignore other possible actions

    // get device location
    const char* devNode = udev_device_get_devnode(dev); // "/dev/sda1"
    if (!devNode)  return; // did something go wrong?

    const std::string& devNodeStr(devNode);

    // gather drive info
    DriveInfo drvInfo;
    drvInfo.connected = added;

    // get the mount point
    if (removed)
    {
        // get it from the cache, because it will have already been removed from
        // the relevant locations by the time getMountPoint() will attempt to read it
        drvInfo.mountPoint = mMounted[devNodeStr];
        mMounted.erase(devNodeStr); // remove from cache
    }
    else // added
    {
        // reading it might happen before the relevant locations have been updated,
        // so allow retrying a few times, say at 100ms intervals
        for (int i = 0; i < 5; ++i)
        {
            drvInfo.mountPoint = getMountPoint(devNodeStr);

            if (!drvInfo.mountPoint.empty())
            {
                mMounted[devNodeStr] = drvInfo.mountPoint; // cache it
                break;
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    }

    // send notification
    if (!drvInfo.mountPoint.empty())
    {
        add(std::move(drvInfo));
    }
}

std::string DriveNotifyPosix::getMountPoint(const std::string& device)
{
    std::string mountPoint;

    // go to all mounts
    FILE* fsMounts = setmntent("/proc/mounts", "r");
    if (!fsMounts) // this should never happen
    {
        // make another attempt
        fsMounts = setmntent("/etc/mtab", "r");
        if (!fsMounts)  return mountPoint;
    }

    // search mount point for the current device
    for (mntent* mnt = getmntent(fsMounts); mnt; mnt = getmntent(fsMounts))
    {
        if (device == mnt->mnt_fsname)
        {
            mountPoint = mnt->mnt_dir;
            break;
        }
    }

    endmntent(fsMounts); // closes the file descriptor

    return mountPoint;
}

void DriveNotifyPosix::cacheMountedPartitions()
{
    // enumerate all mounted partitions
    udev_enumerate* enumerate = udev_enumerate_new(mUdev);

    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_add_match_property(enumerate, "DEVTYPE", "partition");
    udev_enumerate_scan_devices(enumerate);

    udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    udev_list_entry *entry;

    udev_list_entry_foreach(entry, devices) // for loop
    {
        // get a partition
        const char* entryName = udev_list_entry_get_name(entry);
        udev_device* blockDev = udev_device_new_from_syspath(mUdev, entryName);
        if (!blockDev)  continue;

        // filter only removable ones
        if (isRemovable(blockDev))
        {
            // get partition node
            const char* devNode = udev_device_get_devnode(blockDev); // "/dev/sda1"

            // cache mount point
            std::string mountPoint = getMountPoint(devNode);
            if (!mountPoint.empty())
            {
                mMounted[devNode] = mountPoint;
            }
        }

        udev_device_unref(blockDev);
    }

    udev_enumerate_unref(enumerate);
}

bool DriveNotifyPosix::isRemovable(udev_device* part)
{
    udev_device* parent = udev_device_get_parent(part); // do not unref this one!
    if (!parent)  return false;

    const char* removable = udev_device_get_sysattr_value(parent, "removable");
    return removable && !strcmp(removable, "1");
}

} // namespace

#endif // USE_DRIVE_NOTIFICATIONS
<|endoftext|>


<commit_before>#include "application.h"
#include "Adafruit_LEDBackpack.h"

Adafruit_8x8matrix matrix1;
Adafruit_8x8matrix matrix2;
Adafruit_8x8matrix matrix3;

static const uint8_t smile[] = {
  0b00111100,
  0b01000010,
  0b10100101,
  0b10000001,
  0b10100101,
  0b10011001,
  0b01000010,
  0b00111100
};

void setup()
{
  Wire.begin();
  matrix1.begin(0x70);
  matrix2.begin(0x71);
  matrix3.begin(0x72);
}

void loop()
{
  matrix1.clear();
  delay(500);
  matrix1.drawBitmap(0, 0, smile, 8, 8, LED_ON);
  matrix1.writeDisplay();
  delay(500);
}
<commit_msg>Add Spark function and variables<commit_after>#include "application.h"
#include "Adafruit_LEDBackpack.h"

Adafruit_8x8matrix matrix1;
Adafruit_8x8matrix matrix2;
Adafruit_8x8matrix matrix3;

static const uint8_t smile[] = {
  0b00111100,
  0b01000010,
  0b10100101,
  0b10000001,
  0b10100101,
  0b10011001,
  0b01000010,
  0b00111100
};

int currentTemperature = 0;
int desiredTemperature = 0;
bool isHeatOn = false;
bool isFanOn = false;

int setTemperature(String t)
{
  return 1;
}

void setup()
{
  Wire.begin();
  matrix1.begin(0x70);
  matrix2.begin(0x71);
  matrix3.begin(0x72);

  Spark.function("set_temp", setTemperature);
  Spark.variable("current_temp", &currentTemperature, INT);
  Spark.variable("desired_temp", &desiredTemperature, INT);
  Spark.variable("is_heat_on", &isHeatOn, BOOLEAN);
  Spark.variable("is_fan_on", &isFanOn, BOOLEAN);
}

void loop()
{
  matrix3.clear();
  matrix3.drawBitmap(0, 0, smile, 8, 8, LED_ON);
  matrix3.writeDisplay();
  delay(500);
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "primitives/transaction.h"

#include "hash.h"
#include "tinyformat.h"
#include "utilstrencodings.h"

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString()/*.substr(0,10)*/, n);
}

std::string COutPoint::ToStringShort() const
{
    return strprintf("%s-%u", hash.ToString().substr(0,64), n);
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
    if (nSequence != SEQUENCE_FINAL)
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    scriptPubKey = scriptPubKeyIn;
    nRounds = -10;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
	// 12-12-2018 - R ANDREWS - Show User the vOut ordinal
	std::string IsPog = (Contains(sTxOutMessage, "<POG>")) ? "POG" : "";

    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s) %s", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30), IsPog);
}

CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}

uint256 CMutableTransaction::GetHash() const
{
    return SerializeHash(*this);
}

std::string CMutableTransaction::ToString() const
{
    std::string str;
    str += strprintf("CMutableTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::UpdateHash() const
{
    *const_cast<uint256*>(&hash) = SerializeHash(*this);
}

CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }

CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
    UpdateHash();
}

CTransaction& CTransaction::operator=(const CTransaction &tx) {
    *const_cast<int*>(&nVersion) = tx.nVersion;
    *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
    *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
    *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
    *const_cast<uint256*>(&hash) = tx.hash;
    return *this;
}

CAmount CTransaction::GetValueOut() const
{
    CAmount nValueOut = 0;
    for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)
    {
        nValueOut += it->nValue;
        if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    nTxSize = CalculateModifiedSize(nTxSize);
    if (nTxSize == 0) return 0.0;

    return dPriorityInputs / nTxSize;
}

unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    return nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}
<commit_msg>1.1.6.4f-Leisure Upgrade<commit_after>// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "primitives/transaction.h"

#include "hash.h"
#include "tinyformat.h"
#include "utilstrencodings.h"

bool Contains(std::string data, std::string instring);

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString()/*.substr(0,10)*/, n);
}

std::string COutPoint::ToStringShort() const
{
    return strprintf("%s-%u", hash.ToString().substr(0,64), n);
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
    if (nSequence != SEQUENCE_FINAL)
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    scriptPubKey = scriptPubKeyIn;
    nRounds = -10;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
	// 12-12-2018 - R ANDREWS - Show User the vOut ordinal
	std::string IsPog = (Contains(sTxOutMessage, "<POG>")) ? "POG" : "";

    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s) %s", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30), IsPog);
}

CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}

uint256 CMutableTransaction::GetHash() const
{
    return SerializeHash(*this);
}

std::string CMutableTransaction::ToString() const
{
    std::string str;
    str += strprintf("CMutableTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::UpdateHash() const
{
    *const_cast<uint256*>(&hash) = SerializeHash(*this);
}

CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }

CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
    UpdateHash();
}

CTransaction& CTransaction::operator=(const CTransaction &tx) {
    *const_cast<int*>(&nVersion) = tx.nVersion;
    *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
    *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
    *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
    *const_cast<uint256*>(&hash) = tx.hash;
    return *this;
}

CAmount CTransaction::GetValueOut() const
{
    CAmount nValueOut = 0;
    for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)
    {
        nValueOut += it->nValue;
        if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    nTxSize = CalculateModifiedSize(nTxSize);
    if (nTxSize == 0) return 0.0;

    return dPriorityInputs / nTxSize;
}

unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    return nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}
<|endoftext|>