<commit_before>
//
// File   : IcomCAT.cpp
//
// Purpose: Implementation of the class IcomCAT
//
// $Id$
//

#include <Stream.h>
#include <Streaming.h>

#include <CATutil.h>
#include <IcomCAT.h>

IcomCAT::IcomCAT(Stream& stream,byte address)
 : myStream(stream), rigAddress(address),
   rxMsgLength(0), rxMsgComplete(false),
   myMode(ILLEGAL_MODE), myFrequency(ILLEGAL_FREQ)
 {

}

static int getNibble(const byte* s,int i) {

  byte k = s[i/2];
  if ( i % 2 == 0 )
    k = k >> 4;
  return k & 0x0f;
}

uint32_t IcomCAT::parseFrequency(const byte* message) {

  static byte ks[] = { 10, 11, 8, 9, 6, 7, 4, 5, 2, 3 };
  uint32_t f = 0;

  for (size_t i=0; i<sizeof(ks); ++i) {
     byte k = ks[i];
     f = 10*f + getNibble(message,k);
  }

  return f;
}

bool IcomCAT::parseMessage() {

  if ( !rxMsgComplete ) return false;

#ifdef DEBUG
  Serial << F("Rx(") << rxMsgLength << F("): ");
  CATutil::print(rxMessage,rxMsgLength);
#endif // DEBUG

  // reset 'complete' flag
  rxMsgComplete = false;

  bool err = false;

  if (rxMessage[0] != IcomCAT::INTRO) err = true;
  if (rxMessage[1] != IcomCAT::INTRO) err = true;
  if (rxMessage[rxMsgLength-1] != IcomCAT::EOM) err = true;
  // message to the rig?
  if (rxMessage[2] == rigAddress) {
    // erase it
    rxMsgLength = 0;
    Serial << F("Skipped ECHO!") << endl;
    return false;
  }
  // message from the rig?
  if (rxMessage[3] != rigAddress) err = true;

  if ( err ) {
    Serial << F("CAT message error!") << endl;
    rxMsgLength = 0;

    return false;
  }

  bool status = true;

  switch ( rxMessage[4] ) {

    case eTRANSFER_FREQ: // transfer operating frequency data
    case eGET_OPERATING_FREQ:
      myFrequency = parseFrequency(&rxMessage[4]);
      break;

    case eTRANSFER_MODE: // transfer operating mode data
    case eGET_OPERATING_MODE:
      // rxMessage[6] is the passband/filter data
      // 0x01 = wide, 0x02 = normal, 0x03 = narrow
      myMode = rxMessage[5];
      break;

    default:
      Serial << F("Message ");
      CATutil::print(rxMessage[4]);
      Serial << F(" ignored!") << endl;
      status = false;
      break;
  }

  rxMsgLength = 0;

  return status;
}

bool IcomCAT::read() {

  static int nIntro = 0;

  byte ch = myStream.read();

#ifdef DEBUG
  //Serial << F("Rx: "); CATutil::print(ch); Serial.println();
#endif // DEBUG

  if ( ch == IcomCAT::INTRO ) {
    nIntro++;
    rxMessage[rxMsgLength++] = ch;
  }
  if ( ch != IcomCAT::INTRO && nIntro == 2 ) {
    rxMessage[rxMsgLength++] = ch;
  }
  if ( ch == IcomCAT::EOM ) {
    nIntro = 0;
    rxMsgComplete = true;
  }
  if ( rxMsgLength > IcomCAT::MAXLEN ) {
    Serial << F("MSG length error!") << endl;
    rxMsgComplete = false;
    rxMsgLength = 0;  // clear message buffer
    nIntro = 0;
  }

  return rxMsgComplete;
}

/**
 * - message to ICom:
 *  +------+------+----+----+----+------+
 *  | 0xFE | 0xFE | 58 | E0 | 03 | 0xFD |
 *  +------+------+----+----+----+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *  | 0xFE | 0xFE | 00 | 58 | 00 | Data0 | Data1 | Data2 | Data3 | Data4 | 0xFD |
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 */
bool IcomCAT::requestFrequency() {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eGET_OPERATING_FREQ;
  message[msgLen++] = IcomCAT::EOM;

  return sendMessage(message, msgLen);
}

/**
 * - message to ICom:
 *  +------+------+----+----+----+------+
 *  | 0xFE | 0xFE | 58 | E0 | 03 | 0xFD |
 *  +------+------+----+----+----+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+----+------+------+
 *  | 0xFE | 0xFE | 00 | 58 | 01 | mode | 0xFD |
 *  +------+------+----+----+----+------+------+
 */
bool IcomCAT::requestMode() {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eGET_OPERATING_MODE;
  message[msgLen++] = IcomCAT::EOM;

  return sendMessage(message, msgLen);
}

bool IcomCAT::sendMessage(const byte* msg,size_t msgLen) {

  if (!msgLen ) return false;

#ifdef DEBUG
  Serial << F("Tx(") << msgLen << F("): ");
  CATutil::print(msg, msgLen);
#endif // DEBUG

  for (size_t i=0; i<msgLen; ++i) {

    // SoftwareSerial will not receive during send
    if ( myStream.available() ) read();

    // should return 1 on success (i.e. 1 byte written)
    if ( !myStream.write(msg[i]) ) return false;
  }

  return true;
}

/** Create BCD 'byte' from two characters (digits), no error checking done! */
#define bcd(_h,_l) ((int)_l - '0' + 16 * ((int)_h - '0'))

/**
 *  - message to ICom:
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *  | 0xFE | 0xFE | 58 | E0 | 05 | Data0 | Data1 | Data2 | Data3 | Data4 | 0xFD |
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+------+------+
 *  | 0xFE | 0xFE | E0 | 58 | 0xFB | 0xFD |
 *  +------+------+----+----+------+------+
 */
bool IcomCAT::writeFrequency(uint32_t frequency) {

  int msgLen = 0;
  byte message[12];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eSET_OPERATING_FREQ;

  byte *ptr = &message[msgLen];

  for (int i=0; i<5; ++i )
    message[msgLen++] = 0;

  // convert the integer frequency into a string of 10 bytes length
  char freq_str[12];
  ultoa(frequency, freq_str, 10);

  // ... with leading zeros
  while ( strlen(freq_str) < 10 ) {
    freq_str[strlen(freq_str)+1] = 0;
    for ( int i=strlen(freq_str); i>0; --i)
      freq_str[i] = freq_str[i-1];
    freq_str[0] = '0';
  }

#ifdef DEBUG
  //Serial << "f= " << freq_str << endl;
  //Serial << "len(f)= " << strlen(freq_str) << endl;
#endif // DEBUG

  *ptr++ = bcd(freq_str[8], freq_str[9]);
  *ptr++ = bcd(freq_str[6], freq_str[7]);
  *ptr++ = bcd(freq_str[4], freq_str[5]);
  *ptr++ = bcd(freq_str[2], freq_str[3]);
  *ptr++ = bcd(freq_str[0], freq_str[1]);

  message[msgLen++] = IcomCAT::EOM;

#ifdef DEBUG
  //Serial << F("Tx: ");
  //CATutil::print(message, msgLen);
#endif // DEBUG

  myFrequency = IcomCAT::ILLEGAL_FREQ;

  return sendMessage(message, msgLen);
}

/**
 *  - message to ICom:
 *  +------+------+----+----+----+------+------+
 *  | 0xFE | 0xFE | 58 | E0 | 06 | mode | 0xFD |
 *  +------+------+----+----+----+------+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+------+------+
 *  | 0xFE | 0xFE | E0 | 58 | 0xFB | 0xFD |
 *  +------+------+----+----+------+------+
 */
bool IcomCAT::writeMode(byte mode) {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eSET_OPERATING_MODE;
  message[msgLen++] = mode;
  message[msgLen++] = IcomCAT::EOM;

  myMode = IcomCAT::ILLEGAL_MODE;

  return sendMessage(message, msgLen);
}

<commit_msg>DEBUG/_DEBUG<commit_after>
//
// File   : IcomCAT.cpp
//
// Purpose: Implementation of the class IcomCAT
//
// $Id$
//

#include <Stream.h>
#include <Streaming.h>

#include <CATutil.h>
#include <IcomCAT.h>

#define _DEBUG

IcomCAT::IcomCAT(Stream& stream,byte address)
 : myStream(stream), rigAddress(address),
   rxMsgLength(0), rxMsgComplete(false),
   myMode(ILLEGAL_MODE), myFrequency(ILLEGAL_FREQ)
 {

}

static int getNibble(const byte* s,int i) {

  byte k = s[i/2];
  if ( i % 2 == 0 )
    k = k >> 4;
  return k & 0x0f;
}

uint32_t IcomCAT::parseFrequency(const byte* message) {

  static byte ks[] = { 10, 11, 8, 9, 6, 7, 4, 5, 2, 3 };
  uint32_t f = 0;

  for (size_t i=0; i<sizeof(ks); ++i) {
     byte k = ks[i];
     f = 10*f + getNibble(message,k);
  }

  return f;
}

bool IcomCAT::parseMessage() {

  if ( !rxMsgComplete ) return false;

#ifdef DEBUG
  Serial << F("Rx(") << rxMsgLength << F("): ");
  CATutil::print(rxMessage,rxMsgLength);
#endif // DEBUG

  // reset 'complete' flag
  rxMsgComplete = false;

  bool err = false;

  if (rxMessage[0] != IcomCAT::INTRO) err = true;
  if (rxMessage[1] != IcomCAT::INTRO) err = true;
  if (rxMessage[rxMsgLength-1] != IcomCAT::EOM) err = true;
  // message to the rig?
  if (rxMessage[2] == rigAddress) {
    // erase it
    rxMsgLength = 0;
    Serial << F("Skipped ECHO!") << endl;
    return false;
  }
  // message from the rig?
  if (rxMessage[3] != rigAddress) err = true;

  if ( err ) {
    Serial << F("CAT message error!") << endl;
    rxMsgLength = 0;

    return false;
  }

  bool status = true;

  switch ( rxMessage[4] ) {

    case eTRANSFER_FREQ: // transfer operating frequency data
    case eGET_OPERATING_FREQ:
      myFrequency = parseFrequency(&rxMessage[4]);
      break;

    case eTRANSFER_MODE: // transfer operating mode data
    case eGET_OPERATING_MODE:
      // rxMessage[6] is the passband/filter data
      // 0x01 = wide, 0x02 = normal, 0x03 = narrow
      myMode = rxMessage[5];
      break;

    default:
      Serial << F("Message ");
      CATutil::print(rxMessage[4]);
      Serial << F(" ignored!") << endl;
      status = false;
      break;
  }

  rxMsgLength = 0;

  return status;
}

bool IcomCAT::read() {

  static int nIntro = 0;

  byte ch = myStream.read();

#ifdef DEBUG
  //Serial << F("Rx: "); CATutil::print(ch); Serial.println();
#endif // DEBUG

  if ( ch == IcomCAT::INTRO ) {
    nIntro++;
    rxMessage[rxMsgLength++] = ch;
  }
  if ( ch != IcomCAT::INTRO && nIntro == 2 ) {
    rxMessage[rxMsgLength++] = ch;
  }
  if ( ch == IcomCAT::EOM ) {
    nIntro = 0;
    rxMsgComplete = true;
  }
  if ( rxMsgLength > IcomCAT::MAXLEN ) {
    Serial << F("MSG length error!") << endl;
    rxMsgComplete = false;
    rxMsgLength = 0;  // clear message buffer
    nIntro = 0;
  }

  return rxMsgComplete;
}

