<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_xbus_dccal.H
/// @brief Run Dccal on the link.
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 2
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------

#ifndef _P9_IO_XBUS_DCCAL_H
#define _P9_IO_XBUS_DCCAL_H

//-----------------------------------------------------------------------------
//  fapi2 Includes
//-----------------------------------------------------------------------------
#include <fapi2.H>

typedef fapi2::ReturnCode (*p9_io_xbus_dccal_FP_t)
( const fapi2::Target < fapi2::TARGET_TYPE_XBUS>&,
  const uint8_t& );

extern "C"
{

    /**
     * @brief A I/O EDI+ Procedure that runs Rx Dccal and Tx Z Impedance calibration
     * on every instance of the EDI+ XBUS.
     * @param[in] i_target FAPI2 Target
     * @retval ReturnCode
     */
    fapi2::ReturnCode
    p9_io_xbus_dccal(
        const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target,
        const uint8_t&                                   i_group );

} // extern "C"

#endif // _P9_IO_XBUS_DCCAL_H
<commit_msg>io xbus dccal l3<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_xbus_dccal.H $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_xbus_dccal.H
/// @brief Run Dccal on the link.
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 3
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------

#ifndef _P9_IO_XBUS_DCCAL_H
#define _P9_IO_XBUS_DCCAL_H

//-----------------------------------------------------------------------------
//  fapi2 Includes
//-----------------------------------------------------------------------------
#include <fapi2.H>

typedef fapi2::ReturnCode (*p9_io_xbus_dccal_FP_t)
( const fapi2::Target < fapi2::TARGET_TYPE_XBUS>&, const uint8_t& );

extern "C"
{

    /**
     * @brief A I/O EDI+ Procedure that runs Rx Dccal and Tx Z Impedance calibration
     * on every group of the EDI+ XBUS.
     * @param[in] i_target FAPI2 Target
     * @retval ReturnCode
     */
    fapi2::ReturnCode p9_io_xbus_dccal(
        const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target,
        const uint8_t&                                   i_group );

} // extern "C"

#endif // _P9_IO_XBUS_DCCAL_H
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <limits>
#include <type_traits>
#include <seastar/core/future.hh>
#include "gc_clock.hh"
#include "timestamp.hh"
#include "sstables/types.hh"
#include "sstables/exceptions.hh"
#include "clustering_bounds_comparator.hh"
#include "sstables/mx/types.hh"

namespace sstables {

class random_access_reader;

// Utilities for reading integral values in variable-length format
// See vint-serialization.hh for more details
future<uint64_t> read_unsigned_vint(random_access_reader& in);
future<int64_t> read_signed_vint(random_access_reader& in);

template <typename T>
typename std::enable_if_t<!std::is_integral_v<T>>
read_vint(random_access_reader& in, T& t) = delete;

template <typename T>
inline future<> read_vint(random_access_reader& in, T& value) {
    static_assert(std::is_integral_v<T>, "Non-integral values can't be read using read_vint");
    if constexpr(std::is_unsigned_v<T>) {
        return read_unsigned_vint(in).then([&value] (uint64_t res) {
            value = res;
        });
    } else {
        return read_signed_vint(in).then([&value] (int64_t res) {
            value = res;
        });
    }
}

inline api::timestamp_type parse_timestamp(const serialization_header& header,
                                           uint64_t delta) {
    return static_cast<api::timestamp_type>(header.get_min_timestamp() + delta);
}

inline gc_clock::duration parse_ttl(int64_t value) {
    if (!is_expired_liveness_ttl(value)) {
        if (value < 0) {
            throw malformed_sstable_exception(format("Negative ttl: {}", value));
        }
        if (value > max_ttl.count()) {
            throw malformed_sstable_exception(format("Too big ttl: {}", value));
        }
    }
    return gc_clock::duration(value);
}

inline gc_clock::duration parse_ttl(const serialization_header& header,
                                    uint64_t delta) {
    // sign-extend min_ttl back to 64 bits and
    // add the delta using unsigned arithmetic
    // to prevent signed integer overflow
    uint64_t min_ttl = static_cast<uint64_t>(header.get_min_ttl());
    return parse_ttl(static_cast<int64_t>(min_ttl + delta));
}

inline gc_clock::time_point parse_expiry(int64_t value) {
    return gc_clock::time_point(gc_clock::duration(value));
}

inline gc_clock::time_point parse_expiry(const serialization_header& header,
                                   uint64_t delta) {
    // sign-extend min_local_deletion_time back to 64 bits and
    // add the delta using unsigned arithmetic
    // to prevent signed integer overflow
    uint64_t min_local_deletion_time = static_cast<uint64_t>(header.get_min_local_deletion_time());
    return parse_expiry(static_cast<int64_t>(min_local_deletion_time + delta));
}

};   // namespace sstables
<commit_msg>sstables: read_vint(): convert enable_if to concepts<commit_after>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <limits>
#include <type_traits>
#include <concepts>
#include <seastar/core/future.hh>
#include "gc_clock.hh"
#include "timestamp.hh"
#include "sstables/types.hh"
#include "sstables/exceptions.hh"
#include "clustering_bounds_comparator.hh"
#include "sstables/mx/types.hh"

namespace sstables {

class random_access_reader;

// Utilities for reading integral values in variable-length format
// See vint-serialization.hh for more details
future<uint64_t> read_unsigned_vint(random_access_reader& in);
future<int64_t> read_signed_vint(random_access_reader& in);

template <std::integral T>
inline future<> read_vint(random_access_reader& in, T& value) {
    if constexpr(std::is_unsigned_v<T>) {
        return read_unsigned_vint(in).then([&value] (uint64_t res) {
            value = res;
        });
    } else {
        return read_signed_vint(in).then([&value] (int64_t res) {
            value = res;
        });
    }
}

inline api::timestamp_type parse_timestamp(const serialization_header& header,
                                           uint64_t delta) {
    return static_cast<api::timestamp_type>(header.get_min_timestamp() + delta);
}

inline gc_clock::duration parse_ttl(int64_t value) {
    if (!is_expired_liveness_ttl(value)) {
        if (value < 0) {
            throw malformed_sstable_exception(format("Negative ttl: {}", value));
        }
        if (value > max_ttl.count()) {
            throw malformed_sstable_exception(format("Too big ttl: {}", value));
        }
    }
    return gc_clock::duration(value);
}

inline gc_clock::duration parse_ttl(const serialization_header& header,
                                    uint64_t delta) {
    // sign-extend min_ttl back to 64 bits and
    // add the delta using unsigned arithmetic
    // to prevent signed integer overflow
    uint64_t min_ttl = static_cast<uint64_t>(header.get_min_ttl());
    return parse_ttl(static_cast<int64_t>(min_ttl + delta));
}

inline gc_clock::time_point parse_expiry(int64_t value) {
    return gc_clock::time_point(gc_clock::duration(value));
}

inline gc_clock::time_point parse_expiry(const serialization_header& header,
                                   uint64_t delta) {
    // sign-extend min_local_deletion_time back to 64 bits and
    // add the delta using unsigned arithmetic
    // to prevent signed integer overflow
    uint64_t min_local_deletion_time = static_cast<uint64_t>(header.get_min_local_deletion_time());
    return parse_expiry(static_cast<int64_t>(min_local_deletion_time + delta));
}

};   // namespace sstables
<|endoftext|>


<commit_before>#include "config.h"
#include <gtest/gtest.h>

#include <ros_type_introspection/deserializer.hpp>
#include <sensor_msgs/JointState.h>
#include <sensor_msgs/NavSatStatus.h>
#include <sensor_msgs/Imu.h>
#include <std_msgs/Int16MultiArray.h>

using namespace ros::message_traits;
using namespace RosIntrospection;

TEST(Deserialize, JointState)

