<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <vector>

#include "webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
#include "webrtc/modules/video_coding/main/interface/mock/mock_vcm_callbacks.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/tick_util.h"

#include "gtest/gtest.h"

using ::testing::_;
using ::testing::AllOf;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::NiceMock;
using ::testing::Pointee;
using ::testing::Return;

namespace webrtc {

class TestVideoCodingModule : public ::testing::Test {
 protected:
  static const int kDefaultWidth = 1280;
  static const int kDefaultHeight = 720;
  static const int kNumberOfStreams = 3;
  static const int kNumberOfLayers = 3;
  static const int kUnusedPayloadType = 10;

  virtual void SetUp() {
    TickTime::UseFakeClock(0);
    vcm_ = VideoCodingModule::Create(0);
    EXPECT_EQ(0, vcm_->InitializeReceiver());
    EXPECT_EQ(0, vcm_->InitializeSender());
    EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType,
                                               false));
    EXPECT_EQ(0, vcm_->RegisterExternalDecoder(&decoder_, kUnusedPayloadType,
                                               true));
    memset(&settings_, 0, sizeof(settings_));
    EXPECT_EQ(0, vcm_->Codec(kVideoCodecVP8, &settings_));
    settings_.numberOfSimulcastStreams = kNumberOfStreams;
    ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, 100,
                    &settings_.simulcastStream[0]);
    ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, 500,
                    &settings_.simulcastStream[1]);
    ConfigureStream(kDefaultWidth, kDefaultHeight, 1200,
                    &settings_.simulcastStream[2]);
    settings_.plType = kUnusedPayloadType;  // Use the mocked encoder.
    EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200));
    EXPECT_EQ(0, vcm_->RegisterReceiveCodec(&settings_, 1, true));
  }

  virtual void TearDown() {
    VideoCodingModule::Destroy(vcm_);
  }

  void ExpectIntraRequest(int stream) {
    if (stream == -1) {
      // No intra request expected.
      EXPECT_CALL(encoder_, Encode(
          _, _, Pointee(ElementsAre(kDeltaFrame, kDeltaFrame, kDeltaFrame))))
          .Times(1)
          .WillRepeatedly(Return(0));
      return;
    }
    assert(stream >= 0);
    assert(stream < kNumberOfStreams);
    std::vector<VideoFrameType> frame_types(kNumberOfStreams, kDeltaFrame);
    frame_types[stream] = kKeyFrame;
    EXPECT_CALL(encoder_, Encode(
        _, _, Pointee(ElementsAreArray(&frame_types[0], frame_types.size()))))
        .Times(1)
        .WillRepeatedly(Return(0));
  }

  static void ConfigureStream(int width, int height, int max_bitrate,
                              SimulcastStream* stream) {
    assert(stream);
    stream->width = width;
    stream->height = height;
    stream->maxBitrate = max_bitrate;
    stream->numberOfTemporalLayers = kNumberOfLayers;
    stream->qpMax = 45;
  }

  void InsertAndVerifyPaddingFrame(const uint8_t* payload, int length,
                                   WebRtcRTPHeader* header) {
    ASSERT_TRUE(header != NULL);
    for (int j = 0; j < 5; ++j) {
      // Padding only packets are passed to the VCM with payload size 0.
      EXPECT_EQ(0, vcm_->IncomingPacket(payload, 0, *header));
      ++header->header.sequenceNumber;
    }
    EXPECT_CALL(packet_request_callback_, ResendPackets(_, _))
        .Times(0);
    EXPECT_EQ(0, vcm_->Process());
    EXPECT_CALL(decoder_, Decode(_, _, _, _, _))
        .Times(0);
    EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
  }

  void InsertAndVerifyDecodableFrame(const uint8_t* payload, int length,
                                     WebRtcRTPHeader* header) {
    ASSERT_TRUE(header != NULL);
    EXPECT_EQ(0, vcm_->IncomingPacket(payload, length, *header));
    ++header->header.sequenceNumber;
    EXPECT_CALL(packet_request_callback_, ResendPackets(_, _))
        .Times(0);
    EXPECT_EQ(0, vcm_->Process());
    EXPECT_CALL(decoder_, Decode(_, _, _, _, _))
        .Times(1);
    EXPECT_EQ(0, vcm_->Decode(0));
  }

  VideoCodingModule* vcm_;
  NiceMock<MockVideoDecoder> decoder_;
  NiceMock<MockVideoEncoder> encoder_;
  I420VideoFrame input_frame_;
  VideoCodec settings_;
  NiceMock<MockPacketRequestCallback> packet_request_callback_;
};

TEST_F(TestVideoCodingModule, TestIntraRequests) {
  EXPECT_EQ(0, vcm_->IntraFrameRequest(0));
  ExpectIntraRequest(0);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(0, vcm_->IntraFrameRequest(1));
  ExpectIntraRequest(1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(0, vcm_->IntraFrameRequest(2));
  ExpectIntraRequest(2);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(-1, vcm_->IntraFrameRequest(3));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
}

TEST_F(TestVideoCodingModule, TestIntraRequestsInternalCapture) {
  // De-register current external encoder.
  EXPECT_EQ(0, vcm_->RegisterExternalEncoder(NULL, kUnusedPayloadType, false));
  // Register encoder with internal capture.
  EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType,
                                             true));
  EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200));
  ExpectIntraRequest(0);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(0));
  ExpectIntraRequest(1);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(1));
  ExpectIntraRequest(2);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(2));
  // No requests expected since these indices are out of bounds.
  EXPECT_EQ(-1, vcm_->IntraFrameRequest(3));
  EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1));
}

TEST_F(TestVideoCodingModule, PaddingOnlyFrames) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kPaddingSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  for (int i = 0; i < 10; ++i) {
    InsertAndVerifyPaddingFrame(payload, 0, &header);
    TickTime::AdvanceFakeClock(33);
    header.header.timestamp += 3000;
  }
}

TEST_F(TestVideoCodingModule, PaddingOnlyFramesWithLosses) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kFrameSize = 1200;
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kPaddingSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  // Insert one video frame to get one frame decoded.
  header.frameType = kVideoFrameKey;
  header.type.Video.isFirstPacket = true;
  header.header.markerBit = true;
  InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
  TickTime::AdvanceFakeClock(33);
  header.header.timestamp += 3000;

  header.frameType = kFrameEmpty;
  header.type.Video.isFirstPacket = false;
  header.header.markerBit = false;
  // Insert padding frames.
  for (int i = 0; i < 10; ++i) {
    // Lose the 4th frame.
    if (i == 3) {
      header.header.sequenceNumber += 5;
      ++i;
    }
    // Lose one packet from the 6th frame.
    if (i == 5) {
      ++header.header.sequenceNumber;
    }
    InsertAndVerifyPaddingFrame(payload, 0, &header);
    TickTime::AdvanceFakeClock(33);
    header.header.timestamp += 3000;
  }
}

TEST_F(TestVideoCodingModule, PaddingOnlyAndVideo) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kFrameSize = 1200;
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kPaddingSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.type.Video.isFirstPacket = false;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  header.type.Video.codecHeader.VP8.pictureId = -1;
  header.type.Video.codecHeader.VP8.tl0PicIdx = -1;
  for (int i = 0; i < 3; ++i) {
    // Insert 2 video frames.
    for (int j = 0; j < 2; ++j) {
      if (i == 0 && j == 0)  // First frame should be a key frame.
        header.frameType = kVideoFrameKey;
      else
        header.frameType = kVideoFrameDelta;
      header.type.Video.isFirstPacket = true;
      header.header.markerBit = true;
      InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
      TickTime::AdvanceFakeClock(33);
      header.header.timestamp += 3000;
    }

    // Insert 2 padding only frames.
    header.frameType = kFrameEmpty;
    header.type.Video.isFirstPacket = false;
    header.header.markerBit = false;
    for (int j = 0; j < 2; ++j) {
      InsertAndVerifyPaddingFrame(payload, 0, &header);
      TickTime::AdvanceFakeClock(33);
      header.header.timestamp += 3000;
    }
  }
}

}  // namespace webrtc
<commit_msg>Fix OOB read in padding tests.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <vector>

#include "webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
#include "webrtc/modules/video_coding/main/interface/mock/mock_vcm_callbacks.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/tick_util.h"

#include "gtest/gtest.h"

using ::testing::_;
using ::testing::AllOf;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::NiceMock;
using ::testing::Pointee;
using ::testing::Return;

namespace webrtc {

class TestVideoCodingModule : public ::testing::Test {
 protected:
  static const int kDefaultWidth = 1280;
  static const int kDefaultHeight = 720;
  static const int kNumberOfStreams = 3;
  static const int kNumberOfLayers = 3;
  static const int kUnusedPayloadType = 10;