/**
 * - message to ICom:
 *  +------+------+----+----+----+------+
 *  | 0xFE | 0xFE | 58 | E0 | 03 | 0xFD |
 *  +------+------+----+----+----+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *  | 0xFE | 0xFE | 00 | 58 | 00 | Data0 | Data1 | Data2 | Data3 | Data4 | 0xFD |
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 */
bool IcomCAT::requestFrequency() {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eGET_OPERATING_FREQ;
  message[msgLen++] = IcomCAT::EOM;

  return sendMessage(message, msgLen);
}

/**
 * - message to ICom:
 *  +------+------+----+----+----+------+
 *  | 0xFE | 0xFE | 58 | E0 | 03 | 0xFD |
 *  +------+------+----+----+----+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+----+------+------+
 *  | 0xFE | 0xFE | 00 | 58 | 01 | mode | 0xFD |
 *  +------+------+----+----+----+------+------+
 */
bool IcomCAT::requestMode() {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eGET_OPERATING_MODE;
  message[msgLen++] = IcomCAT::EOM;

  return sendMessage(message, msgLen);
}

bool IcomCAT::sendMessage(const byte* msg,size_t msgLen) {

  if (!msgLen ) return false;

#ifdef DEBUG
  Serial << F("Tx(") << msgLen << F("): ");
  CATutil::print(msg, msgLen);
#endif // DEBUG

  for (size_t i=0; i<msgLen; ++i) {

    // SoftwareSerial will not receive during send
    if ( myStream.available() ) read();

    // should return 1 on success (i.e. 1 byte written)
    if ( !myStream.write(msg[i]) ) return false;
  }

  return true;
}

/** Create BCD 'byte' from two characters (digits), no error checking done! */
#define bcd(_h,_l) ((int)_l - '0' + 16 * ((int)_h - '0'))

/**
 *  - message to ICom:
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *  | 0xFE | 0xFE | 58 | E0 | 05 | Data0 | Data1 | Data2 | Data3 | Data4 | 0xFD |
 *  +------+------+----+----+----+-------+-------+-------+-------+-------+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+------+------+
 *  | 0xFE | 0xFE | E0 | 58 | 0xFB | 0xFD |
 *  +------+------+----+----+------+------+
 */
bool IcomCAT::writeFrequency(uint32_t frequency) {

  int msgLen = 0;
  byte message[12];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eSET_OPERATING_FREQ;

  byte *ptr = &message[msgLen];

  for (int i=0; i<5; ++i )
    message[msgLen++] = 0;

  // convert the integer frequency into a string of 10 bytes length
  char freq_str[12];
  ultoa(frequency, freq_str, 10);

  // ... with leading zeros
  while ( strlen(freq_str) < 10 ) {
    freq_str[strlen(freq_str)+1] = 0;
    for ( int i=strlen(freq_str); i>0; --i)
      freq_str[i] = freq_str[i-1];
    freq_str[0] = '0';
  }

#ifdef DEBUG
  //Serial << "f= " << freq_str << endl;
  //Serial << "len(f)= " << strlen(freq_str) << endl;
#endif // DEBUG

  *ptr++ = bcd(freq_str[8], freq_str[9]);
  *ptr++ = bcd(freq_str[6], freq_str[7]);
  *ptr++ = bcd(freq_str[4], freq_str[5]);
  *ptr++ = bcd(freq_str[2], freq_str[3]);
  *ptr++ = bcd(freq_str[0], freq_str[1]);

  message[msgLen++] = IcomCAT::EOM;

#ifdef DEBUG
  //Serial << F("Tx: ");
  //CATutil::print(message, msgLen);
#endif // DEBUG

  myFrequency = IcomCAT::ILLEGAL_FREQ;

  return sendMessage(message, msgLen);
}

/**
 *  - message to ICom:
 *  +------+------+----+----+----+------+------+
 *  | 0xFE | 0xFE | 58 | E0 | 06 | mode | 0xFD |
 *  +------+------+----+----+----+------+------+
 *
 *  - message from ICom:
 *  +------+------+----+----+------+------+
 *  | 0xFE | 0xFE | E0 | 58 | 0xFB | 0xFD |
 *  +------+------+----+----+------+------+
 */
bool IcomCAT::writeMode(byte mode) {

  int msgLen = 0;
  byte message[8];

  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = IcomCAT::INTRO;
  message[msgLen++] = rigAddress;
  message[msgLen++] = MY_ADDRESS;
  message[msgLen++] = IcomCAT::eSET_OPERATING_MODE;
  message[msgLen++] = mode;
  message[msgLen++] = IcomCAT::EOM;

  myMode = IcomCAT::ILLEGAL_MODE;

  return sendMessage(message, msgLen);
}

<|endoftext|>


<commit_before>#ifndef _algorithm_hpp_1337420
#define _algorithm_hpp_1337420

#include "../ztl_base.hpp"

__ztl_namespace_start

template<typename T> void swap(T& t1, T& t2) {
	T tmp(t1);
	t1 = t2;
	t2 = tmp;
}

template<typename T>
void memset32(T *dest, int32_t val, uint32_t count) {
	/*__asm {
		mov ecx, val
		mov eax, count
		mov edi, dest
		rep stosd
	};*/
	while (count--)
		*dest++ = val;
}

template<typename T>
void memset_custom(T *dest, T val, uint32_t count) {
	while (count--)
		*dest++ = val;
}

__ztl_namespace_end

#endif /*_algorithm_hpp_1337420 */
<commit_msg>Fix memset parameters<commit_after>#ifndef _algorithm_hpp_1337420
#define _algorithm_hpp_1337420

#include "../ztl_base.hpp"

__ztl_namespace_start

template<typename T> void swap(T& t1, T& t2) {
	T tmp(t1);
	t1 = t2;
	t2 = tmp;
}

template<typename T>
void memset32(T *dest, T val, uint32_t count) {
	/*__asm {
		mov ecx, val
		mov eax, count
		mov edi, dest
		rep stosd
	};*/
	while (count--)
		*dest++ = val;
}

template<typename T>
void memset_custom(T *dest, T val, uint32_t count) {
	while (count--)
		*dest++ = val;
}

__ztl_namespace_end

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


<commit_before>/*
 * This istream filter reads a 32 bit header size from the stream,
 * reads it into a buffer and invokes a callback with the tail of the
 * stream.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "sink_header.hxx"
#include "istream_pointer.hxx"
#include "istream_oo.hxx"
#include "async.hxx"
#include "util/Cast.hxx"
#include "util/ByteOrder.hxx"

#include <glib.h>

#include <assert.h>
#include <string.h>
#include <stdint.h>

struct HeaderSink {
    struct istream output;

    enum {
        SIZE, HEADER, CALLBACK, DATA
    } state = SIZE;

    IstreamPointer input;

    unsigned char size_buffer[4];

    unsigned char *buffer;
    size_t size, position = 0;

    /**
     * How much data of the input is pending to be consumed?  Only
     * valid while state==CALLBACK.
     */
    size_t pending;

    const struct sink_header_handler *handler;
    void *handler_ctx;

    struct async_operation operation;

    void Abort() {
        input.Close();
        istream_deinit(&output);
    }

    size_t InvokeCallback(size_t consumed);

    size_t ConsumeSize(const void *data, size_t length);
    size_t ConsumeHeader(const void *data, size_t length);

    /* handler */

    size_t OnData(const void *data, size_t length);
    ssize_t OnDirect(FdType type, int fd, size_t max_length);
    void OnEof();
    void OnError(GError *error);
};

static GQuark
sink_header_quark(void)
{
    return g_quark_from_static_string("sink_header");
}

size_t
HeaderSink::InvokeCallback(size_t consumed)
{
    assert(state == SIZE || state == HEADER);

    operation.Finished();

    const ScopePoolRef ref(*output.pool TRACE_ARGS);

    /* the base value has been set by sink_header_input_data() */
    pending += consumed;

    state = CALLBACK;
    handler->done(buffer, size,
                  &output,
                  handler_ctx);

    if (input.IsDefined()) {
        state = DATA;
        input.SetDirect(output.handler_direct);
    } else
        /* we have been closed meanwhile; bail out */
        consumed = 0;

    return consumed;
}

inline size_t
HeaderSink::ConsumeSize(const void *data, size_t length)
{
    assert(position < sizeof(size_buffer));

    if (length > sizeof(size_buffer) - position)
        length = sizeof(size_buffer) - position;

    memcpy(size_buffer + position, data, length);
    position += length;

    if (position < sizeof(size_buffer))
        return length;

    const uint32_t *size_p = (const uint32_t *)(const void *)size_buffer;
    size = FromBE32(*size_p);
    if (size > 0x100000) {
        /* header too large */
        operation.Finished();
        input.Close();

        GError *error =
            g_error_new_literal(sink_header_quark(), 0,
                                "header is too large");
        handler->error(error, handler_ctx);
        istream_deinit(&output);
        return 0;
    }

    if (size > 0) {
        buffer = (unsigned char *)
            p_malloc(output.pool, size);
        state = HeaderSink::HEADER;
        position = 0;
    } else {
        /* header empty: don't allocate, invoke callback now */

        buffer = nullptr;

        length = InvokeCallback(length);
    }

    return length;
}

inline size_t
HeaderSink::ConsumeHeader(const void *data, size_t length)
{
    size_t nbytes = size - position;

    assert(position < size);

    if (nbytes > length)
        nbytes = length;

    memcpy(buffer + position, data, nbytes);
    position += nbytes;

    if (position < size)
        return nbytes;

    return InvokeCallback(nbytes);
}

/*
 * istream handler
 *
 */

inline size_t
HeaderSink::OnData(const void *data0, size_t length)
{
    const unsigned char *data = (const unsigned char *)data0;
    size_t consumed = 0, nbytes;

    if (state == DATA)
        return istream_invoke_data(&output, data, length);

    if (state == SIZE) {
        pending = 0; /* just in case the callback is invoked */

        consumed = ConsumeSize(data, length);
        if (consumed == 0)
            return 0;

        if (consumed == length)
            return length;

        data += consumed;
        length -= consumed;
    }

    if (state == HEADER) {
        pending = consumed; /* just in case the callback is invoked */

        nbytes = ConsumeHeader(data, length);
        if (nbytes == 0)
            return 0;

        consumed += nbytes;
        if (consumed == length)
            return length;

        data += nbytes;
        length -= nbytes;
    }

    assert(consumed > 0);

    if (state == DATA && length > 0) {
        const ScopePoolRef ref(*output.pool TRACE_ARGS);

        nbytes = istream_invoke_data(&output, data, length);
        if (nbytes == 0 && !input.IsDefined())
            consumed = 0;
        else
            consumed += nbytes;
    }

    return consumed;
}

inline ssize_t
HeaderSink::OnDirect(FdType type, int fd, size_t max_length)
{
    assert(state == DATA);

    return istream_invoke_direct(&output, type, fd, max_length);
}

inline void
HeaderSink::OnEof()
{
    GError *error;

    switch (state) {
    case SIZE:
    case HEADER:
        operation.Finished();

        error = g_error_new_literal(sink_header_quark(), 0,
                                    "premature end of file");
        handler->error(error, handler_ctx);
        istream_deinit(&output);
        break;

    case CALLBACK:
        assert(false);
        gcc_unreachable();

    case DATA:
        istream_deinit_eof(&output);
        break;
    }
}