{
  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::JointState >::value(),
        Definition<sensor_msgs::JointState >::value() );

  sensor_msgs::JointState joint_state;

  joint_state.header.seq = 2016;
  joint_state.header.stamp.sec  = 1234;
  joint_state.header.stamp.nsec = 567*1000*1000;
  joint_state.header.frame_id = "pippo";

  joint_state.name.resize( 3 );
  joint_state.position.resize( 3 );
  joint_state.velocity.resize( 3 );
  joint_state.effort.resize( 3 );

  std::string names[3];
  names[0] = ("hola");
  names[1] = ("ciao");
  names[2] = ("bye");

  for (int i=0; i<3; i++)
  {
    joint_state.name[i] = names[i];
    joint_state.position[i]= 11+i;
    joint_state.velocity[i]= 21+i;
    joint_state.effort[i]= 31+i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::JointState>::write(stream, joint_state);

  ROSType main_type( DataType<sensor_msgs::JointState >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "JointState",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){
    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }

    for(auto&it: flat_container.name) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  EXPECT_EQ( flat_container.value[0].first.toStr() , ("JointState/header/seq"));
  EXPECT_EQ( flat_container.value[0].second, 2016 );
  EXPECT_EQ( flat_container.value[1].first.toStr() , ("JointState/header/stamp"));
  EXPECT_EQ( flat_container.value[1].second, 1234.567 );

  EXPECT_EQ( flat_container.value[2].first.toStr() , ("JointState/position.0"));
  EXPECT_EQ( flat_container.value[2].second, 11 );
  EXPECT_EQ( flat_container.value[3].first.toStr() , ("JointState/position.1"));
  EXPECT_EQ( flat_container.value[3].second, 12 );
  EXPECT_EQ( flat_container.value[4].first.toStr() , ("JointState/position.2"));
  EXPECT_EQ( flat_container.value[4].second, 13 );

  EXPECT_EQ( flat_container.value[5].first.toStr() , ("JointState/velocity.0"));
  EXPECT_EQ( flat_container.value[5].second, 21 );
  EXPECT_EQ( flat_container.value[6].first.toStr() , ("JointState/velocity.1"));
  EXPECT_EQ( flat_container.value[6].second, 22 );
  EXPECT_EQ( flat_container.value[7].first.toStr() , ("JointState/velocity.2"));
  EXPECT_EQ( flat_container.value[7].second, 23 );

  EXPECT_EQ( flat_container.value[8].first.toStr() , ("JointState/effort.0"));
  EXPECT_EQ( flat_container.value[8].second, 31 );
  EXPECT_EQ( flat_container.value[9].first.toStr() , ("JointState/effort.1"));
  EXPECT_EQ( flat_container.value[9].second, 32 );
  EXPECT_EQ( flat_container.value[10].first.toStr() , ("JointState/effort.2"));
  EXPECT_EQ( flat_container.value[10].second, 33 );

  EXPECT_EQ( flat_container.name[0].first.toStr() , ("JointState/header/frame_id"));
  EXPECT_EQ( flat_container.name[0].second, ("pippo") );

  EXPECT_EQ( flat_container.name[1].first.toStr() , ("JointState/name.0"));
  EXPECT_EQ( flat_container.name[1].second, ("hola") );
  EXPECT_EQ( flat_container.name[2].first.toStr() , ("JointState/name.1"));
  EXPECT_EQ( flat_container.name[2].second, ("ciao") );
  EXPECT_EQ( flat_container.name[3].first.toStr() , ("JointState/name.2"));
  EXPECT_EQ( flat_container.name[3].second, ("bye") );
}

TEST( Deserialize, NavSatStatus)

{
  // We test this because we want to test that constant fields are skipped.

  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::NavSatStatus >::value(),
        Definition<sensor_msgs::NavSatStatus >::value() );

  sensor_msgs::NavSatStatus nav_stat;
  nav_stat.status  = nav_stat.STATUS_GBAS_FIX;  // 2
  nav_stat.service = nav_stat.SERVICE_COMPASS; // 4

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::NavSatStatus>::write(stream, nav_stat);

  ROSType main_type( DataType<sensor_msgs::NavSatStatus >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "nav_stat",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){ std::cout << " -------------------- " << std::endl;

    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  EXPECT_EQ( flat_container.value[0].first.toStr() , ("nav_stat.status"));
  EXPECT_EQ( flat_container.value[0].second, nav_stat.STATUS_GBAS_FIX );
  EXPECT_EQ( flat_container.value[1].first.toStr() , ("nav_stat.service"));
  EXPECT_EQ( flat_container.value[1].second, nav_stat.SERVICE_COMPASS );
}