  virtual void SetUp() {
    TickTime::UseFakeClock(0);
    vcm_ = VideoCodingModule::Create(0);
    EXPECT_EQ(0, vcm_->InitializeReceiver());
    EXPECT_EQ(0, vcm_->InitializeSender());
    EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType,
                                               false));
    EXPECT_EQ(0, vcm_->RegisterExternalDecoder(&decoder_, kUnusedPayloadType,
                                               true));
    memset(&settings_, 0, sizeof(settings_));
    EXPECT_EQ(0, vcm_->Codec(kVideoCodecVP8, &settings_));
    settings_.numberOfSimulcastStreams = kNumberOfStreams;
    ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, 100,
                    &settings_.simulcastStream[0]);
    ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, 500,
                    &settings_.simulcastStream[1]);
    ConfigureStream(kDefaultWidth, kDefaultHeight, 1200,
                    &settings_.simulcastStream[2]);
    settings_.plType = kUnusedPayloadType;  // Use the mocked encoder.
    EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200));
    EXPECT_EQ(0, vcm_->RegisterReceiveCodec(&settings_, 1, true));
  }

  virtual void TearDown() {
    VideoCodingModule::Destroy(vcm_);
  }

  void ExpectIntraRequest(int stream) {
    if (stream == -1) {
      // No intra request expected.
      EXPECT_CALL(encoder_, Encode(
          _, _, Pointee(ElementsAre(kDeltaFrame, kDeltaFrame, kDeltaFrame))))
          .Times(1)
          .WillRepeatedly(Return(0));
      return;
    }
    assert(stream >= 0);
    assert(stream < kNumberOfStreams);
    std::vector<VideoFrameType> frame_types(kNumberOfStreams, kDeltaFrame);
    frame_types[stream] = kKeyFrame;
    EXPECT_CALL(encoder_, Encode(
        _, _, Pointee(ElementsAreArray(&frame_types[0], frame_types.size()))))
        .Times(1)
        .WillRepeatedly(Return(0));
  }

  static void ConfigureStream(int width, int height, int max_bitrate,
                              SimulcastStream* stream) {
    assert(stream);
    stream->width = width;
    stream->height = height;
    stream->maxBitrate = max_bitrate;
    stream->numberOfTemporalLayers = kNumberOfLayers;
    stream->qpMax = 45;
  }

  void InsertAndVerifyPaddingFrame(const uint8_t* payload, int length,
                                   WebRtcRTPHeader* header) {
    ASSERT_TRUE(header != NULL);
    for (int j = 0; j < 5; ++j) {
      // Padding only packets are passed to the VCM with payload size 0.
      EXPECT_EQ(0, vcm_->IncomingPacket(payload, 0, *header));
      ++header->header.sequenceNumber;
    }
    EXPECT_CALL(packet_request_callback_, ResendPackets(_, _))
        .Times(0);
    EXPECT_EQ(0, vcm_->Process());
    EXPECT_CALL(decoder_, Decode(_, _, _, _, _))
        .Times(0);
    EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
  }

  void InsertAndVerifyDecodableFrame(const uint8_t* payload, int length,
                                     WebRtcRTPHeader* header) {
    ASSERT_TRUE(header != NULL);
    EXPECT_EQ(0, vcm_->IncomingPacket(payload, length, *header));
    ++header->header.sequenceNumber;
    EXPECT_CALL(packet_request_callback_, ResendPackets(_, _))
        .Times(0);
    EXPECT_EQ(0, vcm_->Process());
    EXPECT_CALL(decoder_, Decode(_, _, _, _, _))
        .Times(1);
    EXPECT_EQ(0, vcm_->Decode(0));
  }

  VideoCodingModule* vcm_;
  NiceMock<MockVideoDecoder> decoder_;
  NiceMock<MockVideoEncoder> encoder_;
  I420VideoFrame input_frame_;
  VideoCodec settings_;
  NiceMock<MockPacketRequestCallback> packet_request_callback_;
};

TEST_F(TestVideoCodingModule, TestIntraRequests) {
  EXPECT_EQ(0, vcm_->IntraFrameRequest(0));
  ExpectIntraRequest(0);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(0, vcm_->IntraFrameRequest(1));
  ExpectIntraRequest(1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(0, vcm_->IntraFrameRequest(2));
  ExpectIntraRequest(2);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(-1, vcm_->IntraFrameRequest(3));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));

  EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1));
  ExpectIntraRequest(-1);
  EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
}

TEST_F(TestVideoCodingModule, TestIntraRequestsInternalCapture) {
  // De-register current external encoder.
  EXPECT_EQ(0, vcm_->RegisterExternalEncoder(NULL, kUnusedPayloadType, false));
  // Register encoder with internal capture.
  EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType,
                                             true));
  EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200));
  ExpectIntraRequest(0);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(0));
  ExpectIntraRequest(1);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(1));
  ExpectIntraRequest(2);
  EXPECT_EQ(0, vcm_->IntraFrameRequest(2));
  // No requests expected since these indices are out of bounds.
  EXPECT_EQ(-1, vcm_->IntraFrameRequest(3));
  EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1));
}

TEST_F(TestVideoCodingModule, PaddingOnlyFrames) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kPaddingSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  for (int i = 0; i < 10; ++i) {
    InsertAndVerifyPaddingFrame(payload, 0, &header);
    TickTime::AdvanceFakeClock(33);
    header.header.timestamp += 3000;
  }
}

TEST_F(TestVideoCodingModule, PaddingOnlyFramesWithLosses) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kFrameSize = 1200;
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kFrameSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  // Insert one video frame to get one frame decoded.
  header.frameType = kVideoFrameKey;
  header.type.Video.isFirstPacket = true;
  header.header.markerBit = true;
  InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
  TickTime::AdvanceFakeClock(33);
  header.header.timestamp += 3000;

  header.frameType = kFrameEmpty;
  header.type.Video.isFirstPacket = false;
  header.header.markerBit = false;
  // Insert padding frames.
  for (int i = 0; i < 10; ++i) {
    // Lose the 4th frame.
    if (i == 3) {
      header.header.sequenceNumber += 5;
      ++i;
    }
    // Lose one packet from the 6th frame.
    if (i == 5) {
      ++header.header.sequenceNumber;
    }
    InsertAndVerifyPaddingFrame(payload, 0, &header);
    TickTime::AdvanceFakeClock(33);
    header.header.timestamp += 3000;
  }
}

TEST_F(TestVideoCodingModule, PaddingOnlyAndVideo) {
  EXPECT_EQ(0, vcm_->SetVideoProtection(kProtectionNack, true));
  EXPECT_EQ(0, vcm_->RegisterPacketRequestCallback(&packet_request_callback_));
  const unsigned int kFrameSize = 1200;
  const unsigned int kPaddingSize = 220;
  const uint8_t payload[kFrameSize] = {0};
  WebRtcRTPHeader header;
  memset(&header, 0, sizeof(header));
  header.frameType = kFrameEmpty;
  header.type.Video.isFirstPacket = false;
  header.header.markerBit = false;
  header.header.paddingLength = kPaddingSize;
  header.header.payloadType = kUnusedPayloadType;
  header.header.ssrc = 1;
  header.header.headerLength = 12;
  header.type.Video.codec = kRTPVideoVP8;
  header.type.Video.codecHeader.VP8.pictureId = -1;
  header.type.Video.codecHeader.VP8.tl0PicIdx = -1;
  for (int i = 0; i < 3; ++i) {
    // Insert 2 video frames.
    for (int j = 0; j < 2; ++j) {
      if (i == 0 && j == 0)  // First frame should be a key frame.
        header.frameType = kVideoFrameKey;
      else
        header.frameType = kVideoFrameDelta;
      header.type.Video.isFirstPacket = true;
      header.header.markerBit = true;
      InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
      TickTime::AdvanceFakeClock(33);
      header.header.timestamp += 3000;
    }

    // Insert 2 padding only frames.
    header.frameType = kFrameEmpty;
    header.type.Video.isFirstPacket = false;
    header.header.markerBit = false;
    for (int j = 0; j < 2; ++j) {
      InsertAndVerifyPaddingFrame(payload, 0, &header);
      TickTime::AdvanceFakeClock(33);
      header.header.timestamp += 3000;
    }
  }
}

}  // namespace webrtc
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or1 FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

#include <Eigen/Core>

using namespace Eigen;

template <typename Scalar, int Storage>
void run_matrix_tests()
{
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;
  typedef MatrixType::Index Index;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50,50);
  m.conservativeResize(1,50);
  VERIFY_IS_APPROX(m, n.block(0,0,1,50));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,1);
  VERIFY_IS_APPROX(m, n.block(0,0,50,1));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,50);
  VERIFY_IS_APPROX(m, n.block(0,0,50,50));

  // random shrinking ...
  for (int i=0; i<25; ++i)
  {
    const Index rows = ei_random<Index>(1,50);
    const Index cols = ei_random<Index>(1,50);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols);
    VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));
  }

  // random growing with zeroing ...
  for (int i=0; i<25; ++i)
  {
    const Index rows = ei_random<Index>(50,75);
    const Index cols = ei_random<Index>(50,75);
    m = n = MatrixType::Random(50,50);
    m.conservativeResizeLike(MatrixType::Zero(rows,cols));
    VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
    VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
    VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
  }
}

template <typename Scalar>
void run_vector_tests()
{
  typedef Matrix<Scalar, 1, Eigen::Dynamic> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50);
  m.conservativeResize(1);
  VERIFY_IS_APPROX(m, n.segment(0,1));

  m = n = MatrixType::Random(50);
  m.conservativeResize(50);
  VERIFY_IS_APPROX(m, n.segment(0,50));

  // random shrinking ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(1,50);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size);
    VERIFY_IS_APPROX(m, n.segment(0,size));
  }

  // random growing with zeroing ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(50,100);
    m = n = MatrixType::Random(50);
    m.conservativeResizeLike(MatrixType::Zero(size));
    VERIFY_IS_APPROX(m.segment(0,50), n);
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
  }
}

void test_conservative_resize()
{
  CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor>()));
  CALL_SUBTEST_1((run_matrix_tests<int, Eigen::ColMajor>()));
  CALL_SUBTEST_2((run_matrix_tests<float, Eigen::RowMajor>()));
  CALL_SUBTEST_2((run_matrix_tests<float, Eigen::ColMajor>()));
  CALL_SUBTEST_3((run_matrix_tests<double, Eigen::RowMajor>()));
  CALL_SUBTEST_3((run_matrix_tests<double, Eigen::ColMajor>()));
  CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::RowMajor>()));
  CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::ColMajor>()));
  CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::RowMajor>()));
  CALL_SUBTEST_6((run_matrix_tests<std::complex<double>, Eigen::ColMajor>()));

  CALL_SUBTEST_1((run_vector_tests<int>()));
  CALL_SUBTEST_2((run_vector_tests<float>()));
  CALL_SUBTEST_3((run_vector_tests<double>()));
  CALL_SUBTEST_4((run_vector_tests<std::complex<float> >()));
  CALL_SUBTEST_5((run_vector_tests<std::complex<double> >()));
}
<commit_msg>Added missing typename.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or1 FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