inline void
HeaderSink::OnError(GError *error)
{
    switch (state) {
    case SIZE:
    case HEADER:
        operation.Finished();
        handler->error(error, handler_ctx);
        istream_deinit(&output);
        break;

    case CALLBACK:
        assert(false);
        gcc_unreachable();

    case DATA:
        istream_deinit_abort(&output, error);
        break;
    }
}

/*
 * istream implementation
 *
 */

static inline HeaderSink *
istream_to_header(struct istream *istream)
{
    return &ContainerCast2(*istream, &HeaderSink::output);
}

static off_t
sink_header_available(struct istream *istream, bool partial)
{
    HeaderSink *header = istream_to_header(istream);
    off_t available = header->input.GetAvailable(partial);

    if (available >= 0 && header->state == HeaderSink::CALLBACK) {
        if (available < (off_t)header->pending) {
            assert(partial);

            return -1;
        }

        available -= header->pending;
    }

    return available;
}

static void
sink_header_read(struct istream *istream)
{
    HeaderSink *header = istream_to_header(istream);

    if (header->state == HeaderSink::CALLBACK)
        /* workaround: when invoking the callback from the data()
           handler, it would be illegal to call header->input again */
        return;

    header->input.SetDirect(header->output.handler_direct);
    header->input.Read();
}

static void
sink_header_close(struct istream *istream)
{
    HeaderSink *header = istream_to_header(istream);

    header->input.ClearAndClose();
    istream_deinit(&header->output);
}

static const struct istream_class istream_sink = {
    .available = sink_header_available,
    .read = sink_header_read,
    .close = sink_header_close,
};

/*
 * constructor
 *
 */

void
sink_header_new(struct pool *pool, struct istream *input,
                const struct sink_header_handler *handler, void *ctx,
                struct async_operation_ref *async_ref)
{
    assert(input != NULL);
    assert(!istream_has_handler(input));
    assert(handler != NULL);
    assert(handler->done != NULL);
    assert(handler->error != NULL);

    auto header = NewFromPool<HeaderSink>(*pool);
    istream_init(&header->output, &istream_sink, pool);

    header->input.Set(*input,
                      MakeIstreamHandler<HeaderSink>::handler, header);

    header->handler = handler;
    header->handler_ctx = ctx;

    header->operation.Init2<HeaderSink>();
    async_ref->Set(header->operation);
}
<commit_msg>sink_header: use class ForwardIstream<commit_after>/*
 * This istream filter reads a 32 bit header size from the stream,
 * reads it into a buffer and invokes a callback with the tail of the
 * stream.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "sink_header.hxx"
#include "ForwardIstream.hxx"
#include "async.hxx"
#include "util/Cast.hxx"
#include "util/ByteOrder.hxx"

#include <glib.h>

#include <assert.h>
#include <string.h>
#include <stdint.h>

class HeaderSink final : public ForwardIstream {
    enum {
        SIZE, HEADER, CALLBACK, DATA
    } state = SIZE;

    unsigned char size_buffer[4];

    unsigned char *buffer;
    size_t size, position = 0;

    /**
     * How much data of the input is pending to be consumed?  Only
     * valid while state==CALLBACK.
     */
    size_t pending;

    const struct sink_header_handler *handler;
    void *handler_ctx;

    struct async_operation operation;

public:
    HeaderSink(struct pool &_pool, struct istream &_input,
               const struct sink_header_handler &_handler, void *_ctx,
               struct async_operation_ref &async_ref)
        :ForwardIstream(_pool, _input,
                        MakeIstreamHandler<HeaderSink>::handler, this),
         handler(&_handler), handler_ctx(_ctx) {
        operation.Init2<HeaderSink, &HeaderSink::operation>();
        async_ref.Set(operation);
    }

    void Abort() {
        input.Close();
        Destroy();
    }

    size_t InvokeCallback(size_t consumed);

    size_t ConsumeSize(const void *data, size_t length);
    size_t ConsumeHeader(const void *data, size_t length);

    /* virtual methods from class Istream */

    off_t GetAvailable(bool partial) override;

    void Read() override {
        if (state == HeaderSink::CALLBACK)
            /* workaround: when invoking the callback from the data()
               handler, it would be illegal to call header->input again */
            return;

        ForwardIstream::Read();
    }

    /* handler */

    size_t OnData(const void *data, size_t length);
    ssize_t OnDirect(FdType type, int fd, size_t max_length);
    void OnEof();
    void OnError(GError *error);
};

static GQuark
sink_header_quark(void)
{
    return g_quark_from_static_string("sink_header");
}

size_t
HeaderSink::InvokeCallback(size_t consumed)
{
    assert(state == SIZE || state == HEADER);

    operation.Finished();

    const ScopePoolRef ref(GetPool() TRACE_ARGS);

    /* the base value has been set by sink_header_input_data() */
    pending += consumed;

    state = CALLBACK;
    handler->done(buffer, size,
                  Cast(),
                  handler_ctx);

    if (input.IsDefined()) {
        state = DATA;
        input.SetDirect(GetHandlerDirect());
    } else
        /* we have been closed meanwhile; bail out */
        consumed = 0;

    return consumed;
}

inline size_t
HeaderSink::ConsumeSize(const void *data, size_t length)
{
    assert(position < sizeof(size_buffer));

    if (length > sizeof(size_buffer) - position)
        length = sizeof(size_buffer) - position;

    memcpy(size_buffer + position, data, length);
    position += length;

    if (position < sizeof(size_buffer))
        return length;

    const uint32_t *size_p = (const uint32_t *)(const void *)size_buffer;
    size = FromBE32(*size_p);
    if (size > 0x100000) {
        /* header too large */
        operation.Finished();
        input.Close();

        GError *error =
            g_error_new_literal(sink_header_quark(), 0,
                                "header is too large");
        handler->error(error, handler_ctx);
        Destroy();
        return 0;
    }

    if (size > 0) {
        buffer = (unsigned char *)p_malloc(&GetPool(), size);
        state = HeaderSink::HEADER;
        position = 0;
    } else {
        /* header empty: don't allocate, invoke callback now */

        buffer = nullptr;

        length = InvokeCallback(length);
    }

    return length;
}

inline size_t
HeaderSink::ConsumeHeader(const void *data, size_t length)
{
    size_t nbytes = size - position;

    assert(position < size);

    if (nbytes > length)
        nbytes = length;

    memcpy(buffer + position, data, nbytes);
    position += nbytes;

    if (position < size)
        return nbytes;

    return InvokeCallback(nbytes);
}

/*
 * istream handler
 *
 */

inline size_t
HeaderSink::OnData(const void *data0, size_t length)
{
    const unsigned char *data = (const unsigned char *)data0;
    size_t consumed = 0, nbytes;

    if (state == DATA)
        return InvokeData(data, length);

    if (state == SIZE) {
        pending = 0; /* just in case the callback is invoked */

        consumed = ConsumeSize(data, length);
        if (consumed == 0)
            return 0;

        if (consumed == length)
            return length;

        data += consumed;
        length -= consumed;
    }

    if (state == HEADER) {
        pending = consumed; /* just in case the callback is invoked */

        nbytes = ConsumeHeader(data, length);
        if (nbytes == 0)
            return 0;

        consumed += nbytes;
        if (consumed == length)
            return length;

        data += nbytes;
        length -= nbytes;
    }

    assert(consumed > 0);

    if (state == DATA && length > 0) {
        const ScopePoolRef ref(GetPool() TRACE_ARGS);

        nbytes = InvokeData(data, length);
        if (nbytes == 0 && !input.IsDefined())
            consumed = 0;
        else
            consumed += nbytes;
    }

    return consumed;
}

inline ssize_t
HeaderSink::OnDirect(FdType type, int fd, size_t max_length)
{
    assert(state == DATA);

    return ForwardIstream::OnDirect(type, fd, max_length);
}

inline void
HeaderSink::OnEof()
{
    GError *error;

    switch (state) {
    case SIZE:
    case HEADER:
        operation.Finished();

        error = g_error_new_literal(sink_header_quark(), 0,
                                    "premature end of file");
        handler->error(error, handler_ctx);
        Destroy();
        break;

    case CALLBACK:
        assert(false);
        gcc_unreachable();

    case DATA:
        DestroyEof();
        break;
    }
}

inline void
HeaderSink::OnError(GError *error)
{
    switch (state) {
    case SIZE:
    case HEADER:
        operation.Finished();
        handler->error(error, handler_ctx);
        Destroy();
        break;

    case CALLBACK:
        assert(false);
        gcc_unreachable();

    case DATA:
        DestroyError(error);
        break;
    }
}

/*
 * istream implementation
 *
 */

off_t
HeaderSink::GetAvailable(bool partial)
{
    off_t available = ForwardIstream::GetAvailable(partial);

    if (available >= 0 && state == HeaderSink::CALLBACK) {
        if (available < (off_t)pending) {
            assert(partial);

            return -1;
        }

        available -= pending;
    }

    return available;
}

/*
 * constructor
 *
 */

void
sink_header_new(struct pool *pool, struct istream *input,
                const struct sink_header_handler *handler, void *ctx,
                struct async_operation_ref *async_ref)
{
    assert(input != NULL);
    assert(!istream_has_handler(input));
    assert(handler != NULL);
    assert(handler->done != NULL);
    assert(handler->error != NULL);

    NewIstream<HeaderSink>(*pool, *input, *handler, ctx, *async_ref);

}
<|endoftext|>


<commit_before>#include "LanguageTranslator.h"

#include <sstream>

#include "Logger.h"
#include "StringUtils.h"

std::vector<std::wstring> LanguageTranslator::CurrentLocale() {
    wchar_t buf[LOCALE_NAME_MAX_LENGTH];
    GetUserDefaultLocaleName(buf, LOCALE_NAME_MAX_LENGTH);
    CLOG(L"Locale: %s", buf);

    std::wstring locale(buf);

    /* Remove custom supplemental locales */
    int custom = locale.find(L"-x-");
    if (custom > 0) {
        locale.erase(custom, locale.size() - 1);
    }

    /* Split up parts of the locale string */
    std::vector<std::wstring> parts;
    std::wstring sub;
    std::wistringstream ss(locale);
    while (std::getline(ss, sub, L'-')) {
        parts.push_back(sub);
    }

    std::vector<std::wstring> finalLocale;
    for (std::wstring sub : parts) {
        /* Remove sort orders */
        int sort = sub.find(L"_");
        if (sort > 0) {
            sub.erase(sort, sub.size() - 1);
        }

        finalLocale.push_back(sub);
    }

    return finalLocale;
}

LanguageTranslator::LanguageTranslator() {

}