TEST( Deserialize, DeserializeIMU)
//int func()
{
  // We test this because to check if arrays with fixed length work.

  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::Imu >::value(),
        Definition<sensor_msgs::Imu >::value() );

  sensor_msgs::Imu imu;

  imu.header.seq = 2016;
  imu.header.stamp.sec  = 1234;
  imu.header.stamp.nsec = 567*1000*1000;
  imu.header.frame_id = "pippo";

  imu.orientation.x = 11;
  imu.orientation.y = 12;
  imu.orientation.z = 13;
  imu.orientation.w = 14;

  imu.angular_velocity.x = 21;
  imu.angular_velocity.y = 22;
  imu.angular_velocity.z = 23;

  imu.linear_acceleration.x = 31;
  imu.linear_acceleration.y = 32;
  imu.linear_acceleration.z = 33;

  for (int i=0; i<9; i++)
  {
    imu.orientation_covariance[i]         = 40+i;
    imu.angular_velocity_covariance[i]    = 50+i;
    imu.linear_acceleration_covariance[i] = 60+i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::Imu>::write(stream, imu);

  ROSType main_type( DataType<sensor_msgs::Imu >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "imu",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){

    std::cout << " -------------------- " << std::endl;
    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  int index = 0;

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/header/seq"));
  EXPECT_EQ( flat_container.value[index].second, 2016 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/header/stamp"));
  EXPECT_EQ( flat_container.value[index].second, 1234.567 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/x"));
  EXPECT_EQ( flat_container.value[index].second, 11 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/y"));
  EXPECT_EQ( flat_container.value[index].second, 12 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/z"));
  EXPECT_EQ( flat_container.value[index].second, 13 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/w"));
  EXPECT_EQ( flat_container.value[index].second, 14 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/orientation_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 40+i );
    index++;
  }

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/x"));
  EXPECT_EQ( flat_container.value[index].second, 21 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/y"));
  EXPECT_EQ( flat_container.value[index].second, 22 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/z"));
  EXPECT_EQ( flat_container.value[index].second, 23 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/angular_velocity_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 50+i );
    index++;
  }

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/x"));
  EXPECT_EQ( flat_container.value[index].second, 31 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/y"));
  EXPECT_EQ( flat_container.value[index].second, 32 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/z"));
  EXPECT_EQ( flat_container.value[index].second, 33 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/linear_acceleration_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 60+i );
    index++;
  }
}

TEST( Deserialize, Int16MultiArrayDeserialize)
//int func()
{
  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<std_msgs::Int16MultiArray >::value(),
        Definition<std_msgs::Int16MultiArray >::value() );

  std_msgs::Int16MultiArray multi_array;

  const unsigned N = 6;
  multi_array.layout.data_offset = 42;
  multi_array.data.resize(N);

  for (unsigned i=0; i<N; i++){
    multi_array.data[i] = i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<std_msgs::Int16MultiArray>::write(stream, multi_array);

  ROSType main_type( DataType<std_msgs::Int16MultiArray>::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "multi_array",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){
    std::cout << " -------------------- " << std::endl;

    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

}

<commit_msg>fix tests?<commit_after>#include "config.h"
#include <gtest/gtest.h>

#include <ros_type_introspection/deserializer.hpp>
#include <sensor_msgs/JointState.h>
#include <sensor_msgs/NavSatStatus.h>
#include <sensor_msgs/Imu.h>
#include <std_msgs/Int16MultiArray.h>

using namespace ros::message_traits;
using namespace RosIntrospection;

TEST(Deserialize, JointState)

{
  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::JointState >::value(),
        Definition<sensor_msgs::JointState >::value() );

  sensor_msgs::JointState joint_state;

  joint_state.header.seq = 2016;
  joint_state.header.stamp.sec  = 1234;
  joint_state.header.stamp.nsec = 567*1000*1000;
  joint_state.header.frame_id = "pippo";

  joint_state.name.resize( 3 );
  joint_state.position.resize( 3 );
  joint_state.velocity.resize( 3 );
  joint_state.effort.resize( 3 );

  std::string names[3];
  names[0] = ("hola");
  names[1] = ("ciao");
  names[2] = ("bye");

  for (int i=0; i<3; i++)
  {
    joint_state.name[i] = names[i];
    joint_state.position[i]= 11+i;
    joint_state.velocity[i]= 21+i;
    joint_state.effort[i]= 31+i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::JointState>::write(stream, joint_state);

  ROSType main_type( DataType<sensor_msgs::JointState >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "JointState",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){
    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }

    for(auto&it: flat_container.name) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  EXPECT_EQ( flat_container.value[0].first.toStr() , ("JointState/header/seq"));
  EXPECT_EQ( flat_container.value[0].second, 2016 );
  EXPECT_EQ( flat_container.value[1].first.toStr() , ("JointState/header/stamp"));
  EXPECT_EQ( flat_container.value[1].second, 1234.567 );

  EXPECT_EQ( flat_container.value[2].first.toStr() , ("JointState/position.0"));
  EXPECT_EQ( flat_container.value[2].second, 11 );
  EXPECT_EQ( flat_container.value[3].first.toStr() , ("JointState/position.1"));
  EXPECT_EQ( flat_container.value[3].second, 12 );
  EXPECT_EQ( flat_container.value[4].first.toStr() , ("JointState/position.2"));
  EXPECT_EQ( flat_container.value[4].second, 13 );

  EXPECT_EQ( flat_container.value[5].first.toStr() , ("JointState/velocity.0"));
  EXPECT_EQ( flat_container.value[5].second, 21 );
  EXPECT_EQ( flat_container.value[6].first.toStr() , ("JointState/velocity.1"));
  EXPECT_EQ( flat_container.value[6].second, 22 );
  EXPECT_EQ( flat_container.value[7].first.toStr() , ("JointState/velocity.2"));
  EXPECT_EQ( flat_container.value[7].second, 23 );

  EXPECT_EQ( flat_container.value[8].first.toStr() , ("JointState/effort.0"));
  EXPECT_EQ( flat_container.value[8].second, 31 );
  EXPECT_EQ( flat_container.value[9].first.toStr() , ("JointState/effort.1"));
  EXPECT_EQ( flat_container.value[9].second, 32 );
  EXPECT_EQ( flat_container.value[10].first.toStr() , ("JointState/effort.2"));
  EXPECT_EQ( flat_container.value[10].second, 33 );

  EXPECT_EQ( flat_container.name[0].first.toStr() , ("JointState/header/frame_id"));
  EXPECT_EQ( flat_container.name[0].second, ("pippo") );

  EXPECT_EQ( flat_container.name[1].first.toStr() , ("JointState/name.0"));
  EXPECT_EQ( flat_container.name[1].second, ("hola") );
  EXPECT_EQ( flat_container.name[2].first.toStr() , ("JointState/name.1"));
  EXPECT_EQ( flat_container.name[2].second, ("ciao") );
  EXPECT_EQ( flat_container.name[3].first.toStr() , ("JointState/name.2"));
  EXPECT_EQ( flat_container.name[3].second, ("bye") );
}

TEST( Deserialize, NavSatStatus)

{
  // We test this because we want to test that constant fields are skipped.

  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::NavSatStatus >::value(),
        Definition<sensor_msgs::NavSatStatus >::value() );

  sensor_msgs::NavSatStatus nav_stat;
  nav_stat.status  = nav_stat.STATUS_GBAS_FIX;  // 2
  nav_stat.service = nav_stat.SERVICE_COMPASS; // 4

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::NavSatStatus>::write(stream, nav_stat);

  ROSType main_type( DataType<sensor_msgs::NavSatStatus >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "nav_stat",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){ std::cout << " -------------------- " << std::endl;

    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  EXPECT_EQ( flat_container.value[0].first.toStr() , ("nav_stat/status"));
  EXPECT_EQ( flat_container.value[0].second, nav_stat.STATUS_GBAS_FIX );
  EXPECT_EQ( flat_container.value[1].first.toStr() , ("nav_stat/service"));
  EXPECT_EQ( flat_container.value[1].second, nav_stat.SERVICE_COMPASS );
}

TEST( Deserialize, DeserializeIMU)
//int func()
{
  // We test this because to check if arrays with fixed length work.

  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<sensor_msgs::Imu >::value(),
        Definition<sensor_msgs::Imu >::value() );

  sensor_msgs::Imu imu;

  imu.header.seq = 2016;
  imu.header.stamp.sec  = 1234;
  imu.header.stamp.nsec = 567*1000*1000;
  imu.header.frame_id = "pippo";

  imu.orientation.x = 11;
  imu.orientation.y = 12;
  imu.orientation.z = 13;
  imu.orientation.w = 14;

  imu.angular_velocity.x = 21;
  imu.angular_velocity.y = 22;
  imu.angular_velocity.z = 23;

  imu.linear_acceleration.x = 31;
  imu.linear_acceleration.y = 32;
  imu.linear_acceleration.z = 33;

  for (int i=0; i<9; i++)
  {
    imu.orientation_covariance[i]         = 40+i;
    imu.angular_velocity_covariance[i]    = 50+i;
    imu.linear_acceleration_covariance[i] = 60+i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<sensor_msgs::Imu>::write(stream, imu);

  ROSType main_type( DataType<sensor_msgs::Imu >::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "imu",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){

    std::cout << " -------------------- " << std::endl;
    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

  int index = 0;

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/header/seq"));
  EXPECT_EQ( flat_container.value[index].second, 2016 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/header/stamp"));
  EXPECT_EQ( flat_container.value[index].second, 1234.567 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/x"));
  EXPECT_EQ( flat_container.value[index].second, 11 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/y"));
  EXPECT_EQ( flat_container.value[index].second, 12 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/z"));
  EXPECT_EQ( flat_container.value[index].second, 13 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/orientation/w"));
  EXPECT_EQ( flat_container.value[index].second, 14 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/orientation_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 40+i );
    index++;
  }

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/x"));
  EXPECT_EQ( flat_container.value[index].second, 21 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/y"));
  EXPECT_EQ( flat_container.value[index].second, 22 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/angular_velocity/z"));
  EXPECT_EQ( flat_container.value[index].second, 23 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/angular_velocity_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 50+i );
    index++;
  }

  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/x"));
  EXPECT_EQ( flat_container.value[index].second, 31 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/y"));
  EXPECT_EQ( flat_container.value[index].second, 32 );
  index++;
  EXPECT_EQ( flat_container.value[index].first.toStr() , ("imu/linear_acceleration/z"));
  EXPECT_EQ( flat_container.value[index].second, 33 );
  index++;

  for(int i=0; i<9; i++)
  {
    char str[64];
    sprintf(str, "imu/linear_acceleration_covariance.%d",i);
    EXPECT_EQ( flat_container.value[index].first.toStr() , (str) );
    EXPECT_EQ( flat_container.value[index].second, 60+i );
    index++;
  }
}

TEST( Deserialize, Int16MultiArrayDeserialize)
//int func()
{
  ROSTypeList type_map = buildROSTypeMapFromDefinition(
        DataType<std_msgs::Int16MultiArray >::value(),
        Definition<std_msgs::Int16MultiArray >::value() );

  std_msgs::Int16MultiArray multi_array;

  const unsigned N = 6;
  multi_array.layout.data_offset = 42;
  multi_array.data.resize(N);

  for (unsigned i=0; i<N; i++){
    multi_array.data[i] = i;
  }

  std::vector<uint8_t> buffer(64*1024);
  ros::serialization::OStream stream(buffer.data(), buffer.size());
  ros::serialization::Serializer<std_msgs::Int16MultiArray>::write(stream, multi_array);

  ROSType main_type( DataType<std_msgs::Int16MultiArray>::value() );

  ROSTypeFlat flat_container;
  buildRosFlatType(type_map,
                   main_type,
                   "multi_array",
                   buffer.data(),
                   &flat_container);

  if(VERBOSE_TEST){
    std::cout << " -------------------- " << std::endl;

    for(auto&it: flat_container.value) {
      std::cout << it.first << " >> " << it.second << std::endl;
    }
  }

}

<|endoftext|>


<commit_before>/*
   Copyright (C) 2014-2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

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

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

 */

#include "CTcpTransport.hpp"

#include <QTimer>

#include <QDebug>

static const quint32 tcpTimeout = 15 * 1000;

CTcpTransport::CTcpTransport(QObject *parent) :
    CTelegramTransport(parent),
    m_socket(nullptr),
    m_timeoutTimer(new QTimer(this))
{
    m_timeoutTimer->setInterval(tcpTimeout);
    connect(m_timeoutTimer, &QTimer::timeout, this, &CTcpTransport::onTimeout);
}

CTcpTransport::~CTcpTransport()
{
    if (m_socket && m_socket->isWritable()) {
        m_socket->waitForBytesWritten(100);
        m_socket->disconnectFromHost();
    }
}

void CTcpTransport::connectToHost(const QString &ipAddress, quint32 port)
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO << ipAddress << port;
#endif
    m_socket->connectToHost(ipAddress, port);
}

void CTcpTransport::disconnectFromHost()
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO;
#endif
    if (m_socket) {
        m_socket->disconnectFromHost();
    }
}

void CTcpTransport::sendPackageImplementation(const QByteArray &payload)
{
    // quint32 length (included length itself + packet number + crc32 + payload // Length MUST be divisible by 4
    // quint32 packet number
    // quint32 CRC32 (length, quint32 packet number, payload)
    // Payload

    // Abridged version:
    // quint8: 0xef
    // DataLength / 4 < 0x7f ?
    //      (quint8: Packet length / 4) :
    //      (quint8: 0x7f, quint24: Packet length / 4)
    // Payload

    if (payload.length() % 4) {
        qCritical() << Q_FUNC_INFO << "Invalid outgoing package! The payload size is not divisible by four!";
    }

    QByteArray package;
    package.reserve(payload.size() + 4);
    const quint32 length = payload.length() / 4;
    if (length < 0x7f) {
        package.append(char(length));
    } else {
        package.append(char(0x7f));
        package.append(reinterpret_cast<const char *>(&length), 3);
    }
    package.append(payload);
    m_socket->write(package);
    emit packageSent(package);
}

void CTcpTransport::setSessionType(CTcpTransport::SessionType sessionType)
{
    m_sessionType = sessionType;
}

void CTcpTransport::setState(QAbstractSocket::SocketState newState)
{
    //    qDebug() << Q_FUNC_INFO << newState;
    switch (newState) {
    case QAbstractSocket::HostLookupState:
    case QAbstractSocket::ConnectingState:
        m_timeoutTimer->start();
        break;
    case QAbstractSocket::ConnectedState:
        m_expectedLength = 0;
        setSessionType(Unknown);
        break;
    default:
        m_timeoutTimer->stop();
        break;
    }
    CTelegramTransport::setState(newState);
}

void CTcpTransport::onReadyRead()
{
    readEvent();
    while (m_socket->bytesAvailable() > 0) {
        if (m_expectedLength == 0) {
            if (m_socket->bytesAvailable() < 4) {
                // Four bytes is minimum readable size for new package
                return;
            }

            char length;
            m_socket->getChar(&length);

            if (length < char(0x7f)) {
                m_expectedLength = length * 4;
            } else if (length == char(0x7f)) {
                m_socket->read((char *) &m_expectedLength, 3);
                m_expectedLength *= 4;
            } else {
                qDebug() << "Incorrect TCP package!";
            }
        }

        if (m_socket->bytesAvailable() < m_expectedLength) {
            return;
        }

        const QByteArray readPackage = m_socket->read(m_expectedLength);
        m_expectedLength = 0;
        packageReceived(readPackage);
    }
}

void CTcpTransport::onTimeout()
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO << "(connection to " << m_socket->peerName() << m_socket->peerPort() << ").";
#endif
    emit timeout();
    m_socket->disconnectFromHost();
}

void CTcpTransport::setSocket(QAbstractSocket *socket)
{
    if (m_socket) {
        qCritical() << Q_FUNC_INFO << "An attempt to set a socket twice";
    }
    m_socket = socket;
    connect(m_socket, &QAbstractSocket::stateChanged, this, &CTcpTransport::setState);
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(setError(QAbstractSocket::SocketError)));
    connect(m_socket, &QIODevice::readyRead, this, &CTcpTransport::onReadyRead);
}
<commit_msg>CTcpTransport: Fix connection timeout timer<commit_after>/*
   Copyright (C) 2014-2017 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

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

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

 */

#include "CTcpTransport.hpp"

#include <QTimer>

#include <QDebug>

#ifndef Q_FALLTHROUGH
#define Q_FALLTHROUGH() (void)0
#endif

static const quint32 tcpTimeout = 15 * 1000;

CTcpTransport::CTcpTransport(QObject *parent) :
    CTelegramTransport(parent),
    m_socket(nullptr),
    m_timeoutTimer(new QTimer(this))
{
    m_timeoutTimer->setInterval(tcpTimeout);
    connect(m_timeoutTimer, &QTimer::timeout, this, &CTcpTransport::onTimeout);
}

CTcpTransport::~CTcpTransport()
{
    if (m_socket && m_socket->isWritable()) {
        m_socket->waitForBytesWritten(100);
        m_socket->disconnectFromHost();
    }
}

void CTcpTransport::connectToHost(const QString &ipAddress, quint32 port)
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO << ipAddress << port;
#endif
    m_socket->connectToHost(ipAddress, port);
}

void CTcpTransport::disconnectFromHost()
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO;
#endif
    if (m_socket) {
        m_socket->disconnectFromHost();
    }
}

void CTcpTransport::sendPackageImplementation(const QByteArray &payload)
{
    // quint32 length (included length itself + packet number + crc32 + payload // Length MUST be divisible by 4
    // quint32 packet number
    // quint32 CRC32 (length, quint32 packet number, payload)
    // Payload

    // Abridged version:
    // quint8: 0xef
    // DataLength / 4 < 0x7f ?
    //      (quint8: Packet length / 4) :
    //      (quint8: 0x7f, quint24: Packet length / 4)
    // Payload

    if (payload.length() % 4) {
        qCritical() << Q_FUNC_INFO << "Invalid outgoing package! The payload size is not divisible by four!";
    }

    QByteArray package;
    package.reserve(payload.size() + 4);
    const quint32 length = payload.length() / 4;
    if (length < 0x7f) {
        package.append(char(length));
    } else {
        package.append(char(0x7f));
        package.append(reinterpret_cast<const char *>(&length), 3);
    }
    package.append(payload);
    m_socket->write(package);
    emit packageSent(package);
}

void CTcpTransport::setSessionType(CTcpTransport::SessionType sessionType)
{
    m_sessionType = sessionType;
}

void CTcpTransport::setState(QAbstractSocket::SocketState newState)
{
    //    qDebug() << Q_FUNC_INFO << newState;
    switch (newState) {
    case QAbstractSocket::HostLookupState:
    case QAbstractSocket::ConnectingState:
        m_timeoutTimer->start();
        break;
    case QAbstractSocket::ConnectedState:
        m_expectedLength = 0;
        setSessionType(Unknown);
        Q_FALLTHROUGH();
    default:
        m_timeoutTimer->stop();
        break;
    }
    CTelegramTransport::setState(newState);
}

void CTcpTransport::onReadyRead()
{
    readEvent();
    while (m_socket->bytesAvailable() > 0) {
        if (m_expectedLength == 0) {
            if (m_socket->bytesAvailable() < 4) {
                // Four bytes is minimum readable size for new package
                return;
            }

            char length;
            m_socket->getChar(&length);

            if (length < char(0x7f)) {
                m_expectedLength = length * 4;
            } else if (length == char(0x7f)) {
                m_socket->read((char *) &m_expectedLength, 3);
                m_expectedLength *= 4;
            } else {
                qDebug() << "Incorrect TCP package!";
            }
        }

        if (m_socket->bytesAvailable() < m_expectedLength) {
            return;
        }

        const QByteArray readPackage = m_socket->read(m_expectedLength);
        m_expectedLength = 0;
        packageReceived(readPackage);
    }
}

void CTcpTransport::onTimeout()
{
#ifdef DEVELOPER_BUILD
    qDebug() << Q_FUNC_INFO << "(connection to " << m_socket->peerName() << m_socket->peerPort() << ").";
#endif
    emit timeout();
    m_socket->disconnectFromHost();
}

void CTcpTransport::setSocket(QAbstractSocket *socket)
{
    if (m_socket) {
        qCritical() << Q_FUNC_INFO << "An attempt to set a socket twice";
    }
    m_socket = socket;
    connect(m_socket, &QAbstractSocket::stateChanged, this, &CTcpTransport::setState);
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(setError(QAbstractSocket::SocketError)));
    connect(m_socket, &QIODevice::readyRead, this, &CTcpTransport::onReadyRead);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016+     AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2
 * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
 */

#define _CRT_SECURE_NO_DEPRECATE

#include "wdt.h"

u_map_fcc MWMOMagic = { {'O', 'M', 'W', 'M'} };
u_map_fcc MPHDMagic = { {'D', 'H', 'P', 'M'} };
u_map_fcc MAINMagic = { {'N', 'I', 'A', 'M'} };

bool wdt_MWMO::prepareLoadedData()
{
    if (fcc != MWMOMagic.fcc)
        return false;
    return true;
}

bool wdt_MPHD::prepareLoadedData()
{
    if (fcc != MPHDMagic.fcc)
        return false;
    return true;
}

bool wdt_MAIN::prepareLoadedData()
{
    if (fcc != MAINMagic.fcc)
        return false;
    return true;
}

WDT_file::WDT_file()
{
    mphd = nullptr;
    main = nullptr;
    wmo  = nullptr;
}

WDT_file::~WDT_file()
{
    free();
}

void WDT_file::free()
{
    mphd = nullptr;
    main = nullptr;
    wmo  = nullptr;
    FileLoader::free();
}

bool WDT_file::prepareLoadedData()
{
    // Check parent
    if (!FileLoader::prepareLoadedData())
        return false;

    mphd = (wdt_MPHD*)((uint8*)version + version->size + 8);
    if (!mphd->prepareLoadedData())
        return false;
    main = (wdt_MAIN*)((uint8*)mphd + mphd->size + 8);
    if (!main->prepareLoadedData())
        return false;
    wmo = (wdt_MWMO*)((uint8*)main + main->size + 8);
    if (!wmo->prepareLoadedData())
        return false;
    return true;
}
<commit_msg>fix(Core/Tools): extracting custom maps (#5138)<commit_after>/*
 * Copyright (C) 2016+     AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2
 * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
 */

#define _CRT_SECURE_NO_DEPRECATE

#include "wdt.h"

u_map_fcc MWMOMagic = { {'O', 'M', 'W', 'M'} };
u_map_fcc MPHDMagic = { {'D', 'H', 'P', 'M'} };
u_map_fcc MAINMagic = { {'N', 'I', 'A', 'M'} };

bool wdt_MWMO::prepareLoadedData()
{
    if (fcc != MWMOMagic.fcc)
        return false;
    return true;
}

bool wdt_MPHD::prepareLoadedData()
{
    if (fcc != MPHDMagic.fcc)
        return false;
    return true;
}

bool wdt_MAIN::prepareLoadedData()
{
    if (fcc != MAINMagic.fcc)
        return false;
    return true;
}

WDT_file::WDT_file()
{
    mphd = nullptr;
    main = nullptr;
    wmo  = nullptr;
}

WDT_file::~WDT_file()
{
    free();
}

void WDT_file::free()
{
    mphd = nullptr;
    main = nullptr;
    wmo  = nullptr;
    FileLoader::free();
}

bool WDT_file::prepareLoadedData()
{
    // Check parent
    if (!FileLoader::prepareLoadedData())
        return false;

    mphd = (wdt_MPHD*)((uint8*)version + version->size + 8);
    if (!mphd->prepareLoadedData())
        return false;
    main = (wdt_MAIN*)((uint8*)mphd + mphd->size + 8);
    if (!main->prepareLoadedData())
        return false;
    wmo = (wdt_MWMO*)((uint8*)main + main->size + 8);
    // if (!wmo->prepareLoadedData())
    //     return false;
    return true;
}
<|endoftext|>


<commit_before><commit_msg>Resolves: rhbz#807316 don't complain that nocrashreport is an unknown option<commit_after><|endoftext|>


<commit_before>/*
   Copyright 2013 Brain Research Institute, Melbourne, Australia

   Written by David Raffelt 10/04/2013

   This file is part of MRtrix.

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

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

   You should have received a copy of the GNU General Public License
   along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "mrtrix.h"
#include "gui/mrview/window.h"
#include "gui/mrview/mode/base.h"
#include "gui/mrview/tool/screen_capture.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        ScreenCapture::ScreenCapture (Window& main_window, Dock* parent) :
          Base (main_window, parent)
        {
          VBoxLayout* main_box = new VBoxLayout (this);

          QGroupBox* rotate_group_box = new QGroupBox ("Rotate");
          GridLayout* rotate_layout = new GridLayout;
          rotate_layout->setContentsMargins (5, 5, 5, 5);
          rotate_layout->setSpacing (5);
          main_box->addWidget (rotate_group_box);
          rotate_group_box->setLayout (rotate_layout);

          rotate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          rotation_axis_x = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_x, 0, 1);
          rotation_axis_x->setValue (0.0);
          rotation_axis_x->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          rotation_axis_y = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_y, 1, 1);
          rotation_axis_y->setValue (0.0);
          rotation_axis_y->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          rotation_axis_z = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_z, 2, 1);
          rotation_axis_z->setValue (1.0);
          rotation_axis_z->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Angle"), 3, 0);
          degrees_button = new AdjustButton (this);
          rotate_layout->addWidget (degrees_button, 3, 1);
          degrees_button->setValue (0.0);
          degrees_button->setRate (0.1);

          QGroupBox* translate_group_box = new QGroupBox ("Translate");
          GridLayout* translate_layout = new GridLayout;
          translate_layout->setContentsMargins (5, 5, 5, 5);
          translate_layout->setSpacing (5);
          main_box->addWidget (translate_group_box);
          translate_group_box->setLayout (translate_layout);

          translate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          translate_x = new AdjustButton (this);
          translate_layout->addWidget (translate_x, 0, 1);
          translate_x->setValue (0.0);
          translate_x->setRate (0.1);

          translate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          translate_y = new AdjustButton (this);
          translate_layout->addWidget (translate_y, 1, 1);
          translate_y->setValue (0.0);
          translate_y->setRate (0.1);

          translate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          translate_z = new AdjustButton (this);
          translate_layout->addWidget (translate_z, 2, 1);
          translate_z->setValue (0.0);
          translate_z->setRate (0.1);

          QGroupBox* volume_group_box = new QGroupBox ("Volume");
          GridLayout* volume_layout = new GridLayout;
          volume_layout->setContentsMargins (5, 5, 5, 5);
          volume_layout->setSpacing (5);
          main_box->addWidget (volume_group_box);
          volume_group_box->setLayout (volume_layout);

          volume_layout->addWidget (new QLabel ("Axis"), 0, 0);
          volume_axis = new QSpinBox (this);
          volume_axis->setMinimum (3);
          volume_axis->setValue (3);
          volume_layout->addWidget (volume_axis, 0, 1);

          volume_layout->addWidget (new QLabel ("Target"), 1, 0);
          target_volume = new AdjustButton (this);
          volume_layout->addWidget (target_volume, 1, 1);
          target_volume->setValue (0.0);
          target_volume->setRate (0.1);

          QGroupBox* FOV_group_box = new QGroupBox ("FOV");
          GridLayout* FOV_layout = new GridLayout;
          FOV_layout->setContentsMargins (5, 5, 5, 5);
          FOV_layout->setSpacing (5);
          main_box->addWidget (FOV_group_box);
          FOV_group_box->setLayout (FOV_layout);

          FOV_layout->addWidget (new QLabel ("Multiplier"), 0, 0);
          FOV_multipler = new AdjustButton (this);
          FOV_layout->addWidget (FOV_multipler, 0, 1);
          FOV_multipler->setValue (1.0);
          FOV_multipler->setRate (0.01);

          QGroupBox* output_group_box = new QGroupBox ("Output");
          main_box->addWidget (output_group_box);
          GridLayout* output_grid_layout = new GridLayout;
          output_group_box->setLayout (output_grid_layout);

          output_grid_layout->addWidget (new QLabel ("Prefix"), 0, 0);
          prefix_textbox = new QLineEdit ("screenshot", this);
          output_grid_layout->addWidget (prefix_textbox, 0, 1);
          connect (prefix_textbox, SIGNAL (editingFinished()), this, SLOT (on_output_update()));

          folder_button = new QPushButton ("Select output folder", this);
          folder_button->setToolTip (tr ("Output Folder"));
          connect (folder_button, SIGNAL (clicked()), this, SLOT (select_output_folder_slot ()));
          output_grid_layout->addWidget (folder_button, 1, 0, 1, 2);

          QGroupBox* capture_group_box = new QGroupBox ("Capture");
          main_box->addWidget (capture_group_box);
          GridLayout* capture_grid_layout = new GridLayout;
          capture_group_box->setLayout (capture_grid_layout);

          capture_grid_layout->addWidget (new QLabel ("Start Index"), 0, 0);
          start_index = new QSpinBox (this);
          start_index->setMinimum (0);
          start_index->setMaximum (std::numeric_limits<int>::max());
          start_index->setValue (0);
          capture_grid_layout->addWidget (start_index, 0, 1);

          capture_grid_layout->addWidget (new QLabel ("Frames"), 1, 0);
          frames = new QSpinBox (this);
          frames->setMinimum (0);
          frames->setMaximum (std::numeric_limits<int>::max());
          frames->setValue (1);
          capture_grid_layout->addWidget (frames, 1, 1);

          QPushButton* preview = new QPushButton ("Preview", this);
          connect (preview, SIGNAL (clicked()), this, SLOT (on_screen_preview()));
          capture_grid_layout->addWidget (preview, 2, 0, 1, 2);

          QPushButton* capture = new QPushButton ("Record", this);
          connect (capture, SIGNAL (clicked()), this, SLOT (on_screen_capture()));
          capture_grid_layout->addWidget (capture, 3, 0, 1, 2);

          main_box->addStretch ();

          directory = new QDir();
        }

        void ScreenCapture::on_screen_preview () { run (false); }

        void ScreenCapture::on_screen_capture () { run (true); }

        void ScreenCapture::run (bool with_capture)
        {
          if (!window.image())
            return;

          Image::VoxelType& vox (window.image()->interp);

          if (std::isnan (rotation_axis_x->value()))
            rotation_axis_x->setValue (0.0);
          if (std::isnan (rotation_axis_y->value()))
            rotation_axis_y->setValue (0.0);
          if (std::isnan (rotation_axis_z->value()))
            rotation_axis_z->setValue (0.0);
          if (std::isnan (degrees_button->value()))
            degrees_button->setValue (0.0);

          if (std::isnan (translate_x->value()))
            translate_x->setValue(0.0);
          if (std::isnan (translate_y->value()))
            translate_y->setValue(0.0);
          if (std::isnan (translate_z->value()))
            translate_z->setValue(0.0);

          if (std::isnan (target_volume->value()))
            target_volume->setValue(0.0);

          if (volume_axis->value() >= ssize_t (vox.ndim()))
            volume_axis->setValue (vox.ndim()-1);

          if (target_volume->value() >= vox.dim(volume_axis->value()))
            target_volume->setValue (vox.dim(volume_axis->value())-1);

          if (std::isnan (FOV_multipler->value()))
            FOV_multipler->setValue(1.0);

          if (window.snap_to_image () && degrees_button->value() > 0.0)
            window.set_snap_to_image (false);
          float radians = degrees_button->value() * (Math::pi / 180.0) / frames->value();
          float volume = vox[volume_axis->value()];
          float volume_inc = (target_volume->value() - volume) / frames->value();
          std::string folder (directory->path().toUtf8().constData());
          std::string prefix (prefix_textbox->text().toUtf8().constData());
          int first_index = start_index->value();
          int i = first_index;

          for (; i < first_index + frames->value(); ++i) {
            if (with_capture)
              this->window.captureGL (folder + "/" + prefix + printf ("%04d.png", i));

            // Rotation
            Math::Versor<float> orientation (this->window.orientation());
            Math::Vector<float> axis (3);
            axis[0] = rotation_axis_x->value();
            axis[1] = rotation_axis_y->value();
            axis[2] = rotation_axis_z->value();
            Math::Versor<float> rotation (radians, axis.ptr());
            orientation *= rotation;
            this->window.set_orientation (orientation);

            // Translation
            Point<float> focus (this->window.focus());
            focus[0] += translate_x->value() / frames->value();
            focus[1] += translate_y->value() / frames->value();
            focus[2] += translate_z->value() / frames->value();
            window.set_focus (focus);
            Point<float> target (this->window.target());
            target[0] += translate_x->value() / frames->value();
            target[1] += translate_y->value() / frames->value();
            target[2] += translate_z->value() / frames->value();
            window.set_target (target);

            // Volume
            volume += volume_inc;
            window.set_image_volume (volume_axis->value(), std::round (volume));

            // FOV
            window.set_FOV (window.FOV() * (std::pow (FOV_multipler->value(), (float) 1.0 / frames->value())));

            start_index->setValue (i + 1);
            this->window.updateGL();
            qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
          }
        }

        void ScreenCapture::select_output_folder_slot ()
        {
          directory->setPath(QFileDialog::getExistingDirectory (this, tr("Directory"), directory->path()));
          QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
          if (!path.size()) return;
          folder_button->setText(path);
          on_output_update ();
        }

        void ScreenCapture::on_output_update () {
          start_index->setValue (0);
        }

        bool ScreenCapture::process_batch_command (const std::string& cmd, const std::string& args)
        {
          // BATCH_COMMAND capture.folder path # Set the output folder for the screen capture tool
          if (cmd == "capture.folder") {
            directory->setPath (args.c_str());
            QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
            folder_button->setText(path);
            on_output_update ();
            return true;
          }

          // BATCH_COMMAND capture.prefix path # Set the output file prefix for the screen capture tool
          if (cmd == "capture.prefix") {
            prefix_textbox->setText (args.c_str());
            on_output_update ();
            return true;
          }

          // BATCH_COMMAND capture.grab # Start the screen capture process
          if (cmd == "capture.grab") {
            on_screen_capture();
            return true;
          }

          return false;
        }

      }
    }
  }
}

<commit_msg>MRView: fix segfault when using Screen Capture tool<commit_after>/*
   Copyright 2013 Brain Research Institute, Melbourne, Australia

   Written by David Raffelt 10/04/2013

   This file is part of MRtrix.

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

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

   You should have received a copy of the GNU General Public License
   along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "mrtrix.h"
#include "gui/mrview/window.h"
#include "gui/mrview/mode/base.h"
#include "gui/mrview/tool/screen_capture.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Tool
      {

        ScreenCapture::ScreenCapture (Window& main_window, Dock* parent) :
          Base (main_window, parent)
        {
          VBoxLayout* main_box = new VBoxLayout (this);

          QGroupBox* rotate_group_box = new QGroupBox ("Rotate");
          GridLayout* rotate_layout = new GridLayout;
          rotate_layout->setContentsMargins (5, 5, 5, 5);
          rotate_layout->setSpacing (5);
          main_box->addWidget (rotate_group_box);
          rotate_group_box->setLayout (rotate_layout);

          rotate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          rotation_axis_x = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_x, 0, 1);
          rotation_axis_x->setValue (0.0);
          rotation_axis_x->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          rotation_axis_y = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_y, 1, 1);
          rotation_axis_y->setValue (0.0);
          rotation_axis_y->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          rotation_axis_z = new AdjustButton (this);
          rotate_layout->addWidget (rotation_axis_z, 2, 1);
          rotation_axis_z->setValue (1.0);
          rotation_axis_z->setRate (0.1);

          rotate_layout->addWidget (new QLabel ("Angle"), 3, 0);
          degrees_button = new AdjustButton (this);
          rotate_layout->addWidget (degrees_button, 3, 1);
          degrees_button->setValue (0.0);
          degrees_button->setRate (0.1);

          QGroupBox* translate_group_box = new QGroupBox ("Translate");
          GridLayout* translate_layout = new GridLayout;
          translate_layout->setContentsMargins (5, 5, 5, 5);
          translate_layout->setSpacing (5);
          main_box->addWidget (translate_group_box);
          translate_group_box->setLayout (translate_layout);

          translate_layout->addWidget (new QLabel ("Axis X"), 0, 0);
          translate_x = new AdjustButton (this);
          translate_layout->addWidget (translate_x, 0, 1);
          translate_x->setValue (0.0);
          translate_x->setRate (0.1);

          translate_layout->addWidget (new QLabel ("Axis Y"), 1, 0);
          translate_y = new AdjustButton (this);
          translate_layout->addWidget (translate_y, 1, 1);
          translate_y->setValue (0.0);
          translate_y->setRate (0.1);

          translate_layout->addWidget (new QLabel ("Axis Z"), 2, 0);
          translate_z = new AdjustButton (this);
          translate_layout->addWidget (translate_z, 2, 1);
          translate_z->setValue (0.0);
          translate_z->setRate (0.1);

          QGroupBox* volume_group_box = new QGroupBox ("Volume");
          GridLayout* volume_layout = new GridLayout;
          volume_layout->setContentsMargins (5, 5, 5, 5);
          volume_layout->setSpacing (5);
          main_box->addWidget (volume_group_box);
          volume_group_box->setLayout (volume_layout);

          volume_layout->addWidget (new QLabel ("Axis"), 0, 0);
          volume_axis = new QSpinBox (this);
          volume_axis->setMinimum (3);
          volume_axis->setValue (3);
          volume_layout->addWidget (volume_axis, 0, 1);

          volume_layout->addWidget (new QLabel ("Target"), 1, 0);
          target_volume = new AdjustButton (this);
          volume_layout->addWidget (target_volume, 1, 1);
          target_volume->setValue (0.0);
          target_volume->setRate (0.1);

          QGroupBox* FOV_group_box = new QGroupBox ("FOV");
          GridLayout* FOV_layout = new GridLayout;
          FOV_layout->setContentsMargins (5, 5, 5, 5);
          FOV_layout->setSpacing (5);
          main_box->addWidget (FOV_group_box);
          FOV_group_box->setLayout (FOV_layout);

          FOV_layout->addWidget (new QLabel ("Multiplier"), 0, 0);
          FOV_multipler = new AdjustButton (this);
          FOV_layout->addWidget (FOV_multipler, 0, 1);
          FOV_multipler->setValue (1.0);
          FOV_multipler->setRate (0.01);

          QGroupBox* output_group_box = new QGroupBox ("Output");
          main_box->addWidget (output_group_box);
          GridLayout* output_grid_layout = new GridLayout;
          output_group_box->setLayout (output_grid_layout);

          output_grid_layout->addWidget (new QLabel ("Prefix"), 0, 0);
          prefix_textbox = new QLineEdit ("screenshot", this);
          output_grid_layout->addWidget (prefix_textbox, 0, 1);
          connect (prefix_textbox, SIGNAL (editingFinished()), this, SLOT (on_output_update()));

          folder_button = new QPushButton ("Select output folder", this);
          folder_button->setToolTip (tr ("Output Folder"));
          connect (folder_button, SIGNAL (clicked()), this, SLOT (select_output_folder_slot ()));
          output_grid_layout->addWidget (folder_button, 1, 0, 1, 2);

          QGroupBox* capture_group_box = new QGroupBox ("Capture");
          main_box->addWidget (capture_group_box);
          GridLayout* capture_grid_layout = new GridLayout;
          capture_group_box->setLayout (capture_grid_layout);

          capture_grid_layout->addWidget (new QLabel ("Start Index"), 0, 0);
          start_index = new QSpinBox (this);
          start_index->setMinimum (0);
          start_index->setMaximum (std::numeric_limits<int>::max());
          start_index->setValue (0);
          capture_grid_layout->addWidget (start_index, 0, 1);

          capture_grid_layout->addWidget (new QLabel ("Frames"), 1, 0);
          frames = new QSpinBox (this);
          frames->setMinimum (0);
          frames->setMaximum (std::numeric_limits<int>::max());
          frames->setValue (1);
          capture_grid_layout->addWidget (frames, 1, 1);

          QPushButton* preview = new QPushButton ("Preview", this);
          connect (preview, SIGNAL (clicked()), this, SLOT (on_screen_preview()));
          capture_grid_layout->addWidget (preview, 2, 0, 1, 2);

          QPushButton* capture = new QPushButton ("Record", this);
          connect (capture, SIGNAL (clicked()), this, SLOT (on_screen_capture()));
          capture_grid_layout->addWidget (capture, 3, 0, 1, 2);

          main_box->addStretch ();

          directory = new QDir();
        }

        void ScreenCapture::on_screen_preview () { run (false); }

        void ScreenCapture::on_screen_capture () { run (true); }

        void ScreenCapture::run (bool with_capture)
        {
          if (!window.image())
            return;

          Image::VoxelType& vox (window.image()->interp);

          if (std::isnan (rotation_axis_x->value()))
            rotation_axis_x->setValue (0.0);
          if (std::isnan (rotation_axis_y->value()))
            rotation_axis_y->setValue (0.0);
          if (std::isnan (rotation_axis_z->value()))
            rotation_axis_z->setValue (0.0);
          if (std::isnan (degrees_button->value()))
            degrees_button->setValue (0.0);

          if (std::isnan (translate_x->value()))
            translate_x->setValue(0.0);
          if (std::isnan (translate_y->value()))
            translate_y->setValue(0.0);
          if (std::isnan (translate_z->value()))
            translate_z->setValue(0.0);

          if (std::isnan (target_volume->value()))
            target_volume->setValue(0.0);

          if (std::isnan (FOV_multipler->value()))
            FOV_multipler->setValue(1.0);

          if (window.snap_to_image () && degrees_button->value() > 0.0)
            window.set_snap_to_image (false);

          float volume = 0.0, volume_inc = 0.0;
          if (volume_axis->value() < ssize_t (vox.ndim())) {
            if (target_volume->value() >= vox.dim(volume_axis->value()))
              target_volume->setValue (vox.dim(volume_axis->value())-1);
            volume = vox[volume_axis->value()];
            volume_inc = (target_volume->value() - volume) / frames->value();
          }

          std::string folder (directory->path().toUtf8().constData());
          std::string prefix (prefix_textbox->text().toUtf8().constData());
          float radians = degrees_button->value() * (Math::pi / 180.0) / frames->value();
          int first_index = start_index->value();
          int i = first_index;

          for (; i < first_index + frames->value(); ++i) {
            if (with_capture)
              this->window.captureGL (folder + "/" + prefix + printf ("%04d.png", i));

            // Rotation
            Math::Versor<float> orientation (this->window.orientation());
            Math::Vector<float> axis (3);
            axis[0] = rotation_axis_x->value();
            axis[1] = rotation_axis_y->value();
            axis[2] = rotation_axis_z->value();
            Math::Versor<float> rotation (radians, axis.ptr());
            orientation *= rotation;
            this->window.set_orientation (orientation);

            // Translation
            Point<float> focus (this->window.focus());
            focus[0] += translate_x->value() / frames->value();
            focus[1] += translate_y->value() / frames->value();
            focus[2] += translate_z->value() / frames->value();
            window.set_focus (focus);
            Point<float> target (this->window.target());
            target[0] += translate_x->value() / frames->value();
            target[1] += translate_y->value() / frames->value();
            target[2] += translate_z->value() / frames->value();
            window.set_target (target);

            // Volume
            if (volume_axis->value() < ssize_t (vox.ndim())) {
              volume += volume_inc;
              window.set_image_volume (volume_axis->value(), std::round (volume));
            }

            // FOV
            window.set_FOV (window.FOV() * (std::pow (FOV_multipler->value(), (float) 1.0 / frames->value())));

            start_index->setValue (i + 1);
            this->window.updateGL();
            qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
          }
        }

        void ScreenCapture::select_output_folder_slot ()
        {
          directory->setPath(QFileDialog::getExistingDirectory (this, tr("Directory"), directory->path()));
          QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
          if (!path.size()) return;
          folder_button->setText(path);
          on_output_update ();
        }

        void ScreenCapture::on_output_update () {
          start_index->setValue (0);
        }

        bool ScreenCapture::process_batch_command (const std::string& cmd, const std::string& args)
        {
          // BATCH_COMMAND capture.folder path # Set the output folder for the screen capture tool
          if (cmd == "capture.folder") {
            directory->setPath (args.c_str());
            QString path (shorten(directory->path().toUtf8().constData(), 20, 0).c_str());
            folder_button->setText(path);
            on_output_update ();
            return true;
          }

          // BATCH_COMMAND capture.prefix path # Set the output file prefix for the screen capture tool
          if (cmd == "capture.prefix") {
            prefix_textbox->setText (args.c_str());
            on_output_update ();
            return true;
          }

          // BATCH_COMMAND capture.grab # Start the screen capture process
          if (cmd == "capture.grab") {
            on_screen_capture();
            return true;
          }

          return false;
        }

      }
    }
  }
}

<|endoftext|>


<commit_before>/*! @file zerocrossings.cc
 *  @brief Number of time domain zero crossings of the signal.
 *  @author Markovtsev Vadim <v.markovtsev@samsung.com>
 *  @version 1.0
 *
 *  @section Notes
 *  This code partially conforms to Google C++ Style Guide.
 *
 *  @section Copyright
 *  Copyright 2013 Samsung R&D Institute Russia
 */

#include "src/transforms/zerocrossings.h"
#ifdef __AVX__
#include <immintrin.h>
#elif defined(__ARM_NEON__)
#include <arm_neon.h>
#endif
#include <simd/avx_extra.h>

namespace sound_feature_extraction {
namespace transforms {

int ZeroCrossingsF::DoInternal(bool simd, const float* input,
                                    size_t length) const noexcept {
  int ilength = length;
  if (simd) {
#ifdef __AVX__
    __m256 crossings = _mm256_setzero_ps();
    const __m256 zeros = _mm256_setzero_ps();
    const __m256 ones = _mm256_set1_ps(1.f);
    for (int i = 0; i < ilength - 8; i += 8) {
      __m256 vecpre = _mm256_load_ps(input + i);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
      __m256 zerocheck =  _mm256_cmp_ps(vecpre, zeros, _CMP_EQ_OQ);
      __m256 vec = _mm256_loadu_ps(input + i + 1);
      __m256 tmp = _mm256_mul_ps(vecpre, vec);
      tmp = _mm256_cmp_ps(tmp, zeros, _CMP_LT_OQ);
#pragma GCC diagnostic pop
      tmp = _mm256_or_ps(tmp, zerocheck);
      tmp = _mm256_blendv_ps(zeros, ones, tmp);
      crossings = _mm256_add_ps(crossings, tmp);
    }
    crossings = _mm256_hadd_ps(crossings, crossings);
    crossings = _mm256_hadd_ps(crossings, crossings);
    int res = ElementAt(crossings, 0) + ElementAt(crossings, 4);
    int startIndex = ((ilength - 1) >> 3) << 3;
    float valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#elif defined(__ARM_NEON__)
    uint32x4_t crossings = vdupq_n_u32(0);
    const float32x4_t zeros = vdupq_n_f32(0.f);
    for (int i = 0; i < ilength - 4; i += 4) {
      float32x4_t vecpre = vld1q_f32(input + i);
      uint32x4_t zerocheck =  vceqq_f32(vecpre, zeros);
      float32x4_t vec = vld1q_f32(input + i + 1);
      float32x4_t tmp = vmulq_f32(vecpre, vec);
      uint32x4_t cmpres = vcltq_f32(tmp, zeros);
      cmpres = vorrq_u32(cmpres, zerocheck);
      crossings = vaddq_u32(crossings, cmpres);
    }
    uint64x2_t crossings64 = vpaddlq_u32(crossings);
    int res = vgetq_lane_u64(crossings64, 0) + vgetq_lane_u64(crossings64, 1);
    int startIndex = ((ilength - 1) >> 2) << 2;
    float valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#else
  } {
#endif
    int res = 0;
    float valpre = input[0];
    for (int i = 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  }
}

int ZeroCrossings16::DoInternal(bool simd, const int16_t* input,
                                 size_t length) const noexcept {
  int ilength = length;
  if (simd) {
#ifdef __AVX__
#ifdef __AVX2__
#error TODO(v.markovtsev): AVX2 adds integer operations, implement Do properly
#endif
    __m128i crossings = _mm_setzero_si128();
    const __m128i zeros = _mm_setzero_si128();
    const __m128i ones = _mm_set1_epi16(1);
    for (int i = 0; i < ilength - 8; i += 8) {
      __m128i vecpre = _mm_loadu_si128(
          reinterpret_cast<const __m128i*>(input + i));
      __m128i zerocheck =  _mm_cmpeq_epi16(vecpre, zeros);
      __m128i vec = _mm_loadu_si128(
          reinterpret_cast<const __m128i*>(input + i + 1));
      __m128i tmp = _mm_xor_si128(vecpre, vec);
      tmp = _mm_cmplt_epi16(tmp, ones);
      tmp = _mm_xor_si128(tmp, zerocheck);
      tmp = _mm_and_si128(tmp, ones);
      __m128i tmplo = _mm_unpacklo_epi16(tmp, zeros);
      __m128i tmphi = _mm_unpackhi_epi16(tmp, zeros);
      crossings = _mm_add_epi32(crossings, tmplo);
      crossings = _mm_add_epi32(crossings, tmphi);
    }
    crossings = _mm_hadd_epi32(crossings, crossings);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
    int res = _mm_extract_epi32(crossings, 0) + _mm_extract_epi32(crossings, 2);
#pragma GCC diagnostic pop
    int startIndex = ((ilength - 1) >> 3) << 3;
    int16_t valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#elif defined(__ARM_NEON__)
    uint32x4_t crossings = vdupq_n_u32(0);
    const int16x8_t zeros = vdupq_n_s16(0);
    for (int i = 0; i < ilength - 8; i += 8) {
      int16x8_t vecpre = vld1q_s16(input + i);
      uint16x8_t zerocheck =  vceqq_s16(vecpre, zeros);
      int16x8_t vec = vld1q_s16(input + i + 1);
      int16x8_t tmp = veorq_s16(vecpre, vec);
      uint16x8_t cmpres = vcleq_s16(tmp, zeros);
      cmpres = veorq_u16(cmpres, zerocheck);
      crossings = vpadalq_u16(crossings, cmpres);
    }
    uint64x2_t crossings64 = vpaddlq_u32(crossings);
    int res = vgetq_lane_u64(crossings64, 0) + vgetq_lane_u64(crossings64, 1);
    int startIndex = ((ilength - 1) >> 3) << 3;
    int16_t valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#else
  } {
#endif
    int res = 0;
    int16_t valpre = input[0];
    for (int i = 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  }
}

REGISTER_TRANSFORM(ZeroCrossingsF);
REGISTER_TRANSFORM(ZeroCrossings16);

}  // namespace transforms
}  // namespace sound_feature_extraction
<commit_msg>Fixed transforms/zerocrossings on ARM<commit_after>/*! @file zerocrossings.cc
 *  @brief Number of time domain zero crossings of the signal.
 *  @author Markovtsev Vadim <v.markovtsev@samsung.com>
 *  @version 1.0
 *
 *  @section Notes
 *  This code partially conforms to Google C++ Style Guide.
 *
 *  @section Copyright
 *  Copyright 2013 Samsung R&D Institute Russia
 */

#include "src/transforms/zerocrossings.h"
#ifdef __AVX__
#include <immintrin.h>
#elif defined(__ARM_NEON__)
#include <arm_neon.h>
#endif
#include <simd/avx_extra.h>

namespace sound_feature_extraction {
namespace transforms {

int ZeroCrossingsF::DoInternal(bool simd, const float* input,
                               size_t length) const noexcept {
  int ilength = length;
  if (simd) {
#ifdef __AVX__
    __m256 crossings = _mm256_setzero_ps();
    const __m256 zeros = _mm256_setzero_ps();
    const __m256 ones = _mm256_set1_ps(1.f);
    for (int i = 0; i < ilength - 8; i += 8) {
      __m256 vecpre = _mm256_load_ps(input + i);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
      __m256 zerocheck =  _mm256_cmp_ps(vecpre, zeros, _CMP_EQ_OQ);
      __m256 vec = _mm256_loadu_ps(input + i + 1);
      __m256 tmp = _mm256_mul_ps(vecpre, vec);
      tmp = _mm256_cmp_ps(tmp, zeros, _CMP_LT_OQ);
#pragma GCC diagnostic pop
      tmp = _mm256_or_ps(tmp, zerocheck);
      tmp = _mm256_blendv_ps(zeros, ones, tmp);
      crossings = _mm256_add_ps(crossings, tmp);
    }
    crossings = _mm256_hadd_ps(crossings, crossings);
    crossings = _mm256_hadd_ps(crossings, crossings);
    int res = ElementAt(crossings, 0) + ElementAt(crossings, 4);
    int startIndex = (ilength - 1) & ~0x7;
    float valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#elif defined(__ARM_NEON__)
    uint32x4_t crossings = vdupq_n_u32(0), ones = vdupq_n_u32(1);
    const float32x4_t zeros = vdupq_n_f32(0.f);
    for (int i = 0; i < ilength - 4; i += 4) {
      float32x4_t vecpre = vld1q_f32(input + i);
      uint32x4_t zerocheck =  vceqq_f32(vecpre, zeros);
      float32x4_t vec = vld1q_f32(input + i + 1);
      float32x4_t tmp = vmulq_f32(vecpre, vec);
      uint32x4_t cmpres = vcltq_f32(tmp, zeros);
      cmpres = vorrq_u32(cmpres, zerocheck);
      cmpres = vandq_u32(cmpres, ones);
      crossings = vaddq_u32(crossings, cmpres);
    }
    uint64x2_t crossings64 = vpaddlq_u32(crossings);
    int res = vgetq_lane_u64(crossings64, 0) + vgetq_lane_u64(crossings64, 1);
    int startIndex = (ilength - 1) & ~0x3;
    float valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#else
  } {
#endif
    int res = 0;
    float valpre = input[0];
    for (int i = 1; i < ilength; i++) {
      float val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  }
}

int ZeroCrossings16::DoInternal(bool simd, const int16_t* input,
                                size_t length) const noexcept {
  int ilength = length;
  if (simd) {
#ifdef __AVX__
#ifdef __AVX2__
#error TODO(v.markovtsev): AVX2 adds integer operations, implement Do properly
#endif
    __m128i crossings = _mm_setzero_si128();
    const __m128i zeros = _mm_setzero_si128();
    const __m128i ones = _mm_set1_epi16(1);
    for (int i = 0; i < ilength - 8; i += 8) {
      __m128i vecpre = _mm_loadu_si128(
          reinterpret_cast<const __m128i*>(input + i));
      __m128i zerocheck =  _mm_cmpeq_epi16(vecpre, zeros);
      __m128i vec = _mm_loadu_si128(
          reinterpret_cast<const __m128i*>(input + i + 1));
      __m128i tmp = _mm_xor_si128(vecpre, vec);
      tmp = _mm_cmplt_epi16(tmp, ones);
      tmp = _mm_xor_si128(tmp, zerocheck);
      tmp = _mm_and_si128(tmp, ones);
      __m128i tmplo = _mm_unpacklo_epi16(tmp, zeros);
      __m128i tmphi = _mm_unpackhi_epi16(tmp, zeros);
      crossings = _mm_add_epi32(crossings, tmplo);
      crossings = _mm_add_epi32(crossings, tmphi);
    }
    crossings = _mm_hadd_epi32(crossings, crossings);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
    int res = _mm_extract_epi32(crossings, 0) + _mm_extract_epi32(crossings, 2);
#pragma GCC diagnostic pop
    int startIndex = ((ilength - 1) >> 3) << 3;
    int16_t valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#elif defined(__ARM_NEON__)
    uint32x4_t crossings = vdupq_n_u32(0);
    uint16x8_t ones = vdupq_n_u16(1);
    const int16x8_t zeros = vdupq_n_s16(0);
    for (int i = 0; i < ilength - 8; i += 8) {
      int16x8_t vecpre = vld1q_s16(input + i);
      uint16x8_t zerocheck =  vceqq_s16(vecpre, zeros);
      int16x8_t vec = vld1q_s16(input + i + 1);
      int16x8_t tmp = veorq_s16(vecpre, vec);
      uint16x8_t cmpres = vcleq_s16(tmp, zeros);
      cmpres = veorq_u16(cmpres, zerocheck);
      cmpres = vandq_u16(cmpres, ones);
      crossings = vpadalq_u16(crossings, cmpres);
    }
    uint64x2_t crossings64 = vpaddlq_u32(crossings);
    int res = vgetq_lane_u64(crossings64, 0) + vgetq_lane_u64(crossings64, 1);
    int startIndex = ((ilength - 1) >> 3) << 3;
    int16_t valpre = input[startIndex];
    for (int i = startIndex + 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  } else {
#else
  } {
#endif
    int res = 0;
    int16_t valpre = input[0];
    for (int i = 1; i < ilength; i++) {
      int16_t val = input[i];
      if (valpre * val < 0 || valpre == 0) {
        res++;
      }
      valpre = val;
    }
    if (valpre == 0) {
      res++;
    }
    return res;
  }
}

REGISTER_TRANSFORM(ZeroCrossingsF);
REGISTER_TRANSFORM(ZeroCrossings16);

}  // namespace transforms
}  // namespace sound_feature_extraction
<|endoftext|>