#include <Eigen/Core>

using namespace Eigen;

template <typename Scalar, int Storage>
void run_matrix_tests()
{
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;
  typedef typename MatrixType::Index Index;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50,50);
  m.conservativeResize(1,50);
  VERIFY_IS_APPROX(m, n.block(0,0,1,50));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,1);
  VERIFY_IS_APPROX(m, n.block(0,0,50,1));

  m = n = MatrixType::Random(50,50);
  m.conservativeResize(50,50);
  VERIFY_IS_APPROX(m, n.block(0,0,50,50));

  // random shrinking ...
  for (int i=0; i<25; ++i)
  {
    const Index rows = ei_random<Index>(1,50);
    const Index cols = ei_random<Index>(1,50);
    m = n = MatrixType::Random(50,50);
    m.conservativeResize(rows,cols);
    VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));
  }

  // random growing with zeroing ...
  for (int i=0; i<25; ++i)
  {
    const Index rows = ei_random<Index>(50,75);
    const Index cols = ei_random<Index>(50,75);
    m = n = MatrixType::Random(50,50);
    m.conservativeResizeLike(MatrixType::Zero(rows,cols));
    VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);
    VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );
    VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );
  }
}

template <typename Scalar>
void run_vector_tests()
{
  typedef Matrix<Scalar, 1, Eigen::Dynamic> MatrixType;

  MatrixType m, n;

  // boundary cases ...
  m = n = MatrixType::Random(50);
  m.conservativeResize(1);
  VERIFY_IS_APPROX(m, n.segment(0,1));

  m = n = MatrixType::Random(50);
  m.conservativeResize(50);
  VERIFY_IS_APPROX(m, n.segment(0,50));

  // random shrinking ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(1,50);
    m = n = MatrixType::Random(50);
    m.conservativeResize(size);
    VERIFY_IS_APPROX(m, n.segment(0,size));
  }

  // random growing with zeroing ...
  for (int i=0; i<50; ++i)
  {
    const int size = ei_random<int>(50,100);
    m = n = MatrixType::Random(50);
    m.conservativeResizeLike(MatrixType::Zero(size));
    VERIFY_IS_APPROX(m.segment(0,50), n);
    VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );
  }
}

void test_conservative_resize()
{
  CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor>()));
  CALL_SUBTEST_1((run_matrix_tests<int, Eigen::ColMajor>()));
  CALL_SUBTEST_2((run_matrix_tests<float, Eigen::RowMajor>()));
  CALL_SUBTEST_2((run_matrix_tests<float, Eigen::ColMajor>()));
  CALL_SUBTEST_3((run_matrix_tests<double, Eigen::RowMajor>()));
  CALL_SUBTEST_3((run_matrix_tests<double, Eigen::ColMajor>()));
  CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::RowMajor>()));
  CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::ColMajor>()));
  CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::RowMajor>()));
  CALL_SUBTEST_6((run_matrix_tests<std::complex<double>, Eigen::ColMajor>()));

  CALL_SUBTEST_1((run_vector_tests<int>()));
  CALL_SUBTEST_2((run_vector_tests<float>()));
  CALL_SUBTEST_3((run_vector_tests<double>()));
  CALL_SUBTEST_4((run_vector_tests<std::complex<float> >()));
  CALL_SUBTEST_5((run_vector_tests<std::complex<double> >()));
}
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2017 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetUserTask.cpp
 */

#include "./JPetUserTask.h"
#include "../JPetData/JPetData.h"

JPetUserTask::JPetUserTask(const char* name):
  JPetTask(name)
{
}

bool JPetUserTask::init(const JPetParamsInterface& inOptions)
{
  fParams = dynamic_cast<const JPetParams&>(inOptions);
  return init(); /// virtual function must be defined in the descendent class
}

bool JPetUserTask::run(const JPetDataInterface& inData)
{
  auto event = dynamic_cast<const JPetData&>(inData);
  setEvent(&(event.getEvent()));
  return exec();
}

bool JPetUserTask::terminate(JPetParamsInterface& outOptions)
{
  outOptions = fParams;
  return terminate(); /// virtual function must be defined in the descendent class
}

const JPetParamBank& JPetUserTask::getParamBank()
{
  DEBUG("JPetTask");
  auto paramManager = fParams.getParamManager();
  assert(paramManager);
  return paramManager->getParamBank();
}

void JPetUserTask::setStatistics(std::unique_ptr<JPetStatistics> statistics)
{
  fStatistics = std::move(statistics);
}

JPetStatistics& JPetUserTask::getStatistics()
{
  assert(fStatistics);
  return *fStatistics;
}

void JPetUserTask::setEvent(TObject* ev)
{
  fEvent = ev;
}
<commit_msg>Correct small comment in JPetTaskUser<commit_after>/**
 *  @copyright Copyright 2017 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetUserTask.cpp
 */

#include "./JPetUserTask.h"
#include "../JPetData/JPetData.h"

JPetUserTask::JPetUserTask(const char* name):
  JPetTask(name)
{
}

bool JPetUserTask::init(const JPetParamsInterface& inOptions)
{
  fParams = dynamic_cast<const JPetParams&>(inOptions);
  return init(); /// virtual function must be defined in the descendent class
}

bool JPetUserTask::run(const JPetDataInterface& inData)
{
  auto event = dynamic_cast<const JPetData&>(inData);
  setEvent(&(event.getEvent()));
  return exec();
}

bool JPetUserTask::terminate(JPetParamsInterface& outOptions)
{
  outOptions = fParams;
  return terminate(); /// virtual function must be defined in the descendent class
}

const JPetParamBank& JPetUserTask::getParamBank()
{
  DEBUG("JPetUserTask");
  auto paramManager = fParams.getParamManager();
  assert(paramManager);
  return paramManager->getParamBank();
}

void JPetUserTask::setStatistics(std::unique_ptr<JPetStatistics> statistics)
{
  fStatistics = std::move(statistics);
}

JPetStatistics& JPetUserTask::getStatistics()
{
  assert(fStatistics);
  return *fStatistics;
}

void JPetUserTask::setEvent(TObject* ev)
{
  fEvent = ev;
}
<|endoftext|>