LanguageTranslator::LanguageTranslator(std::wstring langFileName) {
    CLOG(L"Loading language XML: %s", langFileName.c_str());
    std::string u8FileName = StringUtils::Narrow(langFileName);
    tinyxml2::XMLError result = _xml.LoadFile(u8FileName.c_str());
    if (result != tinyxml2::XMLError::XML_SUCCESS) {
        if (result == tinyxml2::XMLError::XML_ERROR_FILE_NOT_FOUND) {
            //Error::ErrorMessageDie(SKINERR_INVALID_SKIN);
        }
        throw std::logic_error("Failed to read XML file!");
    }

    _root = _xml.GetDocument()->FirstChildElement("translation");
    if (_root == NULL) {
        throw std::runtime_error("Could not find root XML element");
    }

    _author = StringUtils::Widen(_root->Attribute("author", ""));
    tinyxml2::XMLElement *trans = _root->FirstChildElement("language");
    if (trans == NULL) {
        CLOG(L"No <language> tag.");
    }

    CLOG(L"Loading translation header");
    _name = StringUtils::Widen(trans->Attribute("name"));
    _id = StringUtils::Widen(trans->Attribute("id"));

    if (_name == L"" || _id == L"") {
        CLOG(L"whoops");
    }

    QCLOG(L"Language name: %s", _name.c_str());
    QCLOG(L"Locale identifier: %s", _id.c_str());
    const char *regions = trans->Attribute("regions");
    if (regions != NULL) {
        std::string region;
        std::istringstream ss(regions);
        while (std::getline(ss, region, ',')) {
            std::wstring regionStr = StringUtils::Widen(region);
            _regions.push_back(regionStr);
            QCLOG(L"Region: %s", regionStr.c_str());
        }
    }

    tinyxml2::XMLElement *string = _root->FirstChildElement("string");
    for (; string != NULL; string = string->NextSiblingElement()) {
        /* parse translation */
    }

}

std::wstring LanguageTranslator::Translate(std::wstring str) {
    return str;
}<commit_msg>Fix the build<commit_after>#include "LanguageTranslator.h"

#include <sstream>

#include "Logger.h"
#include "StringUtils.h"

std::vector<std::wstring> LanguageTranslator::CurrentLocale() {
    wchar_t buf[LOCALE_NAME_MAX_LENGTH];
    GetUserDefaultLocaleName(buf, LOCALE_NAME_MAX_LENGTH);
    CLOG(L"Locale: %s", buf);

    std::wstring locale(buf);

    /* Remove custom supplemental locales */
    int custom = locale.find(L"-x-");
    if (custom > 0) {
        locale.erase(custom, locale.size() - 1);
    }

    /* Split up parts of the locale string */
    std::vector<std::wstring> parts;
    std::wstring sub;
    std::wistringstream ss(locale);
    while (std::getline(ss, sub, L'-')) {
        parts.push_back(sub);
    }

    std::vector<std::wstring> finalLocale;
    for (std::wstring sub : parts) {
        /* Remove sort orders */
        int sort = sub.find(L"_");
        if (sort > 0) {
            sub.erase(sort, sub.size() - 1);
        }

        finalLocale.push_back(sub);
    }

    return finalLocale;
}

LanguageTranslator::LanguageTranslator() {

}

LanguageTranslator::LanguageTranslator(std::wstring langFileName) {
    CLOG(L"Loading language XML: %s", langFileName.c_str());
    std::string u8FileName = StringUtils::Narrow(langFileName);
    tinyxml2::XMLError result = _xml.LoadFile(u8FileName.c_str());
    if (result != tinyxml2::XMLError::XML_SUCCESS) {
        if (result == tinyxml2::XMLError::XML_ERROR_FILE_NOT_FOUND) {
            //Error::ErrorMessageDie(SKINERR_INVALID_SKIN);
        }
        throw std::logic_error("Failed to read XML file!");
    }

    _root = _xml.GetDocument()->FirstChildElement("translation");
    if (_root == NULL) {
        throw std::runtime_error("Could not find root XML element");
    }

    _author = StringUtils::Widen(_root->Attribute("author", ""));
    tinyxml2::XMLElement *trans = _root->FirstChildElement("language");
    if (trans == NULL) {
        CLOG(L"No <language> tag.");
    }

    CLOG(L"Loading translation header");
    _name = StringUtils::Widen(trans->Attribute("name"));
    _id = StringUtils::Widen(trans->Attribute("id"));

    if (_name == L"" || _id == L"") {
        CLOG(L"whoops");
    }

    QCLOG(L"Language name: %s", _name.c_str());
    QCLOG(L"Locale identifier: %s", _id.c_str());
    const char *regions = trans->Attribute("regions");
    if (regions != NULL) {
        std::string region;
        std::istringstream ss(regions);
        while (std::getline(ss, region, ',')) {
            std::wstring regionStr = StringUtils::Widen(region);
            _regions.push_back(regionStr);
            QCLOG(L"Region: %s", regionStr.c_str());
        }
    }

    tinyxml2::XMLElement *string = _root->FirstChildElement("string");
    for (; string != NULL; string = string->NextSiblingElement()) {
        string->FirstChildElement("resource");
        /* parse translation */
    }

}

std::wstring LanguageTranslator::Translate(std::wstring str) {
    return str;
}<|endoftext|>


<commit_before>#include <iostream>

#include <cstring>
#include <csignal>

#include <unistd.h>

#include "gestionFichiersw.hpp"
#include "pipe.hpp"

constexpr size_t const TAILLEBUF = 255;

int main() {
	try {
		Pipe myPipe(/* nonBlocking = */ true);
		pid_t pid = fork();

		if(pid == -1) {
			std::perror("fork() a échoué");
			exit(errno);
		} else if(pid == 0) {
			char status[TAILLEBUF];

			sleep(10);

			myPipe >> status;

			if(std::strcmp(status, "Finished\n")) {
				std::cout << "Too late: safe closed." << std::endl;
				myPipe << "Too late\n";
				return EPERM;
			}

		} else {
			try {
				char code[TAILLEBUF];
				std::cout << "You have 10 seconds to open the safe." << std::endl
				          << "Please enter the code of the safe: " << std::flush;

				IFile consoleIn(0, TAILLEBUF);
				consoleIn >> code;

				char status[TAILLEBUF];
				myPipe >> status;
				myPipe << "Finished\n";

				bool invalidCode = std::strcmp(code, "1234\n"),
				     notTooLate = std::strcmp(status, "Too late\n");
				if(notTooLate) {
					if(invalidCode) {
						std::cout << "Code incorrect: safe closed" << std::endl;
					} else {
						std::cout << "Code correct: safe opened." << std::endl;
					}
				}

			} catch(std::ios_base::failure const& e) {
				std::cerr << "Error: " << e.what() << std::endl;
				return e.code().value();
			}
		}

	} catch(std::system_error const& e) {
		std::cerr << "Error: " << e.what() << std::endl;
		return e.code().value();
	}
}
<commit_msg>Using signals instead of pipes for TD3-exIII<commit_after>#include <iostream>

#include <cstring>
#include <csignal>

#include <unistd.h>

#include "gestionFichiersw.hpp"
#include "pipe.hpp"

constexpr size_t const TAILLEBUF = 255;