<commit_before>/*
 * Presence Model - A model of settable presences.
 *
 * Copyright (C) 2016 James D. Smith <smithjd15@gmail.com>
 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "presence-model.h"

#include <QString>
#include <QFont>
#include <QFontDatabase>
#include <QIcon>
#include <QtDBus/QtDBus>

#include <KSharedConfig>
#include <KLocalizedString>
#include <KConfig>
#include <KConfigGroup>

#include "types.h"
#include "debug.h"

namespace KTp
{

struct PresenceModelGreaterThan : public std::function<bool(KTp::Presence,KTp::Presence)>
{
    inline bool operator()(const KTp::Presence& presence, const KTp::Presence& other)
    {
        if (KTp::Presence::sortPriority(presence.type()) < KTp::Presence::sortPriority(other.type())) {
            return true;
        } else if (KTp::Presence::sortPriority(presence.type()) == KTp::Presence::sortPriority(other.type())) {
            return (presence.statusMessage() < other.statusMessage());
        } else {
            return false;
        }
    }
};

PresenceModel::PresenceModel(QObject *parent) :
    QAbstractListModel(parent)
{
    Tp::registerTypes();

    loadPresences();

    QDBusConnection::sessionBus().connect(QString(), QLatin1String("/Telepathy"),
                                              QLatin1String("org.kde.Telepathy"),
                                              QLatin1String("presenceModelChanged"),
                                              this,
                                              SLOT(propagationChange(QVariantList)));
}

PresenceModel::~PresenceModel()
{
}

void PresenceModel::syncCustomPresencesToDisk()
{
    m_presenceGroup.deleteGroup();

    Q_FOREACH (const KTp::Presence &presence, m_presences) {
        if (!presence.statusMessage().isEmpty()) {
            QVariantList presenceVariant;
            presenceVariant.append(presence.type());
            presenceVariant.append(presence.statusMessage());
            QString id = QString::number(presence.type()).append(presence.statusMessage());
            m_presenceGroup.writeEntry(id, presenceVariant);
        }
    }
    m_presenceGroup.sync();
}

void PresenceModel::propagationChange(const QVariantList modelChange)
{
    KTp::Presence presence = KTp::Presence(qdbus_cast<Tp::SimplePresence>(modelChange.value(0)));
    bool presenceAdded = qdbus_cast<bool>(modelChange.value(1));

    if (!presence.isValid()) {
        return;
    }

    if (presenceAdded != m_presences.contains(presence)) {
        modifyModel(presence);
    }
}

QVariant PresenceModel::data(int index) const
{
    if (index < 0 || index >= m_presences.size()) {
        qCDebug(KTP_MODELS) << "invalid index data requested" << index;
        return QVariant();
    }

    return QVariant::fromValue<KTp::Presence>(m_presences[index]);
}

QVariant PresenceModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        qCDebug(KTP_MODELS) << "invalid index data requested" << index;
        return QVariant();
    }

    KTp::Presence presence = m_presences[index.row()];
    switch (role) {
    case Qt::DisplayRole:
        if (presence.statusMessage().isEmpty()) {
            return presence.displayString();
        } else {
            return presence.statusMessage();
        }

    case Qt::DecorationRole:
        return presence.icon();

    case Qt::FontRole:
        if (presence.statusMessage().isEmpty()) {
            QFont font = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
            font.setBold(true);
            return font;
        } else {
            return QVariant();
        }

    case PresenceRole:
        return QVariant::fromValue<KTp::Presence>(presence);

    case IconNameRole:
        return presence.iconName();
    }

    return QVariant();
}

int PresenceModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_presences.size();
}

void PresenceModel::loadPresences()
{
    KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("ktelepathyrc"));
    config->reparseConfiguration();
    m_presenceGroup = config->group("Custom Presence List");
    m_presences.clear();
    loadDefaultPresences();
    loadCustomPresences();
}

void PresenceModel::loadDefaultPresences()
{
    modifyModel(KTp::Presence::available());
    modifyModel(KTp::Presence::busy());
    modifyModel(KTp::Presence::away());
    modifyModel(KTp::Presence::xa());
    modifyModel(KTp::Presence::hidden());
    modifyModel(KTp::Presence::offline());
}

void PresenceModel::loadCustomPresences()
{
    Q_FOREACH (const QString &key, m_presenceGroup.keyList()) {
        QVariantList entry = m_presenceGroup.readEntry(key, QVariantList());

        QString statusMessage = entry.last().toString();

        switch (entry.first().toInt()) {
        case Tp::ConnectionPresenceTypeAvailable:
            modifyModel(KTp::Presence::available(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeAway:
            modifyModel(KTp::Presence::away(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeBusy:
            modifyModel(KTp::Presence::busy(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeExtendedAway:
            modifyModel(KTp::Presence::xa(statusMessage));
        }
    }
}

void PresenceModel::modifyModel(const KTp::Presence &presence)
{
    if (m_presences.contains(presence)) {
        int row = m_presences.indexOf(presence);
        beginRemoveRows(QModelIndex(), row, row);
        endRemoveRows();

        m_presences.removeOne(presence);
    } else {
        m_presences.append(presence);

        // Identical presence types with status messages are compared with the
        // status messages in ascending order.
        std::sort(m_presences.begin(), m_presences.end(), PresenceModelGreaterThan());

        int index = m_presences.indexOf(presence);

        beginInsertRows(QModelIndex(), index, index);
        endInsertRows();
    }

    Q_EMIT countChanged();
}

QModelIndex PresenceModel::addPresence(const KTp::Presence &presence)
{
    if (!m_presences.contains(presence)) {
        modifyModel(presence);
        propagateChange(presence);
    }

    return createIndex(m_presences.indexOf(presence), 0);
}

void PresenceModel::removePresence(const KTp::Presence &presence)
{
    if (m_presences.contains(presence)) {
        modifyModel(presence);
        propagateChange(presence);
    }
}

void PresenceModel::propagateChange(const KTp::Presence &presence)
{
    QVariantList messageArgList;
    QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/Telepathy"),
                                                          QLatin1String("org.kde.Telepathy"),
                                                          QLatin1String("presenceModelChanged"));

    messageArgList << QVariant::fromValue<Tp::SimplePresence>(presence.barePresence());
    messageArgList << QVariant::fromValue<bool>(m_presences.contains(presence));
    message << messageArgList;

    if (!QDBusConnection::sessionBus().send(message)) {
        const QString &error = QDBusConnection::sessionBus().lastError().message();
        qCWarning(KTP_MODELS) << "presence model change propagation failed: " << error;
    }
}

QHash<int, QByteArray> PresenceModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
    roles.insert(PresenceRole, "presence");
    roles.insert(IconNameRole, "iconName");
    return roles;
}

QVariant PresenceModel::get(int row, const QByteArray& role) const
{
    //TODO: cache roles?
    QHash<int, QByteArray> roles = roleNames();
    return index(row, 0).data(roles.key(role));
}

}
<commit_msg>Include <functional> for std::function<commit_after>/*
 * Presence Model - A model of settable presences.
 *
 * Copyright (C) 2016 James D. Smith <smithjd15@gmail.com>
 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "presence-model.h"

#include <QString>
#include <QFont>
#include <QFontDatabase>
#include <QIcon>
#include <QtDBus/QtDBus>

#include <KSharedConfig>
#include <KLocalizedString>
#include <KConfig>
#include <KConfigGroup>

#include <functional>

#include "types.h"
#include "debug.h"

namespace KTp
{

struct PresenceModelGreaterThan : public std::function<bool(KTp::Presence,KTp::Presence)>
{
    inline bool operator()(const KTp::Presence& presence, const KTp::Presence& other)
    {
        if (KTp::Presence::sortPriority(presence.type()) < KTp::Presence::sortPriority(other.type())) {
            return true;
        } else if (KTp::Presence::sortPriority(presence.type()) == KTp::Presence::sortPriority(other.type())) {
            return (presence.statusMessage() < other.statusMessage());
        } else {
            return false;
        }
    }
};

PresenceModel::PresenceModel(QObject *parent) :
    QAbstractListModel(parent)
{
    Tp::registerTypes();

    loadPresences();

    QDBusConnection::sessionBus().connect(QString(), QLatin1String("/Telepathy"),
                                              QLatin1String("org.kde.Telepathy"),
                                              QLatin1String("presenceModelChanged"),
                                              this,
                                              SLOT(propagationChange(QVariantList)));
}

PresenceModel::~PresenceModel()
{
}

void PresenceModel::syncCustomPresencesToDisk()
{
    m_presenceGroup.deleteGroup();

    Q_FOREACH (const KTp::Presence &presence, m_presences) {
        if (!presence.statusMessage().isEmpty()) {
            QVariantList presenceVariant;
            presenceVariant.append(presence.type());
            presenceVariant.append(presence.statusMessage());
            QString id = QString::number(presence.type()).append(presence.statusMessage());
            m_presenceGroup.writeEntry(id, presenceVariant);
        }
    }
    m_presenceGroup.sync();
}

void PresenceModel::propagationChange(const QVariantList modelChange)
{
    KTp::Presence presence = KTp::Presence(qdbus_cast<Tp::SimplePresence>(modelChange.value(0)));
    bool presenceAdded = qdbus_cast<bool>(modelChange.value(1));

    if (!presence.isValid()) {
        return;
    }

    if (presenceAdded != m_presences.contains(presence)) {
        modifyModel(presence);
    }
}

QVariant PresenceModel::data(int index) const
{
    if (index < 0 || index >= m_presences.size()) {
        qCDebug(KTP_MODELS) << "invalid index data requested" << index;
        return QVariant();
    }

    return QVariant::fromValue<KTp::Presence>(m_presences[index]);
}

QVariant PresenceModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        qCDebug(KTP_MODELS) << "invalid index data requested" << index;
        return QVariant();
    }

    KTp::Presence presence = m_presences[index.row()];
    switch (role) {
    case Qt::DisplayRole:
        if (presence.statusMessage().isEmpty()) {
            return presence.displayString();
        } else {
            return presence.statusMessage();
        }

    case Qt::DecorationRole:
        return presence.icon();

    case Qt::FontRole:
        if (presence.statusMessage().isEmpty()) {
            QFont font = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
            font.setBold(true);
            return font;
        } else {
            return QVariant();
        }

    case PresenceRole:
        return QVariant::fromValue<KTp::Presence>(presence);

    case IconNameRole:
        return presence.iconName();
    }

    return QVariant();
}

int PresenceModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_presences.size();
}

void PresenceModel::loadPresences()
{
    KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("ktelepathyrc"));
    config->reparseConfiguration();
    m_presenceGroup = config->group("Custom Presence List");
    m_presences.clear();
    loadDefaultPresences();
    loadCustomPresences();
}

void PresenceModel::loadDefaultPresences()
{
    modifyModel(KTp::Presence::available());
    modifyModel(KTp::Presence::busy());
    modifyModel(KTp::Presence::away());
    modifyModel(KTp::Presence::xa());
    modifyModel(KTp::Presence::hidden());
    modifyModel(KTp::Presence::offline());
}

void PresenceModel::loadCustomPresences()
{
    Q_FOREACH (const QString &key, m_presenceGroup.keyList()) {
        QVariantList entry = m_presenceGroup.readEntry(key, QVariantList());

        QString statusMessage = entry.last().toString();

        switch (entry.first().toInt()) {
        case Tp::ConnectionPresenceTypeAvailable:
            modifyModel(KTp::Presence::available(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeAway:
            modifyModel(KTp::Presence::away(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeBusy:
            modifyModel(KTp::Presence::busy(statusMessage));
            break;
        case Tp::ConnectionPresenceTypeExtendedAway:
            modifyModel(KTp::Presence::xa(statusMessage));
        }
    }
}

void PresenceModel::modifyModel(const KTp::Presence &presence)
{
    if (m_presences.contains(presence)) {
        int row = m_presences.indexOf(presence);
        beginRemoveRows(QModelIndex(), row, row);
        endRemoveRows();

        m_presences.removeOne(presence);
    } else {
        m_presences.append(presence);

        // Identical presence types with status messages are compared with the
        // status messages in ascending order.
        std::sort(m_presences.begin(), m_presences.end(), PresenceModelGreaterThan());

        int index = m_presences.indexOf(presence);

        beginInsertRows(QModelIndex(), index, index);
        endInsertRows();
    }

    Q_EMIT countChanged();
}

QModelIndex PresenceModel::addPresence(const KTp::Presence &presence)
{
    if (!m_presences.contains(presence)) {
        modifyModel(presence);
        propagateChange(presence);
    }

    return createIndex(m_presences.indexOf(presence), 0);
}

void PresenceModel::removePresence(const KTp::Presence &presence)
{
    if (m_presences.contains(presence)) {
        modifyModel(presence);
        propagateChange(presence);
    }
}

void PresenceModel::propagateChange(const KTp::Presence &presence)
{
    QVariantList messageArgList;
    QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/Telepathy"),
                                                          QLatin1String("org.kde.Telepathy"),
                                                          QLatin1String("presenceModelChanged"));

    messageArgList << QVariant::fromValue<Tp::SimplePresence>(presence.barePresence());
    messageArgList << QVariant::fromValue<bool>(m_presences.contains(presence));
    message << messageArgList;

    if (!QDBusConnection::sessionBus().send(message)) {
        const QString &error = QDBusConnection::sessionBus().lastError().message();
        qCWarning(KTP_MODELS) << "presence model change propagation failed: " << error;
    }
}

QHash<int, QByteArray> PresenceModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
    roles.insert(PresenceRole, "presence");
    roles.insert(IconNameRole, "iconName");
    return roles;
}

QVariant PresenceModel::get(int row, const QByteArray& role) const
{
    //TODO: cache roles?
    QHash<int, QByteArray> roles = roleNames();
    return index(row, 0).data(roles.key(role));
}

}
<|endoftext|>


<commit_before>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "CrossTermBarrierFunctionMaterial.h"

template<>
InputParameters validParams<CrossTermBarrierFunctionMaterial>()
{
  InputParameters params = validParams<Material>();
  params.addParam<std::string>("function_name", "g", "actual name for g(eta_i)");
  MooseEnum h_order("SIMPLE=0", "SIMPLE");
  params.addParam<MooseEnum>("g_order", h_order, "Polynomial order of the switching function h(eta)");
  params.addRequiredCoupledVar("etas", "eta_i order parameters, one for each h");
  params.addRequiredParam<std::vector<Real> >("W_ij", "Terms controlling barrier height set W=1 in DerivativeMultiPhaseMaterial for these to apply");
  return params;
}

CrossTermBarrierFunctionMaterial::CrossTermBarrierFunctionMaterial(const InputParameters & parameters) :
    DerivativeMaterialInterface<Material>(parameters),
    _function_name(getParam<std::string>("function_name")),
    _g_order(getParam<MooseEnum>("g_order")),
    _W_ij(getParam<std::vector<Real> >("W_ij")),
    _num_eta(coupledComponents("etas")),
    _eta(_num_eta),
    _prop_g(declareProperty<Real>(_function_name)),
    _prop_dg(_num_eta),
    _prop_d2g(_num_eta)
{
  // if Vector W_ij is not the correct size to fill the matrix give error
  if (_num_eta * _num_eta != _W_ij.size())
    mooseError("Supply the number of etas squared for W_ij.");
  // if W_ij is not symmetric or if diagonal values are not zero, return error
  for (unsigned int i = 0; i < _num_eta; ++i)
    for (unsigned int j = 0; j < _num_eta; ++j)
    {
      if (_W_ij[_num_eta*i + j] != _W_ij[_num_eta*j + i])
        mooseError("Supply symmetric values for W_ij");
      if (_W_ij[_num_eta*i + i] != 0)
        mooseError("Set on-diagonal values of W_ij to zero");
    }

  // declare derivative properties, fetch eta values
  for (unsigned int i = 0; i < _num_eta; ++i)
  {
    const std::string & eta_name = getVar("etas", i)->name();
    _prop_dg[i]  = &declarePropertyDerivative<Real>(_function_name, eta_name);
    _prop_d2g[i] = &declarePropertyDerivative<Real>(_function_name, eta_name, eta_name);
    _eta[i] = &coupledValue("etas", i);
  }
}

void
CrossTermBarrierFunctionMaterial::computeQpProperties()
{
  // Initialize properties to zero before accumulating
  _prop_g[_qp] = 0.;
  for (unsigned int i = 0; i < _num_eta; ++i)
  {
    (*_prop_dg[i])[_qp] = 0.;
    (*_prop_d2g[i])[_qp] = 0.;
  }

  // Sum the components of our W_ij matrix to get constant used in our g function
  for (unsigned int i = 0; i < _num_eta; ++i)
    for (unsigned int j = 0; j < _num_eta; ++j)
    {
      switch (_g_order)
      {
        case 0: // SIMPLE
          _prop_g[_qp]         +=  _W_ij[_num_eta*i + j] * (*_eta[i])[_qp] * (*_eta[i])[_qp] * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          (*_prop_dg[i])[_qp]  +=  2 * _W_ij[_num_eta*i + j] * 2 * (*_eta[i])[_qp] * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          (*_prop_d2g[i])[_qp] +=  2 * _W_ij[_num_eta*i + j] * 2 * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          break;
      }
    }
}
<commit_msg>Redo loops (#5192)<commit_after>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/
#include "CrossTermBarrierFunctionMaterial.h"

template<>
InputParameters validParams<CrossTermBarrierFunctionMaterial>()
{
  InputParameters params = validParams<Material>();
  params.addParam<std::string>("function_name", "g", "actual name for g(eta_i)");
  MooseEnum h_order("SIMPLE=0", "SIMPLE");
  params.addParam<MooseEnum>("g_order", h_order, "Polynomial order of the switching function h(eta)");
  params.addRequiredCoupledVar("etas", "eta_i order parameters, one for each h");
  params.addRequiredParam<std::vector<Real> >("W_ij", "Terms controlling barrier height set W=1 in DerivativeMultiPhaseMaterial for these to apply");
  return params;
}

CrossTermBarrierFunctionMaterial::CrossTermBarrierFunctionMaterial(const InputParameters & parameters) :
    DerivativeMaterialInterface<Material>(parameters),
    _function_name(getParam<std::string>("function_name")),
    _g_order(getParam<MooseEnum>("g_order")),
    _W_ij(getParam<std::vector<Real> >("W_ij")),
    _num_eta(coupledComponents("etas")),
    _eta(_num_eta),
    _prop_g(declareProperty<Real>(_function_name)),
    _prop_dg(_num_eta),
    _prop_d2g(_num_eta)
{
  // if Vector W_ij is not the correct size to fill the matrix give error
  if (_num_eta * _num_eta != _W_ij.size())
    mooseError("Supply the number of etas squared for W_ij.");

  // if W_ij is not symmetric or if diagonal values are not zero, return error
  for (unsigned int i = 0; i < _num_eta; ++i)
  {
    if (_W_ij[_num_eta * i + i] != 0)
      mooseError("Set on-diagonal values of W_ij to zero");

    for (unsigned int j = i; j < _num_eta; ++j)
    {
      if (_W_ij[_num_eta * i + j] != _W_ij[_num_eta*j + i])
        mooseError("Supply symmetric values for W_ij");
    }
  }

  // declare derivative properties, fetch eta values
  for (unsigned int i = 0; i < _num_eta; ++i)
  {
    const std::string & eta_name = getVar("etas", i)->name();
    _prop_dg[i]  = &declarePropertyDerivative<Real>(_function_name, eta_name);
    _prop_d2g[i] = &declarePropertyDerivative<Real>(_function_name, eta_name, eta_name);
    _eta[i] = &coupledValue("etas", i);
  }
}

void
CrossTermBarrierFunctionMaterial::computeQpProperties()
{
  // Initialize properties to zero before accumulating
  _prop_g[_qp] = 0.;
  for (unsigned int i = 0; i < _num_eta; ++i)
  {
    (*_prop_dg[i])[_qp] = 0.;
    (*_prop_d2g[i])[_qp] = 0.;
  }

  // Sum the components of our W_ij matrix to get constant used in our g function
  for (unsigned int i = 0; i < _num_eta; ++i)
    for (unsigned int j = 0; j < _num_eta; ++j)
    {
      switch (_g_order)
      {
        case 0: // SIMPLE
          _prop_g[_qp]         +=  _W_ij[_num_eta*i + j] * (*_eta[i])[_qp] * (*_eta[i])[_qp] * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          (*_prop_dg[i])[_qp]  +=  2 * _W_ij[_num_eta*i + j] * 2 * (*_eta[i])[_qp] * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          (*_prop_d2g[i])[_qp] +=  2 * _W_ij[_num_eta*i + j] * 2 * (*_eta[j])[_qp] * (*_eta[j])[_qp];
          break;
      }
    }
}
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <iostream.h>
#include "heap.h"
#include "../../H/dbug.h"
#include "../rtdefs.h"

rtQueue::rtQueue()
{
  head=NULL;
  tail=NULL;
  size=0;
}

// Return the number of elements on the rtQueue

int rtQueue::getSize()
{
  return size;
}

// Return the starting sample chunk of the top Instrument

int rtQueue::nextChunk()
{
  return head->Inst->chunkstart;
}

// Push an element to end of the rtQueue

void rtQueue::push(Instrument *newInst)
{
  int i;
  long diff;
  rtQElt *newElt;  // create new rtQElt
  rtQElt *tempElt; // BGG: for queue insertion
  newElt = new rtQElt;
  newElt->Inst = newInst;
  newElt->next = NULL;
  newElt->prev = NULL;

  if (head == NULL)  // if first item on rtQueue
    head = tail = newElt;
  else if(tail->Inst->chunkstart <= newElt->Inst->chunkstart) {
    // append to the end of the rtQueue
    tail->next = newElt;
    newElt->prev = tail;
    tail = newElt;
  }
  else { // BGG: we have to insert this one
#ifdef DBUG
    cout << "rtQueue::push():  scanning ...\n";
    cout << "tail->Inst->chunkstart = " << tail->Inst->chunkstart << endl;
    cout << "newElt->Inst->chunkstart = " << newElt->Inst->chunkstart << endl;
    cout << "Queue size = " << size << endl;
#endif
    tempElt = tail;
    i = 1;
#ifdef DBUG
    cout << "STARTING SCAN\n";
#endif
    while((tempElt->Inst->chunkstart > newElt->Inst->chunkstart) && (tempElt->prev) && (i < size)){
      if (!tempElt->prev) { // BGG: we're at the head
	cout << "We're at the head\n";
	break;
      }
#ifdef DBUG
      cout << "i = " << i << endl;
      cout << "tempElt = " << tempElt << endl;
      cout << "head = " << head << endl;
      cout << "head->Inst->chunkstart = " << head->Inst->chunkstart << endl;
      cout << "tempElt->Inst->chunkstart = " << tempElt->Inst->chunkstart << endl;
      cout << "newElt->Inst->chunkstart = " << newElt->Inst->chunkstart << endl;
      diff = (newElt->Inst->chunkstart - tempElt->Inst->chunkstart);
      cout << "diff = " << diff << endl;
      cout << "tempElt->prev = " << tempElt->prev << endl;
#endif
      tempElt = tempElt->prev;
      i++;
    }
#ifdef DBUG
    cout << "DONE SCANNING\n";
    cout << "i = " << i << endl;
    cout << "tempElt = " << tempElt << endl;
    cout << "head = " << head << endl;
    cout << "head->Inst->chunkstart = " << head->Inst->chunkstart << endl;
    cout << "tempElt->Inst->chunkstart = " << tempElt->Inst->chunkstart << endl;
    cout << "newElt->Inst->chunkstart = " << newElt->Inst->chunkstart << endl;
    diff = (newElt->Inst->chunkstart - tempElt->Inst->chunkstart);
    cout << "diff = " << diff << endl;
    cout << "tempElt->prev = " << tempElt->prev << endl;

    if (diff > MAXBUF) {  // 128 was MAXBUF in my testing
      cerr << "SCHEDULING INCONSISTENCY!\n";
      cerr << "newElt->Inst->chunkstart = " << newElt->Inst->chunkstart << endl;
      cout << "tempElt->Inst->chunkstart = " << tempElt->Inst->chunkstart << endl;
      diff = (newElt->Inst->chunkstart - tempElt->Inst->chunkstart);
      cout << "diff = " << diff << endl;
      exit(1);
    }
#endif

    if ((tempElt->prev) && (i < size)) {  // BGG: "normal" insertion
#ifdef DBUG
      cout << "Normal insertion\n";
#endif
      newElt->next = tempElt->next;
      newElt->prev = tempElt;
      (tempElt->next)->prev = newElt;
      tempElt->next = newElt;
    }
    else { // BGG: put at the head
#ifdef DBUG
      cout << "Put it at the head\n";
#endif
      newElt->next = head;
      newElt->prev = NULL;
      // BGG:  I thought I would have to do the following line here,
      //	but experience shows that it dumps core and does bad things
      //		(tempElt->next)->prev = newElt;
      head = newElt;
    }
  }
  size++;
}

// Pop an element of the top of the rtQueue

Instrument *rtQueue::pop()
{
  rtQElt *tQelt;
  Instrument *retInst;
  tQelt = head;
  if (!head) {
    cerr << "ERROR: attempt to pop empty rtQueue\n";
    return NULL;
  }
  retInst = head->Inst;
  head = head->next;
  delete tQelt;
  size--;
  return retInst;

}

<commit_msg><commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <iostream.h>
#include "heap.h"
#include "../../H/dbug.h"
#include "../rtdefs.h"

rtQueue::rtQueue()
{
  head=NULL;
  tail=NULL;
  size=0;
}

// Return the number of elements on the rtQueue

int rtQueue::getSize()
{
  return size;
}

// Return the starting sample chunk of the top Instrument

int rtQueue::nextChunk()
{
  return head->chunkstart;
}

// Push an element to end of the rtQueue

void rtQueue::push(Instrument *newInst, unsigned long new_chunkstart)
{
  int i;
  long diff;
  rtQElt *newElt;  // create new rtQElt
  rtQElt *tempElt; // BGG: for queue insertion
  newElt = new rtQElt;
  newElt->Inst = newInst;
  newElt->chunkstart = new_chunkstart;
  newElt->next = NULL;
  newElt->prev = NULL;

  if (head == NULL)  // if first item on rtQueue
    head = tail = newElt;
  else if(tail->chunkstart <= newElt->chunkstart) {
    // append to the end of the rtQueue
    tail->next = newElt;
    newElt->prev = tail;
    tail = newElt;
  }
#ifdef QBUG
  else { // BGG: we have to insert this one
#ifdef DBUG
    cout << "rtQueue::push():  scanning ...\n";
    cout << "tail->chunkstart = " << tail->chunkstart << endl;
    cout << "newElt->chunkstart = " << newElt->chunkstart << endl;
    cout << "Queue size = " << size << endl;
#endif
    tempElt = tail;
    i = 1;
#ifdef DBUG
    cout << "STARTING SCAN\n";
#endif
    while((tempElt->chunkstart > newElt->chunkstart) && (tempElt->prev) && (i < size)){
      if (!tempElt->prev) { // BGG: we're at the head
	cout << "We're at the head\n";
	break;
      }
#ifdef DBUG
      cout << "i = " << i << endl;
      cout << "tempElt = " << tempElt << endl;
      cout << "head = " << head << endl;
      cout << "head->chunkstart = " << head->chunkstart << endl;
      cout << "tempElt->chunkstart = " << tempElt->chunkstart << endl;
      cout << "newElt->chunkstart = " << newElt->chunkstart << endl;
      diff = (newElt->chunkstart - tempElt->chunkstart);
      cout << "diff = " << diff << endl;
      cout << "tempElt->prev = " << tempElt->prev << endl;
#endif
      tempElt = tempElt->prev;
      i++;
    }
#ifdef DBUG
    cout << "DONE SCANNING\n";
    cout << "i = " << i << endl;
    cout << "tempElt = " << tempElt << endl;
    cout << "head = " << head << endl;
    cout << "head->chunkstart = " << head->chunkstart << endl;
    cout << "tempElt->chunkstart = " << tempElt->chunkstart << endl;
    cout << "newElt->chunkstart = " << newElt->chunkstart << endl;
    diff = (newElt->chunkstart - tempElt->chunkstart);
    cout << "diff = " << diff << endl;
    cout << "tempElt->prev = " << tempElt->prev << endl;

    if (diff > MAXBUF) {  // 128 was MAXBUF in my testing
      cerr << "SCHEDULING INCONSISTENCY!\n";
      cerr << "newElt->chunkstart = " << newElt->chunkstart << endl;
      cout << "tempElt->chunkstart = " << tempElt->chunkstart << endl;
      diff = (newElt->chunkstart - tempElt->chunkstart);
      cout << "diff = " << diff << endl;
      exit(1);
    }
#endif

    if ((tempElt->prev) && (i < size)) {  // BGG: "normal" insertion
#ifdef DBUG
      cout << "Normal insertion\n";
#endif
      newElt->next = tempElt->next;
      newElt->prev = tempElt;
      (tempElt->next)->prev = newElt;
      tempElt->next = newElt;
    }
    else { // BGG: put at the head
#ifdef DBUG
      cout << "Put it at the head\n";
#endif
      newElt->next = head;
      newElt->prev = NULL;
      // BGG:  I thought I would have to do the following line here,
      //	but experience shows that it dumps core and does bad things
      //		(tempElt->next)->prev = newElt;
      head = newElt;
    }
  }
#endif // QBUG
  size++;
}

// Pop an element of the top of the rtQueue

Instrument *rtQueue::pop()
{
  rtQElt *tQelt;
  Instrument *retInst;
  tQelt = head;
  if (!head) {
    cerr << "ERROR: attempt to pop empty rtQueue\n";
    return NULL;
  }
  retInst = head->Inst;
  head = head->next;
  delete tQelt;
  size--;
  return retInst;

}

<|endoftext|>


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

#include <QApplication>
#include <QTimer>

#include <boost/thread.hpp>
#include <boost/program_options.hpp>
#include <signal.h>

#include <OGRE/OgreHighLevelGpuProgramManager.h>
#include <OGRE/OgreLogManager.h>
#include <std_srvs/Empty.h>

#ifdef Q_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
// Apparently OSX #defines 'check' to be an empty string somewhere.
// That was fun to figure out.
#undef check
#endif

#include <ros/ros.h>

#include "visualization_frame.h"
#include "version.h"
#include "wait_for_master_dialog.h"
#include "visualizer_app.h"

namespace po = boost::program_options;

namespace rviz
{

bool reloadShaders(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
{
  Ogre::ResourceManager::ResourceMapIterator it = Ogre::HighLevelGpuProgramManager::getSingleton().getResourceIterator();
  while (it.hasMoreElements())
  {
    Ogre::ResourcePtr resource = it.getNext();
    resource->reload();
  }
  return true;
}

VisualizerApp::VisualizerApp()
  : timer_( 0 )
{
}

void VisualizerApp::onTimer()
{
  if( !continue_ )
  {
    QApplication::closeAllWindows();
  }
}

bool VisualizerApp::init( int argc, char** argv )
{
  ROS_INFO( "rviz revision number %s", get_version().c_str() );
  ROS_INFO( "compiled against OGRE version %d.%d.%d%s (%s)",
            OGRE_VERSION_MAJOR, OGRE_VERSION_MINOR, OGRE_VERSION_PATCH,
            OGRE_VERSION_SUFFIX, OGRE_VERSION_NAME );

#ifdef Q_OS_MAC
  ProcessSerialNumber PSN;
  GetCurrentProcess(&PSN);
  TransformProcessType(&PSN,kProcessTransformToForegroundApplication);
  SetFrontProcess(&PSN);
#endif

  try
  {
    ros::init( argc, argv, "rviz", ros::init_options::AnonymousName | ros::init_options::NoSigintHandler );

    po::options_description options;
    options.add_options()
      ("help,h", "Produce this help message")
      ("splash-screen,s", po::value<std::string>(), "A custom splash-screen image to display")
      ("display-config,d", po::value<std::string>(), "A display config file (.vcg) to load")
      ("target-frame,t", po::value<std::string>(), "Set the target frame")
      ("fixed-frame,f", po::value<std::string>(), "Set the fixed frame")
      ("ogre-log,l", "Enable the Ogre.log file (output in cwd)")
      ("in-mc-wrapper", "Signal that this is running inside a master-chooser wrapper")
      ("verbose,v", "Enable debug visualizations");
    po::variables_map vm;
    std::string display_config, target_frame, fixed_frame, splash_path;
    bool enable_ogre_log = false;
    bool in_mc_wrapper = false;
    bool verbose = false;
    try
    {
      po::store( po::parse_command_line( argc, argv, options ), vm );
      po::notify( vm );

      if( vm.count( "help" ))
      {
        std::cout << "rviz command line options:\n" << options;
        return false;
      }

      if( vm.count( "in-mc-wrapper" ))
      {
        in_mc_wrapper = true;
      }

      if (vm.count("display-config"))
      {
        display_config = vm["display-config"].as<std::string>();
      }

      if (vm.count("splash-screen"))
      {
        splash_path = vm["splash-screen"].as<std::string>();
      }

      if (vm.count("target-frame"))
      {
        target_frame = vm["target-frame"].as<std::string>();
      }

      if (vm.count("fixed-frame"))
      {
        fixed_frame = vm["fixed-frame"].as<std::string>();
      }

      if (vm.count("ogre-log"))
      {
        enable_ogre_log = true;
      }

      if (vm.count("verbose"))
      {
        verbose = true;
      }
    }
    catch (std::exception& e)
    {
      ROS_ERROR("Error parsing command line: %s", e.what());
      return false;
    }

    if( !ros::master::check() )
    {
      WaitForMasterDialog* dialog = new WaitForMasterDialog;
      if( dialog->exec() != QDialog::Accepted )
      {
        return false;
      }
    }

    // block kill signals on all threads, since this also disables signals in threads
    // created by this one (the main thread)
    sigset_t sig_set;
    sigemptyset(&sig_set);
    sigaddset(&sig_set, SIGKILL);
    sigaddset(&sig_set, SIGTERM);
    sigaddset(&sig_set, SIGQUIT);
    sigaddset(&sig_set, SIGINT);
    pthread_sigmask(SIG_BLOCK, &sig_set, NULL);

    // Start up our signal handler
    continue_ = true;
    signal_handler_thread_ = boost::thread(boost::bind(&VisualizerApp::signalHandler, this));

    nh_.reset( new ros::NodeHandle );

    Ogre::LogManager* log_manager = new Ogre::LogManager();
    log_manager->createLog( "Ogre.log", false, false, !enable_ogre_log );

    frame_ = new VisualizationFrame;
    frame_->initialize( display_config, fixed_frame, target_frame, splash_path, verbose, in_mc_wrapper );
    frame_->show();

    timer_ = new QTimer( this );
    connect( timer_, SIGNAL( timeout() ), this, SLOT( onTimer() ));
    timer_->start( 100 );

    ros::NodeHandle private_nh("~");
    reload_shaders_service_ = private_nh.advertiseService("reload_shaders", reloadShaders);
  }
  catch (std::exception& e)
  {
    ROS_ERROR("Caught exception while loading: %s", e.what());
    return false;
  }

  return true;
}

VisualizerApp::~VisualizerApp()
{
  if( timer_ )
  {
    timer_->stop();
  }
  continue_ = false;

  delete frame_;

  raise(SIGQUIT);

  signal_handler_thread_.join();
}

void VisualizerApp::signalHandler()
{
  sigset_t signal_set;
  while(continue_)
  {
    // Wait for any signals
    sigfillset(&signal_set);

#if defined(Q_OS_MAC)
    int sig;
    sigwait(&signal_set, &sig);
#else
    struct timespec ts = {0, 100000000};
    int sig = sigtimedwait(&signal_set, NULL, &ts);
#endif

    switch( sig )
    {
    case SIGKILL:
    case SIGTERM:
    case SIGQUIT:
    {
      exit(1);
    }
    break;

    case SIGINT:
    {
      ros::shutdown();
      continue_ = false;
      return;
    }
    break;

    default:
      break;
    }
  }
}

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

#include <QApplication>
#include <QTimer>

#include <boost/thread.hpp>
#include <boost/program_options.hpp>
#include <signal.h>

#include <OGRE/OgreHighLevelGpuProgramManager.h>
#include <OGRE/OgreLogManager.h>
#include <std_srvs/Empty.h>

#ifdef Q_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
// Apparently OSX #defines 'check' to be an empty string somewhere.
// That was fun to figure out.
#undef check
#endif

#include <ros/ros.h>

#include "visualization_frame.h"
#include "version.h"
#include "wait_for_master_dialog.h"
#include "visualizer_app.h"

#define CATCH_EXCEPTIONS 0

namespace po = boost::program_options;

namespace rviz
{

bool reloadShaders(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
{
  Ogre::ResourceManager::ResourceMapIterator it = Ogre::HighLevelGpuProgramManager::getSingleton().getResourceIterator();
  while (it.hasMoreElements())
  {
    Ogre::ResourcePtr resource = it.getNext();
    resource->reload();
  }
  return true;
}

VisualizerApp::VisualizerApp()
  : timer_( 0 )
  , frame_( 0 )
{
}

void VisualizerApp::onTimer()
{
  if( !continue_ )
  {
    QApplication::closeAllWindows();
  }
}

bool VisualizerApp::init( int argc, char** argv )
{
  ROS_INFO( "rviz revision number %s", get_version().c_str() );
  ROS_INFO( "compiled against OGRE version %d.%d.%d%s (%s)",
            OGRE_VERSION_MAJOR, OGRE_VERSION_MINOR, OGRE_VERSION_PATCH,
            OGRE_VERSION_SUFFIX, OGRE_VERSION_NAME );

#ifdef Q_OS_MAC
  ProcessSerialNumber PSN;
  GetCurrentProcess(&PSN);
  TransformProcessType(&PSN,kProcessTransformToForegroundApplication);
  SetFrontProcess(&PSN);
#endif

#if CATCH_EXCEPTIONS
  try
  {
#endif
    ros::init( argc, argv, "rviz", ros::init_options::AnonymousName | ros::init_options::NoSigintHandler );

    po::options_description options;
    options.add_options()
      ("help,h", "Produce this help message")
      ("splash-screen,s", po::value<std::string>(), "A custom splash-screen image to display")
      ("display-config,d", po::value<std::string>(), "A display config file (.vcg) to load")
      ("target-frame,t", po::value<std::string>(), "Set the target frame")
      ("fixed-frame,f", po::value<std::string>(), "Set the fixed frame")
      ("ogre-log,l", "Enable the Ogre.log file (output in cwd)")
      ("in-mc-wrapper", "Signal that this is running inside a master-chooser wrapper")
      ("verbose,v", "Enable debug visualizations");
    po::variables_map vm;
    std::string display_config, target_frame, fixed_frame, splash_path;
    bool enable_ogre_log = false;
    bool in_mc_wrapper = false;
    bool verbose = false;
    try
    {
      po::store( po::parse_command_line( argc, argv, options ), vm );
      po::notify( vm );

      if( vm.count( "help" ))
      {
        std::cout << "rviz command line options:\n" << options;
        return false;
      }

      if( vm.count( "in-mc-wrapper" ))
      {
        in_mc_wrapper = true;
      }

      if (vm.count("display-config"))
      {
        display_config = vm["display-config"].as<std::string>();
      }

      if (vm.count("splash-screen"))
      {
        splash_path = vm["splash-screen"].as<std::string>();
      }

      if (vm.count("target-frame"))
      {
        target_frame = vm["target-frame"].as<std::string>();
      }

      if (vm.count("fixed-frame"))
      {
        fixed_frame = vm["fixed-frame"].as<std::string>();
      }

      if (vm.count("ogre-log"))
      {
        enable_ogre_log = true;
      }

      if (vm.count("verbose"))
      {
        verbose = true;
      }
    }
    catch (std::exception& e)
    {
      ROS_ERROR("Error parsing command line: %s", e.what());
      return false;
    }

    if( !ros::master::check() )
    {
      WaitForMasterDialog* dialog = new WaitForMasterDialog;
      if( dialog->exec() != QDialog::Accepted )
      {
        return false;
      }
    }

    // block kill signals on all threads, since this also disables signals in threads
    // created by this one (the main thread)
    sigset_t sig_set;
    sigemptyset(&sig_set);
    sigaddset(&sig_set, SIGKILL);
    sigaddset(&sig_set, SIGTERM);
    sigaddset(&sig_set, SIGQUIT);
    sigaddset(&sig_set, SIGINT);
    pthread_sigmask(SIG_BLOCK, &sig_set, NULL);

    // Start up our signal handler
    continue_ = true;
    signal_handler_thread_ = boost::thread(boost::bind(&VisualizerApp::signalHandler, this));

    nh_.reset( new ros::NodeHandle );

    Ogre::LogManager* log_manager = new Ogre::LogManager();
    log_manager->createLog( "Ogre.log", false, false, !enable_ogre_log );

    frame_ = new VisualizationFrame;
    frame_->initialize( display_config, fixed_frame, target_frame, splash_path, verbose, in_mc_wrapper );
    frame_->show();

    timer_ = new QTimer( this );
    connect( timer_, SIGNAL( timeout() ), this, SLOT( onTimer() ));
    timer_->start( 100 );

    ros::NodeHandle private_nh("~");
    reload_shaders_service_ = private_nh.advertiseService("reload_shaders", reloadShaders);
#if CATCH_EXCEPTIONS
  }
  catch (std::exception& e)
  {
    ROS_ERROR("Caught exception while loading: %s", e.what());
    return false;
  }
#endif
  return true;
}

VisualizerApp::~VisualizerApp()
{
  if( timer_ )
  {
    timer_->stop();
  }
  continue_ = false;

  delete frame_;

  raise(SIGQUIT);

  signal_handler_thread_.join();
}

void VisualizerApp::signalHandler()
{
  sigset_t signal_set;
  while(continue_)
  {
    // Wait for any signals
    sigfillset(&signal_set);

#if defined(Q_OS_MAC)
    int sig;
    sigwait(&signal_set, &sig);
#else
    struct timespec ts = {0, 100000000};
    int sig = sigtimedwait(&signal_set, NULL, &ts);
#endif

    switch( sig )
    {
    case SIGKILL:
    case SIGTERM:
    case SIGQUIT:
    {
      exit(1);
    }
    break;

    case SIGINT:
    {
      ros::shutdown();
      continue_ = false;
      return;
    }
    break;

    default:
      break;
    }
  }
}

} // namespace rviz
<|endoftext|>


<commit_before>#include <Halide.h>
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("No gpu target enabled. Skipping test.\n");
        return 0;
    }

    Func f;
    Var x, y;

    ImageParam im(Int(32), 1);

    const int B = 16;
    const int N = 1024*16;
    Expr blocks = im.width() / B;

    f(x, y) = 0;

    f.compute_root().gpu_blocks(y).gpu_threads(x);

    // Sum-scan within each block of size B.
    RDom r1(0, B);
    f(r1, y) = im(y*B + r1) + f(r1-1, y);
    f.update(0).gpu_blocks(y);

    // Sum-scan along the last element of each block into a scratch space just before the start of each block.
    RDom r2(1, blocks-1);
    f(-1, r2) = f(B-1, r2-1) + f(-1, r2-1);
    RVar tmp;
    f.update(1).gpu_single_thread();

    // Add the last element of the previous block to everything in each row
    RDom r3(0, B);
    f(r3, y) += f(-1, y);
    f.update(2).gpu_blocks(y).gpu_threads(r3);

    // Read out the output
    Func out;
    out(x) = f(x % B, x / B);
    out.gpu_tile(x, B);

    // Only deal with inputs that are a multiple of B
    out.bound(x, 0, im.width()/B * B);

    Image<int> input = lambda(x, cast<int>(floor((sin(x))*100))).realize(N);

    im.set(input);
    Image<int> output = out.realize(N);

    int correct = 0;
    for (int i = 0; i < N; i++) {
        correct += input(i);
        if (output(i) != correct) {
            printf("output(%d) = %d instead of %d\n",
                   i, output(i), correct);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}
<commit_msg>Removed dead declaration.<commit_after>#include <Halide.h>
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("No gpu target enabled. Skipping test.\n");
        return 0;
    }

    Func f;
    Var x, y;

    ImageParam im(Int(32), 1);

    const int B = 16;
    const int N = 1024*16;
    Expr blocks = im.width() / B;

    f(x, y) = 0;

    f.compute_root().gpu_blocks(y).gpu_threads(x);

    // Sum-scan within each block of size B.
    RDom r1(0, B);
    f(r1, y) = im(y*B + r1) + f(r1-1, y);
    f.update(0).gpu_blocks(y);

    // Sum-scan along the last element of each block into a scratch space just before the start of each block.
    RDom r2(1, blocks-1);
    f(-1, r2) = f(B-1, r2-1) + f(-1, r2-1);
    f.update(1).gpu_single_thread();

    // Add the last element of the previous block to everything in each row
    RDom r3(0, B);
    f(r3, y) += f(-1, y);
    f.update(2).gpu_blocks(y).gpu_threads(r3);

    // Read out the output
    Func out;
    out(x) = f(x % B, x / B);
    out.gpu_tile(x, B);

    // Only deal with inputs that are a multiple of B
    out.bound(x, 0, im.width()/B * B);

    Image<int> input = lambda(x, cast<int>(floor((sin(x))*100))).realize(N);

    im.set(input);
    Image<int> output = out.realize(N);

    int correct = 0;
    for (int i = 0; i < N; i++) {
        correct += input(i);
        if (output(i) != correct) {
            printf("output(%d) = %d instead of %d\n",
                   i, output(i), correct);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include "Halide.h"

using namespace Halide;

int main(int argc, char **argv) {

    //int W = 64*3, H = 64*3;
    const int W = 128, H = 48;

    Image<uint16_t> in(W, H, 2);
    for (int c = 0; c < 2; c++) {
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                in(x, y, c) = rand() & 0xff;
            }
        }
    }

    Var x("x"), y("y");

    Func interleaved("interleaved");
    interleaved(x, y) = select(x%2 == 0, in(x, y, 0), in(x, y, 1));

    Target target = get_jit_target_from_environment();
    if (target.has_gpu_feature()) {
        interleaved.gpu_tile(x, y, 16, 16);
    } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
        interleaved.hexagon().vectorize(x, 32);
    } else {
        Var xo("xo"), yo("yo");
        interleaved.tile(x, y, xo, yo, x, y, 8, 8).vectorize(x);
    }

    Image<uint16_t> out = interleaved.realize(W, H, target);
    for (int y = 0; y < H; y++) {
        for (int x = 0; x < W; x++) {
            uint16_t correct = x%2 == 0 ? in(x, y, 0) : in(x, y, 1);
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n", x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");

    return 0;

}
<commit_msg>Simplified interleave_x test.<commit_after>#include <stdio.h>
#include "Halide.h"

using namespace Halide;

int main(int argc, char **argv) {

    Var x("x"), y("y");

    Func interleaved("interleaved");
    interleaved(x, y) = select(x%2 == 0, cast<uint16_t>(3), cast<uint16_t>(7));

    Target target = get_jit_target_from_environment();
    if (target.has_gpu_feature()) {
        interleaved.gpu_tile(x, y, 16, 16);
    } else if (target.features_any_of({Target::HVX_64, Target::HVX_128})) {
        interleaved.hexagon().vectorize(x, 32);
    } else {
        Var xo("xo"), yo("yo");
        interleaved.tile(x, y, xo, yo, x, y, 8, 8).vectorize(x);
    }

    Image<uint16_t> out = interleaved.realize(128, 128, target);
    for (int y = 0; y < out.height(); y++) {
        for (int x = 0; x < out.width(); x++) {
            uint16_t correct = x%2 == 0 ? 3 : 7;
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n", x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");

    return 0;

}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-4-21 10:41:20
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const int MAX_SIZE = 1000010;
bool isprime[MAX_SIZE];
vector<int> prime_num;

void init()
{
  fill(isprime, isprime + MAX_SIZE, true);
  isprime[0] = isprime[1] = false;
  for (auto i = 2; i < MAX_SIZE; i++)
  {
    if (isprime[i])
    {
      prime_num.push_back(i);
      for (auto j = 2; i * j < MAX_SIZE; j++)
      {
        isprime[i * j] = false;
      }
    }
  }
}

vector<long long> make_factors(long long x)
{ // 2 \leq x \leq MAX_SIZE^2
  vector<long long> ans;
  auto it = prime_num.begin();
  while (it != prime_num.end())
  {
    if (x == 1)
    {
      break;
    }
    if (x % *it == 0)
    {
      ans.push_back(*it);
      x /= *it;
    }
    else
    {
      it++;
    }
  }
  if (x != 1)
  {
    ans.push_back(x);
  }
  return ans;
}

ll N;
ll a[100010];
set<ll> S;
vector<ll> ans;

void make_primes()
{
  for (auto it = prime_num.begin(); it != prime_num.end(); it++)
  {
    if (*it < N)
    {
      S.insert(*it);
    }
    else
    {
      break;
    }
  }
  auto W = make_factors(a[N]);
  for (auto x : W)
  {
    S.insert(x);
  }
}

void flush()
{
  sort(ans.begin(), ans.end());
  for (auto x : ans)
  {
    cout << x << endl;
  }
}

void check_prime(ll p)
{
  vector<ll> A(p, 0);
  A[0] = a[0];
  for (auto i = 1; i <= N; i++)
  {
    ll t = i % (p - 1);
    if (t == 0)
    {
      t = p - 1;
    }
    A[t] += a[i];
  }
  bool ok = true;
  for (auto x : A)
  {
    if (x % p != 0)
    {
      ok = false;
      break;
    }
  }
  if (ok)
  {
    ans.push_back(p);
  }
}

int main()
{
  init();
  cin >> N;
  for (auto i = 0; i <= N; i++)
  {
    cin >> a[i];
  }
  reverse(a, a + N + 1);
  make_primes();
  for (auto x : S)
  {
    check_prime(x);
  }
  flush();
}<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-4-21 10:41:20
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(10101010));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const int MAX_SIZE = 1000010;
bool isprime[MAX_SIZE];
vector<int> prime_num;

void init()
{
  fill(isprime, isprime + MAX_SIZE, true);
  isprime[0] = isprime[1] = false;
  for (auto i = 2; i < MAX_SIZE; i++)
  {
    if (isprime[i])
    {
      prime_num.push_back(i);
      for (auto j = 2; i * j < MAX_SIZE; j++)
      {
        isprime[i * j] = false;
      }
    }
  }
}

vector<long long> make_factors(long long x)
{ // 2 \leq x \leq MAX_SIZE^2
  vector<long long> ans;
  auto it = prime_num.begin();
  while (it != prime_num.end())
  {
    if (x == 1)
    {
      break;
    }
    if (x % *it == 0)
    {
      ans.push_back(*it);
      x /= *it;
    }
    else
    {
      it++;
    }
  }
  if (x != 1)
  {
    ans.push_back(x);
  }
  return ans;
}

ll N;
ll a[100010];
set<ll> S;
vector<ll> ans;

void make_primes()
{
  for (auto it = prime_num.begin(); it != prime_num.end(); it++)
  {
    if (*it < N)
    {
      S.insert(*it);
#if DEBUG == 1
      cerr << "S.insert(" << *it << ")" << endl;
#endif
    }
    else
    {
      break;
    }
  }
  auto W = make_factors(a[N]);
  for (auto x : W)
  {
#if DEBUG == 1
    cerr << "W inclues " << x << endl;
#endif
    S.insert(x);
  }
}

void flush()
{
  sort(ans.begin(), ans.end());
  for (auto x : ans)
  {
    cout << x << endl;
  }
}

void check_prime(ll p)
{
  vector<ll> A(p, 0);
  A[0] = a[0];
  for (auto i = 1; i <= N; i++)
  {
    ll t = i % (p - 1);
    if (t == 0)
    {
      t = p - 1;
    }
    A[t] += a[i];
  }
  bool ok = true;
  for (auto x : A)
  {
    if (x % p != 0)
    {
      ok = false;
      break;
    }
  }
  if (ok)
  {
    ans.push_back(p);
  }
}

int main()
{
  init();
  cin >> N;
  for (auto i = 0; i <= N; i++)
  {
    cin >> a[i];
  }
  reverse(a, a + N + 1);
  make_primes();
  for (auto x : S)
  {
    check_prime(x);
  }
  flush();
}<|endoftext|>