int main() {
	try {
		pid_t pid = fork();

		if(pid == -1) {
			std::perror("fork() a échoué");
			exit(errno);
		} else if(pid == 0) {
			sleep(10);
			kill(getppid(), SIGUSR1);
			return EPERM;
		} else {
			try {
				char code[TAILLEBUF];
				std::cout << "You have 10 seconds to open the safe." << std::endl
				          << "Please enter the code of the safe: " << std::flush;

				//bool notTooLate = true;

				// Cannot pass a lambda with a capture to signal (cannot be converted to a function
				// pointer)
				signal(SIGUSR1, [/*&notTooLate*/](int sig) {
					if(sig == SIGUSR1) {
						std::cout << "\nToo late: safe closed" << std::endl;
						// notTooLate = false;
						wait();
						exit(EPERM);
					}
				});

				IFile consoleIn(0, TAILLEBUF);
				consoleIn >> code;

				bool invalidCode = std::strcmp(code, "1234\n");

				if(invalidCode) {
					std::cout << "Code incorrect: safe closed" << std::endl;
				} else {
					std::cout << "Code correct: safe opened." << std::endl;
				}

				signal(SIGUSR1, SIG_IGN);
				// Stop the child
				kill(pid, SIGTERM);

				return invalidCode ? EPERM : 0;

			} catch(std::ios_base::failure const& e) {
				std::cerr << "Error: " << e.what() << std::endl;
				return e.code().value();
			}
		}

	} catch(std::system_error const& e) {
		std::cerr << "Error: " << e.what() << std::endl;
		return e.code().value();
	}
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "Riostream.h"

#include <TClonesArray.h>
#include "AliRun.h"
#include "AliRunLoader.h"
#include "AliACORDETrigger.h"
#include "AliACORDEConstants.h"

//______________________________________________________________________
ClassImp(AliACORDETrigger)

AliACORDETrigger::AliACORDETrigger()
  :AliTriggerDetector(),
   fSingleMuon(0),
   fMultiMuon(0)
{

  cout << " ================>>>>>>>>>>>>>>>>> AliACORDETrigger" << endl;
   SetName("ACORDE");
   CreateInputs();
   for (Int_t i=0; i<60; i++) fModuleFired[i]=kFALSE;
}

void AliACORDETrigger::CreateInputs()
{
  // Do not create inputs again!!
  if( fInputs.GetEntriesFast() > 0 ) return;

  // two acorde triggers, single muon and multicoincidence
  fInputs.AddLast( new
		   AliTriggerInput( "ACORDE_SINGLE",
				    "ACORDE", 0 ) );
  fInputs.AddLast( new
		   AliTriggerInput( "ACORDE_MULTI",
				    "ACORDE", 0 ) );
}

void AliACORDETrigger::Trigger()
{

  // 1.- Get loaders and pointers
  // 2.- Loop over all entries
  //     set temporal variables to default values
  //     start the loop
  // 3.- Loop over all digits in an entrie
  //     Fill temporal arrays
  //     Find module with lowest time
  // 4.- Loop over temporal arrays
  //     Find number of modules within the time window
  // 5.- Set the relevant trigger

  // 1.- Get loaders and pointers
  AliRunLoader* runLoader = AliRunLoader::Instance();
  AliACORDELoader* loader =
    (AliACORDELoader* )runLoader->GetLoader( "ACORDELoader" );
  loader->LoadDigits("READ");
  TTree* acordeDigitsTree = loader->TreeD();
  if (!acordeDigitsTree) return;
  TClonesArray* acordeDigits = new TClonesArray("AliACORDEdigit",1000);
  TBranch* digitBranch = acordeDigitsTree->GetBranch("ACORDEdigit");
  digitBranch->SetAddress(&acordeDigits);

  // 2.- Loop over all entries
  //     set temporal variables to default values

  Int_t MultiMin = AliACORDEConstants::Instance()->MultiMuonThreshold();
  Float_t time_window = AliACORDEConstants::Instance()->MultiMuonWindow();
  Int_t MinTimeModule = -1;
  Float_t MinTime = 1e10;
  Float_t ModuleTimes[60];
  for (Int_t i=0; i<60; i++) ModuleTimes[i] = -1.0;

  //     start the loop
  Int_t nEntries = (Int_t)acordeDigitsTree->GetEntries();
  cout << " ===AliACORDETrigger=== nEntries  " <<nEntries << endl;
  for (Int_t e=0; e<nEntries; e++) {
    acordeDigitsTree->GetEvent(e);
    // 3.- Loop over all digits in an entrie
    //     Fill temporal arrays
    //     Find module with lowest time
    Int_t nDigits = acordeDigits->GetEntriesFast();
    cout << " ===AliACORDETrigger=== nDigits  " <<nDigits << endl;
    for (Int_t d=0; d<nDigits; d++) {
      AliACORDEdigit* digit = (AliACORDEdigit*)acordeDigits->At(d);
      Int_t module = digit->GetModule();
      Float_t mod_time = digit->GetTime();
      ModuleTimes[module-1]=mod_time;
      if (mod_time < MinTime) {
	MinTime = mod_time;
	MinTimeModule = module;
      }
    } // end of loop over digits
  } // end of loop over events in digits tree

  // 4.- Loop over temporal arrays
  //     Find number of modules within the time window
  if (MinTimeModule == -1) return;
  for (Int_t i=0; i<60; i++) {
    if (ModuleTimes[i]<0) continue;
    Float_t diff = ModuleTimes[i]-MinTime;
    if (diff<time_window) {
      fMultiMuon++;
      fModuleFired[i]=kTRUE;
    }
  }
  cout << " fSingleMuon " << fSingleMuon
       << " MinTime " << MinTime
       << " fMultiMuon " << fMultiMuon << endl;
  // 5.- Set the relevant trigger
  fSingleMuon = MinTimeModule;
  SetInput( "ACORDE_SINGLE" );
  if (fMultiMuon>=MultiMin) SetInput( "ACORDE_MULTI" );
  return;
}
<commit_msg>ACORDE trigger inputs following trigger naming conventions<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "Riostream.h"

#include <TClonesArray.h>
#include "AliRun.h"
#include "AliRunLoader.h"
#include "AliACORDETrigger.h"
#include "AliACORDEConstants.h"

//______________________________________________________________________
ClassImp(AliACORDETrigger)

AliACORDETrigger::AliACORDETrigger()
  :AliTriggerDetector(),
   fSingleMuon(0),
   fMultiMuon(0)
{

  cout << " ================>>>>>>>>>>>>>>>>> AliACORDETrigger" << endl;
   SetName("ACORDE");
   CreateInputs();
   for (Int_t i=0; i<60; i++) fModuleFired[i]=kFALSE;
}

void AliACORDETrigger::CreateInputs()
{
  // Do not create inputs again!!
  if( fInputs.GetEntriesFast() > 0 ) return;

  // two acorde triggers, single muon and multicoincidence
  fInputs.AddLast( new
		   AliTriggerInput( "0ASL",
				    "ACORDE", 0 ) );
  fInputs.AddLast( new
		   AliTriggerInput( "0AMU",
				    "ACORDE", 0 ) );
}

void AliACORDETrigger::Trigger()
{

  // 1.- Get loaders and pointers
  // 2.- Loop over all entries
  //     set temporal variables to default values
  //     start the loop
  // 3.- Loop over all digits in an entrie
  //     Fill temporal arrays
  //     Find module with lowest time
  // 4.- Loop over temporal arrays
  //     Find number of modules within the time window
  // 5.- Set the relevant trigger

  // 1.- Get loaders and pointers
  AliRunLoader* runLoader = AliRunLoader::Instance();
  AliACORDELoader* loader =
    (AliACORDELoader* )runLoader->GetLoader( "ACORDELoader" );
  loader->LoadDigits("READ");
  TTree* acordeDigitsTree = loader->TreeD();
  if (!acordeDigitsTree) return;
  TClonesArray* acordeDigits = new TClonesArray("AliACORDEdigit",1000);
  TBranch* digitBranch = acordeDigitsTree->GetBranch("ACORDEdigit");
  digitBranch->SetAddress(&acordeDigits);

  // 2.- Loop over all entries
  //     set temporal variables to default values

  Int_t MultiMin = AliACORDEConstants::Instance()->MultiMuonThreshold();
  Float_t time_window = AliACORDEConstants::Instance()->MultiMuonWindow();
  Int_t MinTimeModule = -1;
  Float_t MinTime = 1e10;
  Float_t ModuleTimes[60];
  for (Int_t i=0; i<60; i++) ModuleTimes[i] = -1.0;

  //     start the loop
  Int_t nEntries = (Int_t)acordeDigitsTree->GetEntries();
  cout << " ===AliACORDETrigger=== nEntries  " <<nEntries << endl;
  for (Int_t e=0; e<nEntries; e++) {
    acordeDigitsTree->GetEvent(e);
    // 3.- Loop over all digits in an entrie
    //     Fill temporal arrays
    //     Find module with lowest time
    Int_t nDigits = acordeDigits->GetEntriesFast();
    cout << " ===AliACORDETrigger=== nDigits  " <<nDigits << endl;
    for (Int_t d=0; d<nDigits; d++) {
      AliACORDEdigit* digit = (AliACORDEdigit*)acordeDigits->At(d);
      Int_t module = digit->GetModule();
      Float_t mod_time = digit->GetTime();
      ModuleTimes[module-1]=mod_time;
      if (mod_time < MinTime) {
	MinTime = mod_time;
	MinTimeModule = module;
      }
    } // end of loop over digits
  } // end of loop over events in digits tree

  // 4.- Loop over temporal arrays
  //     Find number of modules within the time window
  if (MinTimeModule == -1) return;
  for (Int_t i=0; i<60; i++) {
    if (ModuleTimes[i]<0) continue;
    Float_t diff = ModuleTimes[i]-MinTime;
    if (diff<time_window) {
      fMultiMuon++;
      fModuleFired[i]=kTRUE;
    }
  }
  cout << " fSingleMuon " << fSingleMuon
       << " MinTime " << MinTime
       << " fMultiMuon " << fMultiMuon << endl;
  // 5.- Set the relevant trigger
  fSingleMuon = MinTimeModule;
  SetInput( "0ASL" );
  if (fMultiMuon>=MultiMin) SetInput( "0AMU" );
  return;
}
<|endoftext|>


<commit_before>#include <pqxx/transaction>

#include "../test_helpers.hxx"

namespace
{
/// Test conversions for some floating-point type.
template<typename T> void infinity_test()
{
  T inf{std::numeric_limits<T>::infinity()};
  std::string inf_string;
  T back_conversion;

  inf_string = pqxx::to_string(inf);
  pqxx::from_string(inf_string, back_conversion);
  PQXX_CHECK_LESS(
    T(999999999), back_conversion,
    "Infinity doesn't convert back to something huge.");

  inf_string = pqxx::to_string(-inf);
  pqxx::from_string(inf_string, back_conversion);
  PQXX_CHECK_LESS(
    back_conversion, -T(999999999), "Negative infinity is broken");
}

void test_infinities()
{
  infinity_test<float>();
  infinity_test<double>();
  infinity_test<long double>();
}

/// Reproduce bug #262: repeated float conversions break without charconv.
template<typename T> void bug_262()
{
  pqxx::connection conn;
  conn.prepare("stmt", "select cast($1 as float)");
  pqxx::work tr{conn};

  // We must use the same float type both for passing the value to the
  // statement and for retrieving result of the statement execution.  This is
  // due to an internal stringstream being instantiated as a a parameterized
  // thread-local singleton.  So, there are separate stream<float>,
  // stream<double>, stream<long double>, but every such instance is a
  // singleton. We should use only one of them for this test.

  pqxx::row row;

  // Nothing bad here, select a float value.
  // The stream is clear, so just fill it with the value and extract str().
  row = tr.exec1("SELECT 1.0");

  // This works properly, but as we parse the value from the stream, the
  // seeking cursor moves towards the EOF. When the inevitable EOF happens
  // 'eof' flag is set in the stream and 'good' flag is unset.
  row[0].as<T>();

  // The second try. Select a float value again. The stream is not clean, so
  // we need to put an empty string into its buffer {stream.str("");}. This
  // resets the seeking cursor to 0. Then we will put the value using
  // operator<<().
  // ...
  // ...
  // OOPS. stream.str("") does not reset 'eof' flag and 'good' flag! We are
  // trying to read from EOF! This is no good.
  // Throws on unpatched pqxx v6.4.5
  row = tr.exec1("SELECT 2.0");

  // We won't get here without patch. The following statements are just for
  // demonstration of how are intended to work. If we
  // simply just reset the stream flags properly, this would work fine.
  // The most obvious patch is just explicitly stream.seekg(0).
  row[0].as<T>();
  row = tr.exec1("SELECT 3.0");
  row[0].as<T>();
}

/// Test for bug #262.
void test_bug_262()
{
  bug_262<float>();
  bug_262<double>();
  bug_262<long double>();
}

/// Test conversion of malformed floating-point values.
void test_bad_float()
{
  float x [[maybe_unused]];
  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>(""), pqxx::conversion_error,
    "Conversion of empty string to float was not caught.");

  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("Infancy"), pqxx::conversion_error,
    "Misleading infinity was not caught.");
  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("-Infighting"), pqxx::conversion_error,
    "Misleading negative infinity was not caught.");

  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("Nanny"), pqxx::conversion_error,
    "Conversion of misleading NaN was not caught.");
}

/// Test conversion of long float values to strings.
void test_long_float()
{
  auto const dot_one{pqxx::to_string(0.1)};
  auto const detailed_double{-1.3339772437713657e-322};
  auto const detailed{pqxx::to_string(detailed_double)};
  PQXX_CHECK_LESS_EQUAL(
    dot_one.size(), 25u, "0.1 converted to too long a string.");
  PQXX_CHECK_LESS_EQUAL(
    pqxx::to_string(detailed).size(), 25u,
    "Detailed double converted to too long a string.");
  PQXX_CHECK_GREATER_EQUAL(
    pqxx::string_traits<double>::size_buffer(0.1), dot_one.size() + 1,
    "Not enough buffer space for 0.1.");
  PQXX_CHECK_GREATER_EQUAL(
    pqxx::string_traits<double>::size_buffer(detailed_double), 25u,
    "Not enough buffer space for -1.3339772437713657e-322.");
}

PQXX_REGISTER_TEST(test_infinities);
PQXX_REGISTER_TEST(test_bug_262);
PQXX_REGISTER_TEST(test_bad_float);
PQXX_REGISTER_TEST(test_long_float);
} // namespace
<commit_msg>Smoke testing for #328.<commit_after>#include <cmath>

#include <pqxx/transaction>

#include "../test_helpers.hxx"

namespace
{
/// Test conversions for some floating-point type.
template<typename T> void infinity_test()
{
  T inf{std::numeric_limits<T>::infinity()};
  std::string inf_string;
  T back_conversion;

  inf_string = pqxx::to_string(inf);
  pqxx::from_string(inf_string, back_conversion);
  PQXX_CHECK_LESS(
    T(999999999), back_conversion,
    "Infinity doesn't convert back to something huge.");

  inf_string = pqxx::to_string(-inf);
  pqxx::from_string(inf_string, back_conversion);
  PQXX_CHECK_LESS(
    back_conversion, -T(999999999), "Negative infinity is broken");
}

void test_infinities()
{
  infinity_test<float>();
  infinity_test<double>();
  infinity_test<long double>();
}

/// Reproduce bug #262: repeated float conversions break without charconv.
template<typename T> void bug_262()
{
  pqxx::connection conn;
  conn.prepare("stmt", "select cast($1 as float)");
  pqxx::work tr{conn};

  // We must use the same float type both for passing the value to the
  // statement and for retrieving result of the statement execution.  This is
  // due to an internal stringstream being instantiated as a a parameterized
  // thread-local singleton.  So, there are separate stream<float>,
  // stream<double>, stream<long double>, but every such instance is a
  // singleton. We should use only one of them for this test.

  pqxx::row row;

  // Nothing bad here, select a float value.
  // The stream is clear, so just fill it with the value and extract str().
  row = tr.exec1("SELECT 1.0");

  // This works properly, but as we parse the value from the stream, the
  // seeking cursor moves towards the EOF. When the inevitable EOF happens
  // 'eof' flag is set in the stream and 'good' flag is unset.
  row[0].as<T>();

  // The second try. Select a float value again. The stream is not clean, so
  // we need to put an empty string into its buffer {stream.str("");}. This
  // resets the seeking cursor to 0. Then we will put the value using
  // operator<<().
  // ...
  // ...
  // OOPS. stream.str("") does not reset 'eof' flag and 'good' flag! We are
  // trying to read from EOF! This is no good.
  // Throws on unpatched pqxx v6.4.5
  row = tr.exec1("SELECT 2.0");

  // We won't get here without patch. The following statements are just for
  // demonstration of how are intended to work. If we
  // simply just reset the stream flags properly, this would work fine.
  // The most obvious patch is just explicitly stream.seekg(0).
  row[0].as<T>();
  row = tr.exec1("SELECT 3.0");
  row[0].as<T>();
}

/// Test for bug #262.
void test_bug_262()
{
  bug_262<float>();
  bug_262<double>();
  bug_262<long double>();
}

/// Test conversion of malformed floating-point values.
void test_bad_float()
{
  float x [[maybe_unused]];
  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>(""), pqxx::conversion_error,
    "Conversion of empty string to float was not caught.");

  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("Infancy"), pqxx::conversion_error,
    "Misleading infinity was not caught.");
  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("-Infighting"), pqxx::conversion_error,
    "Misleading negative infinity was not caught.");

  PQXX_CHECK_THROWS(
    x = pqxx::from_string<float>("Nanny"), pqxx::conversion_error,
    "Conversion of misleading NaN was not caught.");
}

template<typename T> void test_float_length(T value)
{
  auto const text{pqxx::to_string(value)};
  PQXX_CHECK_GREATER_EQUAL(
    pqxx::string_traits<T>::size_buffer(value), text.size() + 1,
    "Not enough buffer space for " + text + ".");
}

/// Test conversion of long float values to strings.
void test_long_float()
{
  test_float_length(0.1f);
  test_float_length(0.1);

  test_float_length(std::numeric_limits<float>::denorm_min());
  test_float_length(-std::numeric_limits<float>::denorm_min());
  test_float_length(std::numeric_limits<float>::max());
  test_float_length(-std::numeric_limits<double>::max());
  test_float_length(-std::nextafter(1.0f, 2.0f));

  test_float_length(std::numeric_limits<double>::denorm_min());
  test_float_length(-std::numeric_limits<double>::denorm_min());
  test_float_length(std::numeric_limits<double>::max());
  test_float_length(-std::numeric_limits<double>::max());
  test_float_length(-std::nextafter(1.0, 2.0));

  test_float_length(std::numeric_limits<long double>::denorm_min());
  test_float_length(-std::numeric_limits<long double>::denorm_min());
  test_float_length(std::numeric_limits<long double>::max());
  test_float_length(-std::numeric_limits<long double>::max());
  test_float_length(-std::nextafter(1.0L, 2.0L));

  auto constexpr awkward{-2.2250738585072014e-308};
  test_float_length(-1.3339772437713657e-322);
  test_float_length(awkward);
  test_float_length(-1.7976931348623157e+308);

  test_float_length(-1.3339772437713657e-322L);
  test_float_length(static_cast<long double>(awkward));
  test_float_length(-1.7976931348623157e+308L);

  // Ahem.  I'm not proud of this.  We really can't assume much about the
  // floating-point types, but I'd really like to try a few things to see that
  // buffer sizes are in the right ballpark.  So, if "double" is at least 64
  // bits, check for some examples of long conversions.
  if constexpr (sizeof(double) >= 8)
  {
    auto const text{pqxx::to_string(awkward)};
    PQXX_CHECK_LESS_EQUAL(
      text.size(), 25u, text + " converted to too long a string.");
  }
  if constexpr (sizeof(double) <= 8)
  {
    auto const text{pqxx::to_string(awkward)};
    PQXX_CHECK_LESS_EQUAL(
      pqxx::string_traits<double>::size_buffer(awkward), 25u,
      text + " converted to too long a string.");
  }
}

PQXX_REGISTER_TEST(test_infinities);
PQXX_REGISTER_TEST(test_bug_262);
PQXX_REGISTER_TEST(test_bad_float);
PQXX_REGISTER_TEST(test_long_float);
} // namespace
<|endoftext|>


<commit_before>#include "SkillSystem.h"
#include "BulletSystem.h"
#include "interface.h"
#include "GameProcess.h"
#include "ObjectParticles.h"

CSkillSystem::CSkillSystem(CGameProcess*	pGameProcess)
{
	CBulletSystem::GetInstance()->SetCallback(MakeInterface(this, &CSkillSystem::OnSkillCallback));
	m_pGameProcess = pGameProcess;
	AddListen(BR_PARTICLE_HIT, MakeMessageFunc(this, &CSkillSystem::OnParticleHit));
}

CSkillSystem::~CSkillSystem(void)
{
	CBulletSystem::ReleaseInstance();
}

int CSkillSystem::OnSkillCallback(void* pVoid)
{
	_BulletCallback* pBase = (_BulletCallback*)pVoid;

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "SkillSystem.h"
#include "BulletSystem.h"
#include "interface.h"
#include "GameProcess.h"
#include "ObjectParticles.h"

CSkillSystem::CSkillSystem(CGameProcess*	pGameProcess)
{
	CBulletSystem::GetInstance()->SetCallback(MakeInterface(this, &CSkillSystem::OnSkillCallback));
	m_pGameProcess = pGameProcess;
	AddListen(BR_PARTICLE_HIT, MakeMessageFunc(this, &CSkillSystem::OnParticleHit));
}

CSkillSystem::~CSkillSystem(void)
{
	CBulletSystem::ReleaseInstance();
}

int CSkillSystem::OnSkillCallback(void* pVoid)
{
	_BulletCallback* pBase = (_BulletCallback*)pVoid;
	switch (pBase->nMsgID)
	{
	case _BulletCallback::GetTargetPosition:
	{
		_Bullet_GetTargetPosition* pBullet = (_Bullet_GetTargetPosition*)pBase;
		CRoleBase* pRole = m_pGameProcess->GetRole(pBullet->nTarget);//test
		if (pRole)
		{
			pBullet->nRetState = 1;
			pBullet->vRetPos = pRole->GetPosition() + vec3(0.0f, 0.0f, 1.2f);
			pBullet->vRetDir = pRole->GetDirection();
		}
		else
		{
			pBullet->nRetState = 0;
		}
	}break;
	case _BulletCallback::HitTarget:
	{
		_Bullet_HitTarget* pBullet = (_Bullet_HitTarget*)pBase;

	}break;
	case _BulletCallback::GetCollision:
	{
		_Bullet_GetCollision* pBullet = (_Bullet_GetCollision*)pBase;
		//test
		for (int i = 0; i < 20; i++)
		{
			CRoleBase* pRole = m_pGameProcess->GetRoleFormIndex(i);
			if (pRole)
			{
				if ((pRole->GetPosition() - pBullet->vPos).length() < pBullet->fRadius + pRole->GetRoleRadius())
				{
					pBullet->nRetTarget = pRole->GetRoleID();
					pBullet->vRetHitPoint = pRole->GetPosition() + vec3(0.0f, 0.0f, 1.2f);
				}
			}
		}
	}break;
	case _BulletCallback::Blast:
	{
		_Bullet_Blast* pBullet = (_Bullet_Blast*)pBase;

	}break;
	}

	return 1;
}<|endoftext|>


<commit_before>/**
 * \file
 * \brief SignalInformationQueueWrapper class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-10-24
 */

#ifndef INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
#define INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_

#include "distortos/memory/dummyDeleter.hpp"

#include "distortos/synchronization/SignalInformationQueue.hpp"

#include <array>

namespace distortos
{

namespace synchronization
{

class SignalsReceiverControlBlock;

}	// namespace synchronization

/// SignalInformationQueueWrapper class is a container for synchronization::SignalInformationQueue
class SignalInformationQueueWrapper
{
	friend class synchronization::SignalsReceiverControlBlock;

public:

	/// import Storage type alias from synchronization::SignalInformationQueue
	using Storage = synchronization::SignalInformationQueue::Storage;

	/**
	 * \brief SignalInformationQueueWrapper's constructor
	 *
	 * \param [in] storage is an array of Storage elements
	 * \param [in] maxElements is the number of elements in \a storage array
	 */

	SignalInformationQueueWrapper(Storage* storage, size_t maxElements) :
			signalInformationQueue_{{storage, memory::dummyDeleter}, maxElements}
	{

	}

	/**
	 * \brief SignalInformationQueueWrapper's constructor
	 *
	 * \param N is the number of elements in \a storage array
	 *
	 * \param [in] storage is a reference to array of Storage elements
	 */

	template<size_t N>
	explicit SignalInformationQueueWrapper(Storage (& storage)[N]) :
			SignalInformationQueueWrapper{storage, sizeof(storage) / sizeof(*storage)}
	{

	}

	/**
	 * \brief SignalInformationQueueWrapper's constructor
	 *
	 * \param N is the number of elements in \a storage array
	 *
	 * \param [in] storage is a reference to std::array of Storage elements
	 */

	template<size_t N>
	explicit SignalInformationQueueWrapper(std::array<Storage, N>& storage) :
			SignalInformationQueueWrapper{storage.data(), storage.size()}
	{

	}

private:

	/// contained synchronization::SignalInformationQueue object
	synchronization::SignalInformationQueue signalInformationQueue_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
<commit_msg>SignalInformationQueueWrapper: remove helper constructors<commit_after>/**
 * \file
 * \brief SignalInformationQueueWrapper class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-10-24
 */

#ifndef INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
#define INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_

#include "distortos/memory/dummyDeleter.hpp"

#include "distortos/synchronization/SignalInformationQueue.hpp"

namespace distortos
{

namespace synchronization
{

class SignalsReceiverControlBlock;

}	// namespace synchronization

/// SignalInformationQueueWrapper class is a container for synchronization::SignalInformationQueue
class SignalInformationQueueWrapper
{
	friend class synchronization::SignalsReceiverControlBlock;

public:

	/// import Storage type alias from synchronization::SignalInformationQueue
	using Storage = synchronization::SignalInformationQueue::Storage;

	/**
	 * \brief SignalInformationQueueWrapper's constructor
	 *
	 * \param [in] storage is an array of Storage elements
	 * \param [in] maxElements is the number of elements in \a storage array
	 */

	SignalInformationQueueWrapper(Storage* storage, size_t maxElements) :
			signalInformationQueue_{{storage, memory::dummyDeleter}, maxElements}
	{

	}

private:

	/// contained synchronization::SignalInformationQueue object
	synchronization::SignalInformationQueue signalInformationQueue_;
};

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SIGNALINFORMATIONQUEUEWRAPPER_HPP_
<|endoftext|>


<commit_before>/**
\file
\brief Main header file for dsb::comm.
*/
#ifndef DSB_COMM_HPP
#define DSB_COMM_HPP

#include <deque>
#include <string>
#include "zmq.hpp"

namespace dsb
{

/// Helper functions for communication over ZMQ sockets.
namespace comm
{

/**
\brief Sends a message.

The message content will be cleared on return.

\throws std::invalid_argument if `message` is empty.
*/
void Send(zmq::socket_t& socket, std::deque<zmq::message_t>& message);

/**
\brief  Sends an addressed message.

This function sends a multipart message consisting of the frames in `envelope`
followed by an empty delimiter frame and the frames in `body`.

Both `envelope` and `body` will be cleared on return.

\throws std::invalid_argument if either of `envelope` or `body` are empty.
*/
void AddressedSend(
    zmq::socket_t& socket,
    std::deque<zmq::message_t>& envelope,
    std::deque<zmq::message_t>& body);

/**
\brief Receives a message.

Existing message content will be overwritten.
*/
void Receive(
    zmq::socket_t& socket,
    std::deque<zmq::message_t>& message);

/**
\brief  Removes or moves the envelope from a message.

The envelope of a message are the message frames starting at the beginning
of the message and ending at the first empty frame, called a "delimiter".

If `message` is empty, or has no envelope (i.e., no delimiter), this
function returns without doing anything.  Otherwise, if `envelope` is not
null, all message frames up to, but not including, the delimiter are moved
to `envelope`. Any existing contents of `envelope` will be overwritten.
Finally, all frames up to and including the delimiter are removed from
`message`.

\returns The number of frames removed from `message`, including the delimiter.
*/
size_t PopMessageEnvelope(
    std::deque<zmq::message_t>& message,
    std::deque<zmq::message_t>* envelope = nullptr);

void CopyMessage(
    std::deque<zmq::message_t>& source,
    std::deque<zmq::message_t>& target);

/// Returns the content of a message frame as a `std::string`.
std::string ToString(const zmq::message_t& frame);

}}      // namespace
#endif  // header guard
<commit_msg>Documented some exceptions thrown in dsb::comm<commit_after>/**
\file
\brief Main header file for dsb::comm.
*/
#ifndef DSB_COMM_HPP
#define DSB_COMM_HPP

#include <deque>
#include <string>
#include "zmq.hpp"

namespace dsb
{

/// Helper functions for communication over ZMQ sockets.
namespace comm
{

/**
\brief Sends a message.

The message content will be cleared on return.

\throws std::invalid_argument if `message` is empty.
\throws zmq::error_t on failure to send a message frame.
*/
void Send(zmq::socket_t& socket, std::deque<zmq::message_t>& message);

/**
\brief  Sends an addressed message.

This function sends a multipart message consisting of the frames in `envelope`
followed by an empty delimiter frame and the frames in `body`.

Both `envelope` and `body` will be cleared on return.

\throws std::invalid_argument if either of `envelope` or `body` are empty.
\throws zmq::error_t on failure to send a message frame.
*/
void AddressedSend(
    zmq::socket_t& socket,
    std::deque<zmq::message_t>& envelope,
    std::deque<zmq::message_t>& body);

/**
\brief Receives a message.

Existing message content will be overwritten.

\throws zmq::error_t on failure to receive a message frame.
*/
void Receive(
    zmq::socket_t& socket,
    std::deque<zmq::message_t>& message);

/**
\brief  Removes or moves the envelope from a message.

The envelope of a message are the message frames starting at the beginning
of the message and ending at the first empty frame, called a "delimiter".

If `message` is empty, or has no envelope (i.e., no delimiter), this
function returns without doing anything.  Otherwise, if `envelope` is not
null, all message frames up to, but not including, the delimiter are moved
to `envelope`. Any existing contents of `envelope` will be overwritten.
Finally, all frames up to and including the delimiter are removed from
`message`.

\returns The number of frames removed from `message`, including the delimiter.
*/
size_t PopMessageEnvelope(
    std::deque<zmq::message_t>& message,
    std::deque<zmq::message_t>* envelope = nullptr);

void CopyMessage(
    std::deque<zmq::message_t>& source,
    std::deque<zmq::message_t>& target);

/// Returns the content of a message frame as a `std::string`.
std::string ToString(const zmq::message_t& frame);

}}      // namespace
#endif  // header guard
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/math/vector.h>

namespace MATH_NAMESPACE
{

//--------------------------------------------------------------------------------------------------
// matrix4 members
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(
        simd::float4 const& c0,
        simd::float4 const& c1,
        simd::float4 const& c2,
        simd::float4 const& c3
        )
    : col0(c0)
    , col1(c1)
    , col2(c2)
    , col3(c3)
{
}

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(float const data[16])
    : col0(&data[ 0])
    , col1(&data[ 4])
    , col2(&data[ 8])
    , col3(&data[12])
{
}

template <typename U>
VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(matrix<4, 4, U> const& rhs)
    : col0( simd::float4(rhs.col0.x, rhs.col0.y, rhs.col0.z, rhs.col0.w) )
    , col1( simd::float4(rhs.col1.x, rhs.col1.y, rhs.col1.z, rhs.col1.w) )
    , col2( simd::float4(rhs.col2.x, rhs.col2.y, rhs.col2.z, rhs.col2.w) )
    , col3( simd::float4(rhs.col3.x, rhs.col3.y, rhs.col3.z, rhs.col3.w) )
{
}

template <typename U>
VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>& matrix<4, 4, simd::float4>::operator=(matrix<4, 4, U> const& rhs)
{
    col0 = simd::float4(rhs.col0.x, rhs.col0.y, rhs.col0.z, rhs.col0.w);
    col1 = simd::float4(rhs.col1.x, rhs.col1.y, rhs.col1.z, rhs.col1.w);
    col2 = simd::float4(rhs.col2.x, rhs.col2.y, rhs.col2.z, rhs.col2.w);
    col3 = simd::float4(rhs.col3.x, rhs.col3.y, rhs.col3.z, rhs.col3.w);
    return *this;
}

VSNRAY_FORCE_INLINE simd::float4& matrix<4, 4, simd::float4>::operator()(size_t col)
{
    return *(reinterpret_cast<simd::float4*>(this) + col);
}

VSNRAY_FORCE_INLINE simd::float4 const& matrix<4, 4, simd::float4>::operator()(size_t col) const
{
    return *(reinterpret_cast<simd::float4 const*>(this) + col);
}

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> matrix<4, 4, simd::float4>::identity()
{
    return matrix<4, 4, simd::float4>(
            simd::float4(1.0f, 0.0f, 0.0f, 0.0f),
            simd::float4(0.0f, 1.0f, 0.0f, 0.0f),
            simd::float4(0.0f, 0.0f, 1.0f, 0.0f),
            simd::float4(0.0f, 0.0f, 0.0f, 1.0f)
            );
}

//--------------------------------------------------------------------------------------------------
// Basic arithmetic
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> operator*(
        matrix<4, 4, simd::float4> const& a,
        matrix<4, 4, simd::float4> const& b
        )
{

    using simd::shuffle;

    matrix<4, 4, simd::float4> result;

    for (size_t i = 0; i < 4; ++i)
    {
        result(i) = a(0) * shuffle<0, 0, 0, 0>( b(i) )
                  + a(1) * shuffle<1, 1, 1, 1>( b(i) )
                  + a(2) * shuffle<2, 2, 2, 2>( b(i) )
                  + a(3) * shuffle<3, 3, 3, 3>( b(i) );
    }

    return result;

}

VSNRAY_FORCE_INLINE vector<4, simd::float4> operator*(
        matrix<4, 4, simd::float4> const& m,
        vector<4, simd::float4> const& v
        )
{

    matrix<4, 4, simd::float4> tmp(v.x, v.y, v.z, v.w);
    matrix<4, 4, simd::float4> res = tmp * transpose(m);
    return vector<4, simd::float4>( res.col0, res.col1, res.col2, res.col3 );

}

//-------------------------------------------------------------------------------------------------
// Geometric functions
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> transpose(matrix<4, 4, simd::float4> const& m)
{

    using simd::float4;

    float4 tmp0 = _mm_unpacklo_ps( m(0), m(1) );
    float4 tmp1 = _mm_unpacklo_ps( m(2), m(3) );
    float4 tmp2 = _mm_unpackhi_ps( m(0), m(1) );
    float4 tmp3 = _mm_unpackhi_ps( m(2), m(3) );

    return matrix<4, 4, simd::float4>(
            _mm_movelh_ps(tmp0, tmp1),
            _mm_movehl_ps(tmp1, tmp0),
            _mm_movelh_ps(tmp2, tmp3),
            _mm_movehl_ps(tmp3, tmp2)
            );

}

} // MATH_NAMESPACE
<commit_msg>Unnecessary conversion<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <visionaray/math/vector.h>

namespace MATH_NAMESPACE
{

//--------------------------------------------------------------------------------------------------
// matrix4 members
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(
        simd::float4 const& c0,
        simd::float4 const& c1,
        simd::float4 const& c2,
        simd::float4 const& c3
        )
    : col0(c0)
    , col1(c1)
    , col2(c2)
    , col3(c3)
{
}

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(float const data[16])
    : col0(&data[ 0])
    , col1(&data[ 4])
    , col2(&data[ 8])
    , col3(&data[12])
{
}

template <typename U>
VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>::matrix(matrix<4, 4, U> const& rhs)
    : col0( simd::float4(rhs.col0.x, rhs.col0.y, rhs.col0.z, rhs.col0.w) )
    , col1( simd::float4(rhs.col1.x, rhs.col1.y, rhs.col1.z, rhs.col1.w) )
    , col2( simd::float4(rhs.col2.x, rhs.col2.y, rhs.col2.z, rhs.col2.w) )
    , col3( simd::float4(rhs.col3.x, rhs.col3.y, rhs.col3.z, rhs.col3.w) )
{
}

template <typename U>
VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4>& matrix<4, 4, simd::float4>::operator=(matrix<4, 4, U> const& rhs)
{
    col0 = simd::float4(rhs.col0.x, rhs.col0.y, rhs.col0.z, rhs.col0.w);
    col1 = simd::float4(rhs.col1.x, rhs.col1.y, rhs.col1.z, rhs.col1.w);
    col2 = simd::float4(rhs.col2.x, rhs.col2.y, rhs.col2.z, rhs.col2.w);
    col3 = simd::float4(rhs.col3.x, rhs.col3.y, rhs.col3.z, rhs.col3.w);
    return *this;
}

VSNRAY_FORCE_INLINE simd::float4& matrix<4, 4, simd::float4>::operator()(size_t col)
{
    return *(reinterpret_cast<simd::float4*>(this) + col);
}

VSNRAY_FORCE_INLINE simd::float4 const& matrix<4, 4, simd::float4>::operator()(size_t col) const
{
    return *(reinterpret_cast<simd::float4 const*>(this) + col);
}

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> matrix<4, 4, simd::float4>::identity()
{
    return matrix<4, 4, simd::float4>(
            simd::float4(1.0f, 0.0f, 0.0f, 0.0f),
            simd::float4(0.0f, 1.0f, 0.0f, 0.0f),
            simd::float4(0.0f, 0.0f, 1.0f, 0.0f),
            simd::float4(0.0f, 0.0f, 0.0f, 1.0f)
            );
}

//--------------------------------------------------------------------------------------------------
// Basic arithmetic
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> operator*(
        matrix<4, 4, simd::float4> const& a,
        matrix<4, 4, simd::float4> const& b
        )
{

    using simd::shuffle;

    matrix<4, 4, simd::float4> result;

    for (size_t i = 0; i < 4; ++i)
    {
        result(i) = a(0) * shuffle<0, 0, 0, 0>( b(i) )
                  + a(1) * shuffle<1, 1, 1, 1>( b(i) )
                  + a(2) * shuffle<2, 2, 2, 2>( b(i) )
                  + a(3) * shuffle<3, 3, 3, 3>( b(i) );
    }

    return result;

}

VSNRAY_FORCE_INLINE vector<4, simd::float4> operator*(
        matrix<4, 4, simd::float4> const& m,
        vector<4, simd::float4> const& v
        )
{

    matrix<4, 4, simd::float4> tmp(v.x, v.y, v.z, v.w);
    matrix<4, 4, simd::float4> res = tmp * transpose(m);
    return vector<4, simd::float4>( res.col0, res.col1, res.col2, res.col3 );

}

//-------------------------------------------------------------------------------------------------
// Geometric functions
//

VSNRAY_FORCE_INLINE matrix<4, 4, simd::float4> transpose(matrix<4, 4, simd::float4> const& m)
{
    __m128 tmp0 = _mm_unpacklo_ps( m(0), m(1) );
    __m128 tmp1 = _mm_unpacklo_ps( m(2), m(3) );
    __m128 tmp2 = _mm_unpackhi_ps( m(0), m(1) );
    __m128 tmp3 = _mm_unpackhi_ps( m(2), m(3) );

    return matrix<4, 4, simd::float4>(
            _mm_movelh_ps(tmp0, tmp1),
            _mm_movehl_ps(tmp1, tmp0),
            _mm_movelh_ps(tmp2, tmp3),
            _mm_movehl_ps(tmp3, tmp2)
            );

}

} // MATH_NAMESPACE
<|endoftext|>


<commit_before><commit_msg>Fix crasher in framegraph<commit_after><|endoftext|>


<commit_before>#include "data/Format.h"
#include "hardware/parsing/Samples.h"
#include "exception/Base.h"

namespace blitzortung {
  namespace hardware {
    namespace parsing {

      Samples::Samples(const std::vector<std::string>& fields, const hardware::gps::Base& gps) :
	Base(),
	logger_("hardware.parsing.Samples")
      {
	valid_ = false;

	if (gps.isValid()) {
	  // the counter value is always at the second position
	  counter_ = parseHex(fields[1]);

	  pt::ptime eventtime = gps.getTime(counter_);

	  if (eventtime != pt::not_a_date_time) {

	    if (fields[0] == "BLSIG") {
	      if (fields.size() > 3) {
		if (fields[2].size() == 2 && fields[3].size() ==2) {
		  // BLSIG type 1
		  setWaveform(FORMAT_8_2_1, eventtime, pt::nanoseconds(0), fields[2] + fields[3]);
		} else if (fields[2].size() == 3 && fields[3].size() ==3) {
		  // BLSIG type 2
		  setWaveform(FORMAT_12_2_1, eventtime, pt::nanoseconds(0), std::move(fields[2] + fields[3]), 12);
		} else {
		  logger_.warnStream() << "Samples() BLSIG field size mismatch 2: '" << fields[2] << "', 3: '" << fields[3] << "'";
		}
	      } else {
		logger_.warnStream() << "Samples() BLSIG total number of fields mismatch: " << fields.size();
	      }
	    } else if (fields[0] == "BLSEQ") {
	      if (fields[2].size() == 256) {
		// BLSIG type 2
		setWaveform(FORMAT_8_2_64, eventtime, pt::nanoseconds(2900), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BLSEQ field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "BD") {
	      if (fields[2].size() == 256) {
		// BD type
		setWaveform(FORMAT_8_2_64, eventtime, pt::nanoseconds(2800), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BD field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "BM") {
	      if (fields[2].size() == 256) {
		// BM type
		setWaveform(FORMAT_8_1_128, eventtime, pt::nanoseconds(2800), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BM field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "L") {
	      if (fields[2].size() == 1024) {
		// L type
		setWaveform(FORMAT_8_2_256, eventtime, pt::nanoseconds(1950), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BD field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else {
	      logger_.warnStream() << "Samples() unknown sample type '" << fields[0] << "'";
	    }
	  } else {
	    logger_.warnStream() << "Samples() invalid event time";
	  }

	  if (! valid_) {
	    waveform_.reset();

	    std::string line;
	    for (std::vector<std::string>::const_iterator field = fields.begin(); field != fields.end(); field++)
	      line += *field + " ";

	    logger_.warnStream() << "Samples() could not parse '" << line << "'";
	  }
	}
      }

      void Samples::setWaveform(const data::Format& format, const pt::ptime& eventtime, const pt::time_duration&& sampleDt, const std::string&& rawData, unsigned char numberOfBitsPerSample) {
	if (numberOfBitsPerSample == 0) {
	  numberOfBitsPerSample = format.getNumberOfBytesPerSample() * 8;
	}

	std::ostringstream oss;
	oss << (int)format.getNumberOfChannels() << " " << format.getNumberOfSamples() << " "  << (int)numberOfBitsPerSample <<  " " << rawData;
	rawData_ = oss.str();

	// parse lighning event information
	if (format.isValid()) {
	  int numberOfEvents = rawData.size() >> 2;

	  waveform_ = format.createWaveform(eventtime, sampleDt);

	  unsigned short hexCharsPerSample = (numberOfBitsPerSample + 3 ) / 4;
	  unsigned short numberOfChannels = format.getNumberOfChannels();

	  int offset =  -(1 << (numberOfBitsPerSample - 1));

	  if (logger_.isDebugEnabled())
	    logger_.debugStream() << "#ch " << numberOfChannels << ", #chars/sample " << hexCharsPerSample << " zeroOffset " << offset;

	  int index = 0;
	  for (int sample=0; sample < numberOfEvents; sample++) {
	    for (int channel=0; channel < numberOfChannels; channel++) {
	      std::string hexString = rawData_.substr(index, hexCharsPerSample);
	      waveform_->setInt(int(offset + parseHex(hexString)), sample, channel);
	      index += hexCharsPerSample;
	    }
	  }

	  valid_ = true;
	} else {
	  logger_.warnStream() << "invalid format " << format;
	}
      }

      data::Waveform::AP Samples::getWaveform() {
	return std::move(waveform_);
      }

      const std::string& Samples::getRawData() const {
	return rawData_;
      }

      const data::Format Samples::FORMAT_8_2_1(1,2,1);
      const data::Format Samples::FORMAT_12_2_1(2,2,1);
      const data::Format Samples::FORMAT_8_2_64(1,2,64);
      const data::Format Samples::FORMAT_8_1_128(1,1,128);
      const data::Format Samples::FORMAT_8_2_256(1,2,256);
    }
  }
}
<commit_msg>fixed faulty sample buildup<commit_after>#include "data/Format.h"
#include "hardware/parsing/Samples.h"
#include "exception/Base.h"

namespace blitzortung {
  namespace hardware {
    namespace parsing {

      Samples::Samples(const std::vector<std::string>& fields, const hardware::gps::Base& gps) :
	Base(),
	logger_("hardware.parsing.Samples")
      {
	valid_ = false;

	if (gps.isValid()) {
	  // the counter value is always at the second position
	  counter_ = parseHex(fields[1]);

	  pt::ptime eventtime = gps.getTime(counter_);

	  if (eventtime != pt::not_a_date_time) {

	    if (fields[0] == "BLSIG") {
	      if (fields.size() > 3) {
		if (fields[2].size() == 2 && fields[3].size() ==2) {
		  // BLSIG type 1
		  setWaveform(FORMAT_8_2_1, eventtime, pt::nanoseconds(0), fields[2] + fields[3]);
		} else if (fields[2].size() == 3 && fields[3].size() ==3) {
		  // BLSIG type 2
		  setWaveform(FORMAT_12_2_1, eventtime, pt::nanoseconds(0), std::move(fields[2] + fields[3]), 12);
		} else {
		  logger_.warnStream() << "Samples() BLSIG field size mismatch 2: '" << fields[2] << "', 3: '" << fields[3] << "'";
		}
	      } else {
		logger_.warnStream() << "Samples() BLSIG total number of fields mismatch: " << fields.size();
	      }
	    } else if (fields[0] == "BLSEQ") {
	      if (fields[2].size() == 256) {
		// BLSIG type 2
		setWaveform(FORMAT_8_2_64, eventtime, pt::nanoseconds(2900), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BLSEQ field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "BD") {
	      if (fields[2].size() == 256) {
		// BD type
		setWaveform(FORMAT_8_2_64, eventtime, pt::nanoseconds(2800), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BD field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "BM") {
	      if (fields[2].size() == 256) {
		// BM type
		setWaveform(FORMAT_8_1_128, eventtime, pt::nanoseconds(2800), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BM field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else if (fields[0] == "L") {
	      if (fields[2].size() == 1024) {
		// L type
		setWaveform(FORMAT_8_2_256, eventtime, pt::nanoseconds(1950), std::move(fields[2]));
	      } else {
		logger_.warnStream() << "Samples() BD field 2 size mismatch: " << fields[2].size() << " vs. 256";
	      }
	    } else {
	      logger_.warnStream() << "Samples() unknown sample type '" << fields[0] << "'";
	    }
	  } else {
	    logger_.warnStream() << "Samples() invalid event time";
	  }

	  if (! valid_) {
	    waveform_.reset();

	    std::string line;
	    for (std::vector<std::string>::const_iterator field = fields.begin(); field != fields.end(); field++)
	      line += *field + " ";

	    logger_.warnStream() << "Samples() could not parse '" << line << "'";
	  }
	}
      }

      void Samples::setWaveform(const data::Format& format, const pt::ptime& eventtime, const pt::time_duration&& sampleDt, const std::string&& rawData, unsigned char numberOfBitsPerSample) {
	if (numberOfBitsPerSample == 0) {
	  numberOfBitsPerSample = format.getNumberOfBytesPerSample() * 8;
	}

	std::ostringstream oss;
	oss << (int)format.getNumberOfChannels() << " " << format.getNumberOfSamples() << " "  << (int)numberOfBitsPerSample <<  " " << rawData;
	rawData_ = oss.str();

	// parse lighning event information
	if (format.isValid()) {
	  int numberOfEvents = rawData.size() >> 2;

	  waveform_ = format.createWaveform(eventtime, sampleDt);

	  unsigned short hexCharsPerSample = (numberOfBitsPerSample + 3 ) / 4;
	  unsigned short numberOfChannels = format.getNumberOfChannels();

	  int offset =  -(1 << (numberOfBitsPerSample - 1));

	  if (logger_.isDebugEnabled())
	    logger_.debugStream() << "#ch " << numberOfChannels << ", #chars/sample " << hexCharsPerSample << " zeroOffset " << offset;

	  int index = 0;
	  for (int sample=0; sample < numberOfEvents; sample++) {
	    for (int channel=0; channel < numberOfChannels; channel++) {
	      std::string hexString = rawData.substr(index, hexCharsPerSample);
	      waveform_->setInt(int(offset + parseHex(hexString)), sample, channel);
	      index += hexCharsPerSample;
	    }
	  }

	  valid_ = true;
	} else {
	  logger_.warnStream() << "invalid format " << format;
	}
      }

      data::Waveform::AP Samples::getWaveform() {
	return std::move(waveform_);
      }

      const std::string& Samples::getRawData() const {
	return rawData_;
      }

      const data::Format Samples::FORMAT_8_2_1(1,2,1);
      const data::Format Samples::FORMAT_12_2_1(2,2,1);
      const data::Format Samples::FORMAT_8_2_64(1,2,64);
      const data::Format Samples::FORMAT_8_1_128(1,1,128);
      const data::Format Samples::FORMAT_8_2_256(1,2,256);
    }
  }
}
<|endoftext|>