<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/message_loop.h"
#include "chrome/browser/chromeos/cros/mock_network_library.h"
#include "chrome/browser/chromeos/cros/mock_update_library.h"
#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
#include "chrome/browser/chromeos/dbus/mock_session_manager_client.h"
#include "chrome/browser/chromeos/login/mock_screen_observer.h"
#include "chrome/browser/chromeos/login/update_screen.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::Invoke;

static void RequestUpdateCheckSuccess(UpdateCallback callback, void* userdata) {
  callback(userdata, chromeos::UPDATE_RESULT_SUCCESS, NULL);
}

class UpdateScreenTest : public WizardInProcessBrowserTest {
 public:
  UpdateScreenTest() : WizardInProcessBrowserTest("update"),
                       mock_session_manager_client_(NULL),
                       mock_update_library_(NULL),
                       mock_network_library_(NULL) {}

 protected:
  virtual void SetUpInProcessBrowserTestFixture() {
    DBusThreadManager::Initialize();
    WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
    cros_mock_->InitStatusAreaMocks();
    cros_mock_->SetStatusAreaMocksExpectations();
    ASSERT_TRUE(CrosLibrary::Get()->EnsureLoaded());

    mock_session_manager_client_ = new MockSessionManagerClient();
    DBusThreadManager::Get()->set_session_manager_client_for_testing(
        mock_session_manager_client_);
    EXPECT_CALL(*mock_session_manager_client_, EmitLoginPromptReady())
        .Times(1);

    mock_update_library_ = new MockUpdateLibrary();
    cros_mock_->test_api()->SetUpdateLibrary(mock_update_library_, true);

    // UpdateScreen::StartUpdate() will be called by the WizardController
    // just after creating the update screen, so the expectations for that
    // should be set up here.
    EXPECT_CALL(*mock_update_library_, AddObserver(_))
        .Times(1);
    EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
        .Times(AtLeast(1));
    EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
        .Times(1)
        .WillOnce(Invoke(RequestUpdateCheckSuccess));

    mock_network_library_ = cros_mock_->mock_network_library();
    EXPECT_CALL(*mock_network_library_, Connected())
        .Times(1)  // also called by NetworkMenu::InitMenuItems()
        .WillRepeatedly((Return(false)))
        .RetiresOnSaturation();
    EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*mock_network_library_, FindWifiDevice())
        .Times(AnyNumber());
    EXPECT_CALL(*mock_network_library_, FindEthernetDevice())
        .Times(AnyNumber());
  }

  virtual void SetUpOnMainThread() {
    mock_screen_observer_.reset(new MockScreenObserver());
    ASSERT_TRUE(controller() != NULL);
    update_screen_ = controller()->GetUpdateScreen();
    ASSERT_TRUE(update_screen_ != NULL);
    ASSERT_EQ(controller()->current_screen(), update_screen_);
    update_screen_->screen_observer_ = mock_screen_observer_.get();
  }

  virtual void TearDownInProcessBrowserTestFixture() {
    update_screen_->screen_observer_ = (controller());
    cros_mock_->test_api()->SetUpdateLibrary(NULL, true);
    WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
    DBusThreadManager::Shutdown();
  }

  MockSessionManagerClient* mock_session_manager_client_;
  MockUpdateLibrary* mock_update_library_;
  MockNetworkLibrary* mock_network_library_;

  scoped_ptr<MockScreenObserver> mock_screen_observer_;
  UpdateScreen* update_screen_;
  // DBusThreadManager needs a message loop.
  MessageLoopForUI message_loop_;

 private:
  DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest);
};

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) {
  ASSERT_TRUE(update_screen_->actor_ != NULL);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) {
  update_screen_->SetIgnoreIdleStatus(true);
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_IDLE;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(1)
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);
  status.status = UPDATE_STATUS_CHECKING_FOR_UPDATE;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(1)
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);
  status.status = UPDATE_STATUS_IDLE;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_, OnExit(ScreenObserver::UPDATE_NOUPDATE))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) {
  update_screen_->is_ignore_update_deadlines_ = true;

  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
  status.new_version = "latest and greatest";
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_DOWNLOADING;
  status.download_progress = 0.0;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.download_progress = 0.5;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.download_progress = 1.0;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_VERIFYING;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_FINALIZING;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_UPDATED_NEED_REBOOT;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_update_library_, RebootAfterUpdate())
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

static void RequestUpdateCheckFail(UpdateCallback callback, void* userdata) {
  callback(userdata, chromeos::UPDATE_RESULT_FAILED, NULL);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorIssuingUpdateCheck) {
  // First, cancel the update that is already in progress.
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_NOUPDATE))
      .Times(1);
  update_screen_->CancelUpdate();

  // Run UpdateScreen::StartUpdate() again, but CheckForUpdate() will fail
  // issuing the update check this time.
  EXPECT_CALL(*mock_update_library_, AddObserver(_))
      .Times(1);
  EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
      .Times(AtLeast(1));
  EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
      .Times(1)
      .WillOnce(Invoke(RequestUpdateCheckFail));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
      .Times(1);
  update_screen_->StartUpdate();
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorCheckingForUpdate) {
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_ERROR;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorUpdating) {
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
  status.new_version = "latest and greatest";
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_ERROR;
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_UPDATING))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

}  // namespace chromeos
<commit_msg>chromeos: Fix UpdateScreenTest.NoUpdate and TestUpdateAvailable<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/message_loop.h"
#include "chrome/browser/chromeos/cros/mock_network_library.h"
#include "chrome/browser/chromeos/cros/mock_update_library.h"
#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
#include "chrome/browser/chromeos/dbus/mock_session_manager_client.h"
#include "chrome/browser/chromeos/login/mock_screen_observer.h"
#include "chrome/browser/chromeos/login/update_screen.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::Invoke;

static void RequestUpdateCheckSuccess(UpdateCallback callback, void* userdata) {
  callback(userdata, chromeos::UPDATE_RESULT_SUCCESS, NULL);
}

class UpdateScreenTest : public WizardInProcessBrowserTest {
 public:
  UpdateScreenTest() : WizardInProcessBrowserTest("update"),
                       mock_session_manager_client_(NULL),
                       mock_update_library_(NULL),
                       mock_network_library_(NULL) {}

 protected:
  virtual void SetUpInProcessBrowserTestFixture() {
    DBusThreadManager::Initialize();
    WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
    cros_mock_->InitStatusAreaMocks();
    cros_mock_->SetStatusAreaMocksExpectations();
    ASSERT_TRUE(CrosLibrary::Get()->EnsureLoaded());

    mock_session_manager_client_ = new MockSessionManagerClient();
    DBusThreadManager::Get()->set_session_manager_client_for_testing(
        mock_session_manager_client_);
    EXPECT_CALL(*mock_session_manager_client_, EmitLoginPromptReady())
        .Times(1);

    mock_update_library_ = new MockUpdateLibrary();
    cros_mock_->test_api()->SetUpdateLibrary(mock_update_library_, true);

    // UpdateScreen::StartUpdate() will be called by the WizardController
    // just after creating the update screen, so the expectations for that
    // should be set up here.
    EXPECT_CALL(*mock_update_library_, AddObserver(_))
        .Times(1);
    EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
        .Times(AtLeast(1));
    EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
        .Times(1)
        .WillOnce(Invoke(RequestUpdateCheckSuccess));

    mock_network_library_ = cros_mock_->mock_network_library();
    EXPECT_CALL(*mock_network_library_, Connected())
        .Times(1)  // also called by NetworkMenu::InitMenuItems()
        .WillRepeatedly((Return(false)))
        .RetiresOnSaturation();
    EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*mock_network_library_, FindWifiDevice())
        .Times(AnyNumber());
    EXPECT_CALL(*mock_network_library_, FindEthernetDevice())
        .Times(AnyNumber());
  }

  virtual void SetUpOnMainThread() {
    mock_screen_observer_.reset(new MockScreenObserver());
    ASSERT_TRUE(controller() != NULL);
    update_screen_ = controller()->GetUpdateScreen();
    ASSERT_TRUE(update_screen_ != NULL);
    ASSERT_EQ(controller()->current_screen(), update_screen_);
    update_screen_->screen_observer_ = mock_screen_observer_.get();
  }

  virtual void TearDownInProcessBrowserTestFixture() {
    update_screen_->screen_observer_ = (controller());
    cros_mock_->test_api()->SetUpdateLibrary(NULL, true);
    WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
    DBusThreadManager::Shutdown();
  }

  MockSessionManagerClient* mock_session_manager_client_;
  MockUpdateLibrary* mock_update_library_;
  MockNetworkLibrary* mock_network_library_;

  scoped_ptr<MockScreenObserver> mock_screen_observer_;
  UpdateScreen* update_screen_;
  // DBusThreadManager needs a message loop.
  MessageLoopForUI message_loop_;

 private:
  DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest);
};

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) {
  ASSERT_TRUE(update_screen_->actor_ != NULL);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) {
  update_screen_->SetIgnoreIdleStatus(true);
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_IDLE;
  update_screen_->UpdateStatusChanged(status);
  status.status = UPDATE_STATUS_CHECKING_FOR_UPDATE;
  update_screen_->UpdateStatusChanged(status);
  status.status = UPDATE_STATUS_IDLE;
  // status() will be called via ExitUpdate() called from
  // UpdateStatusChanged().
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_, OnExit(ScreenObserver::UPDATE_NOUPDATE))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) {
  update_screen_->is_ignore_update_deadlines_ = true;

  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
  status.new_version = "latest and greatest";
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_DOWNLOADING;
  status.download_progress = 0.0;
  update_screen_->UpdateStatusChanged(status);

  status.download_progress = 0.5;
  update_screen_->UpdateStatusChanged(status);

  status.download_progress = 1.0;
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_VERIFYING;
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_FINALIZING;
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_UPDATED_NEED_REBOOT;
  EXPECT_CALL(*mock_update_library_, RebootAfterUpdate())
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

static void RequestUpdateCheckFail(UpdateCallback callback, void* userdata) {
  callback(userdata, chromeos::UPDATE_RESULT_FAILED, NULL);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorIssuingUpdateCheck) {
  // First, cancel the update that is already in progress.
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_NOUPDATE))
      .Times(1);
  update_screen_->CancelUpdate();

  // Run UpdateScreen::StartUpdate() again, but CheckForUpdate() will fail
  // issuing the update check this time.
  EXPECT_CALL(*mock_update_library_, AddObserver(_))
      .Times(1);
  EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
      .Times(AtLeast(1));
  EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
      .Times(1)
      .WillOnce(Invoke(RequestUpdateCheckFail));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
      .Times(1);
  update_screen_->StartUpdate();
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorCheckingForUpdate) {
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_ERROR;
  // status() will be called via ExitUpdate() called from
  // UpdateStatusChanged().
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorUpdating) {
  UpdateLibrary::Status status;
  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
  status.new_version = "latest and greatest";
  // status() will be called via ExitUpdate() called from
  // UpdateStatusChanged().
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  update_screen_->UpdateStatusChanged(status);

  status.status = UPDATE_STATUS_ERROR;
  // status() will be called via ExitUpdate() called from
  // UpdateStatusChanged().
  EXPECT_CALL(*mock_update_library_, status())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRef(status));
  EXPECT_CALL(*mock_screen_observer_,
              OnExit(ScreenObserver::UPDATE_ERROR_UPDATING))
      .Times(1);
  update_screen_->UpdateStatusChanged(status);
}

}  // namespace chromeos
<|endoftext|>


<commit_before>/*
 * This program is just for personal experiments here on AVR features and C++ stuff
 * to check compilation and link of FastArduino port and pin API.
 * It does not do anything interesting as far as hardware is concerned.
 */

#include <fastarduino/boards/board.h>
#include <fastarduino/gpio.h>
#include <fastarduino/time.h>
#include <fastarduino/realtime_timer.h>
#include <fastarduino/utilities.h>
#include <fastarduino/flash.h>
#include <fastarduino/devices/hcsr04.h>
#include <fastarduino/int.h>
#include <fastarduino/pci.h>

REGISTER_RTT_ISR(0)

static constexpr const board::DigitalPin TRIGGER = board::DigitalPin::D2_PD2;
static constexpr const board::DigitalPin ECHO = board::InterruptPin::D3_PD3_PCI2;
static constexpr const board::Timer TIMER = board::Timer::TIMER0;

using RTT = timer::RTT<TIMER>;
using SONAR = devices::sonar::HCSR04<TIMER, TRIGGER, ECHO>;

class SonarListener
{
public:
	SonarListener(uint16_t min_mm):MIN_US{devices::sonar::distance_mm_to_echo_us(min_mm)}, led_{gpio::PinMode::OUTPUT}
	{
		interrupt::register_handler(*this);
	}

	void on_sonar(uint16_t echo_us)
	{
		if (echo_us && echo_us <= MIN_US)
			led_.set();
		else
			led_.clear();
	}

private:
	const uint16_t MIN_US;
	gpio::FastPinType<board::DigitalPin::LED>::TYPE led_;
};

REGISTER_HCSR04_PCI_ISR_METHOD(TIMER, 2, TRIGGER, ECHO, SonarListener, &SonarListener::on_sonar)

int main() __attribute__((OS_main));
int main()
{
	sei();

	SonarListener listener{150};

	RTT rtt;
	rtt.register_rtt_handler();
	rtt.begin();
	typename interrupt::PCIType<ECHO>::TYPE signal;
	signal.enable_pin<ECHO>();
	signal.enable();
	SONAR sensor{rtt};

	while (true)
	{
		sensor.async_echo();
		sensor.await_echo_us();
	}
}
<commit_msg>First experiments with I2C.<commit_after>/*
 * This program is just for personal experiments here on AVR features and C++ stuff
 * to check compilation and link of FastArduino port and pin API.
 * It does not do anything interesting as far as hardware is concerned.
 */

#include <fastarduino/boards/board.h>
#include <fastarduino/time.h>
#include <fastarduino/uart.h>

// UART for traces
static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 64;
static char output_buffer[OUTPUT_BUFFER_SIZE];
static serial::hard::UATX<board::USART::USART0> uart{output_buffer};
static streams::FormattedOutput<streams::OutputBuffer> out = uart.fout();
// Define vectors we need in the example
REGISTER_UATX_ISR(0)

// DS1307 specific
const uint8_t DEVICE_ADDRESS = 0x68 << 1;
struct BCD
{
	struct
	{
		uint8_t high	:4;
		uint8_t low		:4;
	};
	uint8_t data;
};
struct RealTime
{
	BCD seconds;
	BCD minutes;
	BCD hours;
	uint8_t weekday;
	BCD day;
	BCD month;
	BCD	year;
};

//TODO define constants for expected results

const uint32_t I2C_FREQUENCY = 100000;

// NOTE we use prescaler = 1 everywhere
constexpr uint8_t calculate_TWBR(uint32_t frequency)
{
	return (F_CPU / frequency - 16UL) / 2;
}

static bool wait_twi(uint8_t expected_status)
{
	out << "W " << streams::hex << expected_status << " #1" << streams::flush;
	loop_until_bit_is_set(TWCR, TWINT);
	out << " #2" << streams::flush;
	if ((TWSR & 0xF8) == expected_status)
	{
		out << "- " << streams::dec << streams::flush;
		return true;
	}
	//TODO ERROR handling and trace
	out << " X " << streams::hex << TWSR << streams::dec << ' ' << streams::flush;
	return false;
}

// TODO traits for: SDA, SCL pins
int main() __attribute__((OS_main));
int main()
{
	sei();

	uart.register_handler();
	uart.begin(115200);
	out.width(0);
	out << "Start\n" << streams::flush;

	// Start TWI interface
	//====================
	// 1. set SDA/SCL pullups (TODO: in specific TRAIT)
	PORTC |= _BV(PORTC4) | _BV(PORTC5);
	// 2. set I2C frequency
	TWBR = calculate_TWBR(I2C_FREQUENCY);
	TWSR = 0;
	// 3. Enable TWI
	TWCR = _BV(TWEN);

	out << "I2C interface started\n" << streams::flush;
	time::delay_ms(1000);

	// Send a byte to a slave
	//=======================
	// 1. send START
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
	wait_twi(0x08);
	// 2. send SLA+W
	TWDR = DEVICE_ADDRESS;
	TWCR = _BV(TWEN) | _BV(TWINT);
	wait_twi(0x18);
	// 3. send data
	TWDR = 0;
	TWCR = _BV(TWEN) | _BV(TWINT);
	wait_twi(0x28);
//	// 4. send STOP (normally not needed (or harmful?) with DS1307
//	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO);

	RealTime time;
	// Read a byte from a slave
	//=========================
	// 1. send REPEATING START
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
	wait_twi(0x10);
//	wait_twi(0x08);
	// 2. send SLA+R
	TWDR = DEVICE_ADDRESS | 0x01;
	TWCR = _BV(TWEN) | _BV(TWINT);
	wait_twi(0x40);
	// 3. Read data & send ACK
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.seconds.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.minutes.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.hours.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.weekday = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.day.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.month.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);
	wait_twi(0x50);
	time.year.data = TWDR;
	TWCR = _BV(TWEN) | _BV(TWINT);
	wait_twi(0x58);
	// 4. send STOP
	TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO);

	out	<< "RTC: "
		<< time.day.high << time.day.low << '.'
		<< time.month.high << time.month.low << '.'
		<< time.year.high << time.year.low << ' '
		<< time.hours.high << time.hours.low << ':'
		<< time.minutes.high << time.minutes.low << ':'
		<< time.seconds.high << time.seconds.low << '\n'
		<< streams::flush;

	// Stop TWI interface
	//===================
	// 1. Disable TWI
	TWCR = 0;
	// 2. remove SDA/SCL pullups
	PORTC &= ~(_BV(PORTC4) | _BV(PORTC5));

	out << "End\n" << streams::flush;
}
<|endoftext|>


<commit_before>// Copyright 2008, Google 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:
//
//  1. Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//  2. 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.
//  3. Neither the name of Google 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 AUTHOR ``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 AUTHOR 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.

// This program demonstrates some capabilities of resource management of
// elements in the KML DOM.  An array (std::vector) of PlacemarkPtrs into
// parsed DOM is created.  The DOM root is discarded leaving the only
// references to the underlying Placemarks in the array.  The Placemarks
// are finally discarded when the array goes out of scope.

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include "kml/dom.h"
#include "kml/engine.h"
#include "kml/base/file.h"

using kmldom::ContainerPtr;
using kmldom::ElementPtr;
using kmldom::FeaturePtr;
using kmldom::KmlPtr;
using kmldom::PlacemarkPtr;
using kmlengine::KmlFile;
using kmlengine::KmlFilePtr;
using kmlengine::KmzFile;
using kmlengine::KmzFilePtr;
using std::cout;
using std::endl;

// Declare the types and functions defined in this file.
typedef std::vector<PlacemarkPtr> placemark_vector_t;
static FeaturePtr GetKmlFileRootFeature(const char* kmlfile);
static void SavePlacemarks(const FeaturePtr& feature,
                           placemark_vector_t* placemarks);

// Save the Feature to the placemarks vector if it is a Placemark.  If the
// Feature is a Container call ourselves recursively for each Feature in the
// Container.
static void SavePlacemarks(const FeaturePtr& feature,
                           placemark_vector_t* placemarks) {
  if (PlacemarkPtr placemark = kmldom::AsPlacemark(feature)) {
    placemarks->push_back(placemark);
  } else if (const ContainerPtr container = kmldom::AsContainer(feature)) {
    for (size_t i = 0; i < container->get_feature_array_size(); ++i) {
      SavePlacemarks(container->get_feature_array_at(i), placemarks);
    }
  }
}

// Return a FeaturePtr to the root Feature in the kmlfile.  If the kmlfile
// does not parse or has no root Feature then an empty FeaturePtr is returned.
static FeaturePtr GetKmlFileRootFeature(const char* kmlfile) {
  // Read the file.
  std::string file_data;
  if (!kmlbase::File::ReadFileToString(kmlfile, &file_data)) {
    cout << kmlfile << " read failed" << endl;
    return NULL;
  }

  // If the file was KMZ, extract the KML file.
  std::string kml;
  if (KmzFile::IsKmz(file_data)) {
    KmzFilePtr kmz_file = KmzFile::OpenFromString(kmlfile);
    if (!kmz_file) {
      cout << "Failed opening KMZ file" << endl;
      return NULL;
    }
    if (!kmz_file->ReadKml(&kml)) {
      cout << "Failed to read KML from KMZ" << endl;
      return NULL;
    }
  } else {
    kml = file_data;
  }

  // Parse it.
  std::string errors;
  KmlFilePtr kml_file = KmlFile::CreateFromParse(kml, &errors);
  if (!kml_file) {
    cout << errors << endl;
    return FeaturePtr();
  }

  // Get the root
  return kmlengine::GetRootFeature(kml_file->root());
}

// This function object is used by STL sort() to alphabetize Placemarks
// by <name>.
struct ComparePlacemarks
  : public
      std::binary_function<const PlacemarkPtr&, const PlacemarkPtr&, bool> {
  bool operator()(const PlacemarkPtr& a, const PlacemarkPtr& b) {
    return a->get_name() < b->get_name();
  }
};

int main(int argc, char** argv) {
  if (argc != 2) {
    cout << "usage: " << argv[0] << " kmlfile" << endl;
    return 1;
  }

  placemark_vector_t placemark_vector;
  // Note that the FeaturePtr returned from GetKmlFileRootFeature() is
  // a temporary and goes out of scope and is destroyed after SavePlacemarks()
  // returns.  As such the only references to the Placemarks found in the
  // file are those in the placemark_vector array.  That is, the resource
  // management model of the KML DOM is such that it is completely safe to
  // save off pointers into the KML DOM even after the root of a given parse
  // has been released.
  SavePlacemarks(GetKmlFileRootFeature(argv[1]), &placemark_vector);
  sort(placemark_vector.begin(), placemark_vector.end(), ComparePlacemarks());
  for (size_t i = 0; i < placemark_vector.size(); ++i) {
    cout << i << " " << placemark_vector[i]->get_id() << " " <<
      placemark_vector[i]->get_name() << endl;
  }
  cout << argv[1] << " has " << placemark_vector.size() << " Placemarks." <<
    endl;

  // While we don't really care about resource leaks here because main() exits,
  // note that placemark_vector's destructor calls the destructor
  // of each PlacemarkPtr.  This in turn releases the final reference to
  // each Placemark.  Thus, the last reference to any KML DOM element is
  // released as main goes out of scope.

  return 0;
}
<commit_msg>use KmlFile::get_root()<commit_after>// Copyright 2008, Google 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:
//
//  1. Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//  2. 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.
//  3. Neither the name of Google 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 AUTHOR ``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 AUTHOR 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.

// This program demonstrates some capabilities of resource management of
// elements in the KML DOM.  An array (std::vector) of PlacemarkPtrs into
// parsed DOM is created.  The DOM root is discarded leaving the only
// references to the underlying Placemarks in the array.  The Placemarks
// are finally discarded when the array goes out of scope.

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include "kml/dom.h"
#include "kml/engine.h"
#include "kml/base/file.h"

using kmldom::ContainerPtr;
using kmldom::ElementPtr;
using kmldom::FeaturePtr;
using kmldom::KmlPtr;
using kmldom::PlacemarkPtr;
using kmlengine::KmlFile;
using kmlengine::KmlFilePtr;
using kmlengine::KmzFile;
using kmlengine::KmzFilePtr;
using std::cout;
using std::endl;

// Declare the types and functions defined in this file.
typedef std::vector<PlacemarkPtr> placemark_vector_t;
static FeaturePtr GetKmlFileRootFeature(const char* kmlfile);
static void SavePlacemarks(const FeaturePtr& feature,
                           placemark_vector_t* placemarks);

// Save the Feature to the placemarks vector if it is a Placemark.  If the
// Feature is a Container call ourselves recursively for each Feature in the
// Container.
static void SavePlacemarks(const FeaturePtr& feature,
                           placemark_vector_t* placemarks) {
  if (PlacemarkPtr placemark = kmldom::AsPlacemark(feature)) {
    placemarks->push_back(placemark);
  } else if (const ContainerPtr container = kmldom::AsContainer(feature)) {
    for (size_t i = 0; i < container->get_feature_array_size(); ++i) {
      SavePlacemarks(container->get_feature_array_at(i), placemarks);
    }
  }
}

// Return a FeaturePtr to the root Feature in the kmlfile.  If the kmlfile
// does not parse or has no root Feature then an empty FeaturePtr is returned.
static FeaturePtr GetKmlFileRootFeature(const char* kmlfile) {
  // Read the file.
  std::string file_data;
  if (!kmlbase::File::ReadFileToString(kmlfile, &file_data)) {
    cout << kmlfile << " read failed" << endl;
    return NULL;
  }

  // If the file was KMZ, extract the KML file.
  std::string kml;
  if (KmzFile::IsKmz(file_data)) {
    KmzFilePtr kmz_file = KmzFile::OpenFromString(kmlfile);
    if (!kmz_file) {
      cout << "Failed opening KMZ file" << endl;
      return NULL;
    }
    if (!kmz_file->ReadKml(&kml)) {
      cout << "Failed to read KML from KMZ" << endl;
      return NULL;
    }
  } else {
    kml = file_data;
  }

  // Parse it.
  std::string errors;
  KmlFilePtr kml_file = KmlFile::CreateFromParse(kml, &errors);
  if (!kml_file) {
    cout << errors << endl;
    return FeaturePtr();
  }

  // Get the root
  return kmlengine::GetRootFeature(kml_file->get_root());
}

// This function object is used by STL sort() to alphabetize Placemarks
// by <name>.
struct ComparePlacemarks
  : public
      std::binary_function<const PlacemarkPtr&, const PlacemarkPtr&, bool> {
  bool operator()(const PlacemarkPtr& a, const PlacemarkPtr& b) {
    return a->get_name() < b->get_name();
  }
};

int main(int argc, char** argv) {
  if (argc != 2) {
    cout << "usage: " << argv[0] << " kmlfile" << endl;
    return 1;
  }

  placemark_vector_t placemark_vector;
  // Note that the FeaturePtr returned from GetKmlFileRootFeature() is
  // a temporary and goes out of scope and is destroyed after SavePlacemarks()
  // returns.  As such the only references to the Placemarks found in the
  // file are those in the placemark_vector array.  That is, the resource
  // management model of the KML DOM is such that it is completely safe to
  // save off pointers into the KML DOM even after the root of a given parse
  // has been released.
  SavePlacemarks(GetKmlFileRootFeature(argv[1]), &placemark_vector);
  sort(placemark_vector.begin(), placemark_vector.end(), ComparePlacemarks());
  for (size_t i = 0; i < placemark_vector.size(); ++i) {
    cout << i << " " << placemark_vector[i]->get_id() << " " <<
      placemark_vector[i]->get_name() << endl;
  }
  cout << argv[1] << " has " << placemark_vector.size() << " Placemarks." <<
    endl;

  // While we don't really care about resource leaks here because main() exits,
  // note that placemark_vector's destructor calls the destructor
  // of each PlacemarkPtr.  This in turn releases the final reference to
  // each Placemark.  Thus, the last reference to any KML DOM element is
  // released as main goes out of scope.

  return 0;
}
<|endoftext|>


<commit_before>//This file is released under terms of BSD license`
//See LICENSE.txt for more information

#include "gtest/gtest.h"
#include "serializer/Savepoint.h"
#include "wrapper/SerializationWrapper.h"

using namespace ser;

/**
 * In this test we test the basic C API
 */
TEST(SavepointUnittest, Basic)
{
    Savepoint& sp = *reinterpret_cast<Savepoint*>(fs_create_savepoint("MySavepoint", 11));

    ASSERT_EQ("MySavepoint", sp.name());

    // Add some metainfo with the C++ API
    sp.AddMetainfo("StepNumber", 42);
    sp.AddMetainfo("TimeStepSize", 0.125);
    sp.AddMetainfo("SavepointAuthor", "Andrea Arteaga");

    // Add some metainfo with the C API
    fs_add_savepoint_metainfo_b(&sp, "ILikeThisAPI", 12, true);
    fs_add_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, 7.5);
    fs_add_savepoint_metainfo_s(&sp, "MyOS", 4, "GNU/Linux", 9);

    // Check metainfo
    ASSERT_EQ(6, sp.metainfo().size());
    ASSERT_EQ(42, sp.metainfo().AsInt("StepNumber"));
    ASSERT_EQ(0.125, sp.metainfo().AsDouble("TimeStepSize"));
    ASSERT_EQ(std::string("Andrea Arteaga"), sp.metainfo().AsString("SavepointAuthor"));
    ASSERT_EQ(true, sp.metainfo().AsBool("ILikeThisAPI"));
    ASSERT_EQ(7.5, sp.metainfo().AsDouble("HowManyCookiesIEat"));
    ASSERT_EQ(std::string("GNU/Linux"), sp.metainfo().AsString("MyOS"));

    fs_destroy_savepoint(&sp);
}

/**
 * In this test we test the metainfo retrieval C API
 */
TEST(SavepointUnittest, Metainfo)
{
    Savepoint& sp = *reinterpret_cast<Savepoint*>(fs_create_savepoint("MySavepoint", 11));

    // Add some metainfo with the C++ API
    sp.AddMetainfo("StepNumber", 42);
    sp.AddMetainfo("TimeStepSize", 0.125);
    sp.AddMetainfo("SavepointAuthor", "Andrea Arteaga");

    // Add some metainfo with the C API
    fs_add_savepoint_metainfo_b(&sp, "YouLikeThisAPI", 14, true);
    fs_add_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, 7.5);
    fs_add_savepoint_metainfo_s(&sp, "MyOS", 4, "GNU/Linux", 9);

    // Get metainfo number
    ASSERT_EQ(6, fs_savepoint_metainfo(&sp));

    // Get keys of metainfo
    int key_length[6];
    fs_savepoint_key_lengths(&sp, key_length);
    ASSERT_EQ(18, key_length[0]);
    ASSERT_EQ( 4, key_length[1]);
    ASSERT_EQ(15, key_length[2]);
    ASSERT_EQ(10, key_length[3]);
    ASSERT_EQ(12, key_length[4]);
    ASSERT_EQ(14, key_length[5]);

    // Get keys
    std::string keys_str[6];
    char* keys[6];
    for(int i = 0; i < 6; ++i)
        keys[i] = new char[key_length[i]];

    fs_savepoint_get_keys(&sp, &keys[0]);
    for(int i = 0; i < 6; ++i)
    {
        keys_str[i].assign(keys[i], key_length[i]);
        delete[] keys[i];
    }
    ASSERT_EQ(std::string("HowManyCookiesIEat"), keys_str[0]);
    ASSERT_EQ(std::string("MyOS"), keys_str[1]);
    ASSERT_EQ(std::string("SavepointAuthor"), keys_str[2]);
    ASSERT_EQ(std::string("StepNumber"), keys_str[3]);
    ASSERT_EQ(std::string("TimeStepSize"), keys_str[4]);
    ASSERT_EQ(std::string("YouLikeThisAPI"), keys_str[5]);

    // Get type
    int types[6];
    fs_savepoint_get_types(&sp, types);
    ASSERT_EQ(-4, types[0]);
    ASSERT_EQ( 9, types[1]);
    ASSERT_EQ(14, types[2]);
    ASSERT_EQ(-2, types[3]);
    ASSERT_EQ(-4, types[4]);
    ASSERT_EQ(-1, types[5]);

    // Get values
    bool bvalue;
    int ivalue;
    double dvalue;
    std::string svalue;
    fs_get_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, &dvalue); ASSERT_EQ(7.5, dvalue);
    svalue.resize(9); fs_get_savepoint_metainfo_s(&sp, "MyOS", 4, &svalue[0]); ASSERT_EQ(std::string("GNU/Linux"), svalue);
    svalue.resize(14); fs_get_savepoint_metainfo_s(&sp, "SavepointAuthor", 15, &svalue[0]); ASSERT_EQ(std::string("Andrea Arteaga"), svalue);
    fs_get_savepoint_metainfo_i(&sp, "StepNumber", 10, &ivalue); ASSERT_EQ(42, ivalue);
    fs_get_savepoint_metainfo_d(&sp, "TimeStepSize", 12, &dvalue); ASSERT_EQ(0.125, dvalue);
    fs_get_savepoint_metainfo_b(&sp, "YouLikeThisAPI", 14, &bvalue); ASSERT_EQ(true, bvalue);

    fs_destroy_savepoint(&sp);

}

<commit_msg>Fix serialization wrapper unittest<commit_after>//This file is released under terms of BSD license`
//See LICENSE.txt for more information

#include "gtest/gtest.h"
#include "serializer/Savepoint.h"
#include "wrapper/SerializationWrapper.h"

using namespace ser;

/**
 * In this test we test the basic C API
 */
TEST(SavepointUnittest, Basic)
{
    Savepoint& sp = *reinterpret_cast<Savepoint*>(fs_create_savepoint("MySavepoint", 11));

    ASSERT_EQ("MySavepoint", sp.name());

    // Add some metainfo with the C++ API
    sp.AddMetainfo("StepNumber", 42);
    sp.AddMetainfo("TimeStepSize", 0.125);
    sp.AddMetainfo("SavepointAuthor", "Andrea Arteaga");

    // Add some metainfo with the C API
    fs_add_savepoint_metainfo_b(&sp, "ILikeThisAPI", 12, true);
    fs_add_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, 7.5);
    fs_add_savepoint_metainfo_s(&sp, "MyOS", 4, "GNU/Linux", 9);

    // Check metainfo
    ASSERT_EQ(6, sp.metainfo().size());
    ASSERT_EQ(42, sp.metainfo().AsInt("StepNumber"));
    ASSERT_EQ(0.125, sp.metainfo().AsDouble("TimeStepSize"));
    ASSERT_EQ(std::string("Andrea Arteaga"), sp.metainfo().AsString("SavepointAuthor"));
    ASSERT_EQ(true, sp.metainfo().AsBool("ILikeThisAPI"));
    ASSERT_EQ(7.5, sp.metainfo().AsDouble("HowManyCookiesIEat"));
    ASSERT_EQ(std::string("GNU/Linux"), sp.metainfo().AsString("MyOS"));

    fs_destroy_savepoint(&sp);
}

/**
 * In this test we test the metainfo retrieval C API
 */
TEST(SavepointUnittest, Metainfo)
{
    Savepoint& sp = *reinterpret_cast<Savepoint*>(fs_create_savepoint("MySavepoint", 11));

    // Add some metainfo with the C++ API
    sp.AddMetainfo("StepNumber", 42);
    sp.AddMetainfo("TimeStepSize", 0.125);
    sp.AddMetainfo("SavepointAuthor", "Andrea Arteaga");

    // Add some metainfo with the C API
    fs_add_savepoint_metainfo_b(&sp, "YouLikeThisAPI", 14, true);
    fs_add_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, 7.5);
    fs_add_savepoint_metainfo_s(&sp, "MyOS", 4, "GNU/Linux", 9);

    // Get metainfo number
    ASSERT_EQ(6, fs_savepoint_metainfo_size(&sp));

    // Get keys of metainfo
    int key_length[6];
    fs_savepoint_key_lengths(&sp, key_length);
    ASSERT_EQ(18, key_length[0]);
    ASSERT_EQ( 4, key_length[1]);
    ASSERT_EQ(15, key_length[2]);
    ASSERT_EQ(10, key_length[3]);
    ASSERT_EQ(12, key_length[4]);
    ASSERT_EQ(14, key_length[5]);

    // Get keys
    std::string keys_str[6];
    char* keys[6];
    for(int i = 0; i < 6; ++i)
        keys[i] = new char[key_length[i]];

    fs_savepoint_get_keys(&sp, &keys[0]);
    for(int i = 0; i < 6; ++i)
    {
        keys_str[i].assign(keys[i], key_length[i]);
        delete[] keys[i];
    }
    ASSERT_EQ(std::string("HowManyCookiesIEat"), keys_str[0]);
    ASSERT_EQ(std::string("MyOS"), keys_str[1]);
    ASSERT_EQ(std::string("SavepointAuthor"), keys_str[2]);
    ASSERT_EQ(std::string("StepNumber"), keys_str[3]);
    ASSERT_EQ(std::string("TimeStepSize"), keys_str[4]);
    ASSERT_EQ(std::string("YouLikeThisAPI"), keys_str[5]);

    // Get type
    int types[6];
    fs_savepoint_get_types(&sp, types);
    ASSERT_EQ(-4, types[0]);
    ASSERT_EQ( 9, types[1]);
    ASSERT_EQ(14, types[2]);
    ASSERT_EQ(-2, types[3]);
    ASSERT_EQ(-4, types[4]);
    ASSERT_EQ(-1, types[5]);

    // Get values
    bool bvalue;
    int ivalue;
    double dvalue;
    std::string svalue;
    fs_get_savepoint_metainfo_d(&sp, "HowManyCookiesIEat", 18, &dvalue); ASSERT_EQ(7.5, dvalue);
    svalue.resize(9); fs_get_savepoint_metainfo_s(&sp, "MyOS", 4, &svalue[0]); ASSERT_EQ(std::string("GNU/Linux"), svalue);
    svalue.resize(14); fs_get_savepoint_metainfo_s(&sp, "SavepointAuthor", 15, &svalue[0]); ASSERT_EQ(std::string("Andrea Arteaga"), svalue);
    fs_get_savepoint_metainfo_i(&sp, "StepNumber", 10, &ivalue); ASSERT_EQ(42, ivalue);
    fs_get_savepoint_metainfo_d(&sp, "TimeStepSize", 12, &dvalue); ASSERT_EQ(0.125, dvalue);
    fs_get_savepoint_metainfo_b(&sp, "YouLikeThisAPI", 14, &bvalue); ASSERT_EQ(true, bvalue);

    fs_destroy_savepoint(&sp);

}

<|endoftext|>


<commit_before>//===- MachineInstrTest.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {
// Add a few Bogus backend classes so we can create MachineInstrs without
// depending on a real target.
class BogusTargetLowering : public TargetLowering {
public:
  BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {}
};

class BogusFrameLowering : public TargetFrameLowering {
public:
  BogusFrameLowering()
      : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 4) {}

  void emitPrologue(MachineFunction &MF,
                    MachineBasicBlock &MBB) const override {}
  void emitEpilogue(MachineFunction &MF,
                    MachineBasicBlock &MBB) const override {}
  bool hasFP(const MachineFunction &MF) const override { return false; }
};

static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};

class BogusRegisterInfo : public TargetRegisterInfo {
public:
  BogusRegisterInfo()
      : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
                           nullptr, nullptr, LaneBitmask(~0u), nullptr) {}

  const MCPhysReg *
  getCalleeSavedRegs(const MachineFunction *MF) const override {
    return nullptr;
  }
  ArrayRef<const uint32_t *> getRegMasks() const override { return None; }
  ArrayRef<const char *> getRegMaskNames() const override { return None; }
  BitVector getReservedRegs(const MachineFunction &MF) const override {
    return BitVector();
  }
  const RegClassWeight &
  getRegClassWeight(const TargetRegisterClass *RC) const override {
    static RegClassWeight Bogus{1, 16};
    return Bogus;
  }
  unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; }
  unsigned getNumRegPressureSets() const override { return 0; }
  const char *getRegPressureSetName(unsigned Idx) const override {
    return "bogus";
  }
  unsigned getRegPressureSetLimit(const MachineFunction &MF,
                                  unsigned Idx) const override {
    return 0;
  }
  const int *
  getRegClassPressureSets(const TargetRegisterClass *RC) const override {
    static const int Bogus[] = {0, -1};
    return &Bogus[0];
  }
  const int *getRegUnitPressureSets(unsigned RegUnit) const override {
    static const int Bogus[] = {0, -1};
    return &Bogus[0];
  }

  Register getFrameRegister(const MachineFunction &MF) const override {
    return 0;
  }
  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS = nullptr) const override {}
};

class BogusSubtarget : public TargetSubtargetInfo {
public:
  BogusSubtarget(TargetMachine &TM)
      : TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr,
                            nullptr, nullptr, nullptr, nullptr),
        FL(), TL(TM) {}
  ~BogusSubtarget() override {}

  const TargetFrameLowering *getFrameLowering() const override { return &FL; }

  const TargetLowering *getTargetLowering() const override { return &TL; }

  const TargetInstrInfo *getInstrInfo() const override { return &TII; }

  const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }

private:
  BogusFrameLowering FL;
  BogusRegisterInfo TRI;
  BogusTargetLowering TL;
  TargetInstrInfo TII;
};

class BogusTargetMachine : public LLVMTargetMachine {
public:
  BogusTargetMachine()
      : LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
                          Reloc::Static, CodeModel::Small, CodeGenOpt::Default),
        ST(*this) {}
  ~BogusTargetMachine() override {}

  const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
    return &ST;
  }

private:
  BogusSubtarget ST;
};

std::unique_ptr<BogusTargetMachine> createTargetMachine() {
  return llvm::make_unique<BogusTargetMachine>();
}

std::unique_ptr<MachineFunction> createMachineFunction() {
  LLVMContext Ctx;
  Module M("Module", Ctx);
  auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
  auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M);

  auto TM = createTargetMachine();
  unsigned FunctionNum = 42;
  MachineModuleInfo MMI(TM.get());
  const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F);

  return llvm::make_unique<MachineFunction>(*F, *TM, STI, FunctionNum, MMI);
}

// This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
// for various combinations of IgnoreDefs, and also that it is symmetrical.
TEST(IsIdenticalToTest, DifferentDefs) {
  auto MF = createMachineFunction();

  unsigned short NumOps = 2;
  unsigned char NumDefs = 1;
  MCOperandInfo OpInfo[] = {
      {0, 0, MCOI::OPERAND_REGISTER, 0},
      {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  MCInstrDesc MCID = {
      0, NumOps,  NumDefs, 0,      0, 1ULL << MCID::HasOptionalDef,
      0, nullptr, nullptr, OpInfo, 0, nullptr};

  // Create two MIs with different virtual reg defs and the same uses.
  unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
  unsigned VirtualDef2 = -43;
  unsigned VirtualUse = -44;

  auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));

  auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));

  // Check that they are identical when we ignore virtual register defs, but not
  // when we check defs.
  ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));
  ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));

  ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
  ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));

  // Create two MIs with different virtual reg defs, and a def or use of a
  // sentinel register.
  unsigned SentinelReg = 0;

  auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));

  auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));

  // Check that they are never identical.
  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));

  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
}

// Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with
// MachineInstrExpressionTrait::getHashValue
void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {
  bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);
  bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);

  ASSERT_EQ(IsEqual1, IsEqual2);

  auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
  auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);

  ASSERT_EQ(IsEqual1, Hash1 == Hash2);
}

// This test makes sure that MachineInstrExpressionTraits::isEqual is in sync
// with MachineInstrExpressionTraits::getHashValue.
TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
  auto MF = createMachineFunction();

  unsigned short NumOps = 2;
  unsigned char NumDefs = 1;
  MCOperandInfo OpInfo[] = {
      {0, 0, MCOI::OPERAND_REGISTER, 0},
      {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  MCInstrDesc MCID = {
      0, NumOps,  NumDefs, 0,      0, 1ULL << MCID::HasOptionalDef,
      0, nullptr, nullptr, OpInfo, 0, nullptr};

  // Define a series of instructions with different kinds of operands and make
  // sure that the hash function is consistent with isEqual for various
  // combinations of them.
  unsigned VirtualDef1 = -42;
  unsigned VirtualDef2 = -43;
  unsigned VirtualReg = -44;
  unsigned SentinelReg = 0;
  unsigned PhysicalReg = 45;

  auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));

  auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));

  auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1SU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1SU->addOperand(*MF,
                    MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));

  auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1SD->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1SD->addOperand(*MF,
                    MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));

  auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2PU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2PU->addOperand(*MF,
                    MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));

  auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2PD->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2PD->addOperand(*MF,
                    MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true));

  checkHashAndIsEqualMatch(VD1VU, VD2VU);
  checkHashAndIsEqualMatch(VD1VU, VD1SU);
  checkHashAndIsEqualMatch(VD1VU, VD1SD);
  checkHashAndIsEqualMatch(VD1VU, VD2PU);
  checkHashAndIsEqualMatch(VD1VU, VD2PD);

  checkHashAndIsEqualMatch(VD2VU, VD1SU);
  checkHashAndIsEqualMatch(VD2VU, VD1SD);
  checkHashAndIsEqualMatch(VD2VU, VD2PU);
  checkHashAndIsEqualMatch(VD2VU, VD2PD);

  checkHashAndIsEqualMatch(VD1SU, VD1SD);
  checkHashAndIsEqualMatch(VD1SU, VD2PU);
  checkHashAndIsEqualMatch(VD1SU, VD2PD);

  checkHashAndIsEqualMatch(VD1SD, VD2PU);
  checkHashAndIsEqualMatch(VD1SD, VD2PD);

  checkHashAndIsEqualMatch(VD2PU, VD2PD);
}

TEST(MachineInstrPrintingTest, DebugLocPrinting) {
  auto MF = createMachineFunction();

  MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0};
  MCInstrDesc MCID = {0, 1,       1,       0,       0, 0,
                      0, nullptr, nullptr, &OpInfo, 0, nullptr};

  LLVMContext Ctx;
  DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
  DISubprogram *DIS = DISubprogram::getDistinct(
      Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero,
      DISubprogram::SPFlagZero, nullptr);
  DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS);
  DebugLoc DL(DIL);
  MachineInstr *MI = MF->CreateMachineInstr(MCID, DL);
  MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));

  std::string str;
  raw_string_ostream OS(str);
  MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
            /*AddNewLine*/false);
  ASSERT_TRUE(
      StringRef(OS.str()).startswith("$noreg = UNKNOWN debug-location "));
  ASSERT_TRUE(
      StringRef(OS.str()).endswith("filename:1:5"));
}

TEST(MachineInstrSpan, DistanceBegin) {
  auto MF = createMachineFunction();
  auto MBB = MF->CreateMachineBasicBlock();

  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
                      0, nullptr, nullptr, nullptr, 0, nullptr};

  auto MII = MBB->begin();
  MachineInstrSpan MIS(MII, MBB);
  ASSERT_TRUE(MIS.empty());

  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
  MBB->insert(MII, MI);
  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
}

TEST(MachineInstrSpan, DistanceEnd) {
  auto MF = createMachineFunction();
  auto MBB = MF->CreateMachineBasicBlock();

  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
                      0, nullptr, nullptr, nullptr, 0, nullptr};

  auto MII = MBB->end();
  MachineInstrSpan MIS(MII, MBB);
  ASSERT_TRUE(MIS.empty());

  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
  MBB->insert(MII, MI);
  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
}

static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");

} // end namespace
<commit_msg>[unittest] Add the missing bogus machine register info initialization.<commit_after>//===- MachineInstrTest.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {
// Add a few Bogus backend classes so we can create MachineInstrs without
// depending on a real target.
class BogusTargetLowering : public TargetLowering {
public:
  BogusTargetLowering(TargetMachine &TM) : TargetLowering(TM) {}
};

class BogusFrameLowering : public TargetFrameLowering {
public:
  BogusFrameLowering()
      : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 4) {}

  void emitPrologue(MachineFunction &MF,
                    MachineBasicBlock &MBB) const override {}
  void emitEpilogue(MachineFunction &MF,
                    MachineBasicBlock &MBB) const override {}
  bool hasFP(const MachineFunction &MF) const override { return false; }
};

static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};

class BogusRegisterInfo : public TargetRegisterInfo {
public:
  BogusRegisterInfo()
      : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
                           nullptr, nullptr, LaneBitmask(~0u), nullptr) {
    InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
                       nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
  }

  const MCPhysReg *
  getCalleeSavedRegs(const MachineFunction *MF) const override {
    return nullptr;
  }
  ArrayRef<const uint32_t *> getRegMasks() const override { return None; }
  ArrayRef<const char *> getRegMaskNames() const override { return None; }
  BitVector getReservedRegs(const MachineFunction &MF) const override {
    return BitVector();
  }
  const RegClassWeight &
  getRegClassWeight(const TargetRegisterClass *RC) const override {
    static RegClassWeight Bogus{1, 16};
    return Bogus;
  }
  unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; }
  unsigned getNumRegPressureSets() const override { return 0; }
  const char *getRegPressureSetName(unsigned Idx) const override {
    return "bogus";
  }
  unsigned getRegPressureSetLimit(const MachineFunction &MF,
                                  unsigned Idx) const override {
    return 0;
  }
  const int *
  getRegClassPressureSets(const TargetRegisterClass *RC) const override {
    static const int Bogus[] = {0, -1};
    return &Bogus[0];
  }
  const int *getRegUnitPressureSets(unsigned RegUnit) const override {
    static const int Bogus[] = {0, -1};
    return &Bogus[0];
  }

  Register getFrameRegister(const MachineFunction &MF) const override {
    return 0;
  }
  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS = nullptr) const override {}
};

class BogusSubtarget : public TargetSubtargetInfo {
public:
  BogusSubtarget(TargetMachine &TM)
      : TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr,
                            nullptr, nullptr, nullptr, nullptr),
        FL(), TL(TM) {}
  ~BogusSubtarget() override {}

  const TargetFrameLowering *getFrameLowering() const override { return &FL; }

  const TargetLowering *getTargetLowering() const override { return &TL; }

  const TargetInstrInfo *getInstrInfo() const override { return &TII; }

  const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }

private:
  BogusFrameLowering FL;
  BogusRegisterInfo TRI;
  BogusTargetLowering TL;
  TargetInstrInfo TII;
};

class BogusTargetMachine : public LLVMTargetMachine {
public:
  BogusTargetMachine()
      : LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
                          Reloc::Static, CodeModel::Small, CodeGenOpt::Default),
        ST(*this) {}
  ~BogusTargetMachine() override {}

  const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
    return &ST;
  }

private:
  BogusSubtarget ST;
};

std::unique_ptr<BogusTargetMachine> createTargetMachine() {
  return llvm::make_unique<BogusTargetMachine>();
}

std::unique_ptr<MachineFunction> createMachineFunction() {
  LLVMContext Ctx;
  Module M("Module", Ctx);
  auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
  auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M);

  auto TM = createTargetMachine();
  unsigned FunctionNum = 42;
  MachineModuleInfo MMI(TM.get());
  const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F);

  return llvm::make_unique<MachineFunction>(*F, *TM, STI, FunctionNum, MMI);
}

// This test makes sure that MachineInstr::isIdenticalTo handles Defs correctly
// for various combinations of IgnoreDefs, and also that it is symmetrical.
TEST(IsIdenticalToTest, DifferentDefs) {
  auto MF = createMachineFunction();

  unsigned short NumOps = 2;
  unsigned char NumDefs = 1;
  MCOperandInfo OpInfo[] = {
      {0, 0, MCOI::OPERAND_REGISTER, 0},
      {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  MCInstrDesc MCID = {
      0, NumOps,  NumDefs, 0,      0, 1ULL << MCID::HasOptionalDef,
      0, nullptr, nullptr, OpInfo, 0, nullptr};

  // Create two MIs with different virtual reg defs and the same uses.
  unsigned VirtualDef1 = -42; // The value doesn't matter, but the sign does.
  unsigned VirtualDef2 = -43;
  unsigned VirtualUse = -44;

  auto MI1 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  MI1->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));

  auto MI2 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  MI2->addOperand(*MF, MachineOperand::CreateReg(VirtualUse, /*isDef*/ false));

  // Check that they are identical when we ignore virtual register defs, but not
  // when we check defs.
  ASSERT_FALSE(MI1->isIdenticalTo(*MI2, MachineInstr::CheckDefs));
  ASSERT_FALSE(MI2->isIdenticalTo(*MI1, MachineInstr::CheckDefs));

  ASSERT_TRUE(MI1->isIdenticalTo(*MI2, MachineInstr::IgnoreVRegDefs));
  ASSERT_TRUE(MI2->isIdenticalTo(*MI1, MachineInstr::IgnoreVRegDefs));

  // Create two MIs with different virtual reg defs, and a def or use of a
  // sentinel register.
  unsigned SentinelReg = 0;

  auto MI3 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI3->addOperand(*MF, MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  MI3->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));

  auto MI4 = MF->CreateMachineInstr(MCID, DebugLoc());
  MI4->addOperand(*MF, MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  MI4->addOperand(*MF, MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));

  // Check that they are never identical.
  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::CheckDefs));
  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::CheckDefs));

  ASSERT_FALSE(MI3->isIdenticalTo(*MI4, MachineInstr::IgnoreVRegDefs));
  ASSERT_FALSE(MI4->isIdenticalTo(*MI3, MachineInstr::IgnoreVRegDefs));
}

// Check that MachineInstrExpressionTrait::isEqual is symmetric and in sync with
// MachineInstrExpressionTrait::getHashValue
void checkHashAndIsEqualMatch(MachineInstr *MI1, MachineInstr *MI2) {
  bool IsEqual1 = MachineInstrExpressionTrait::isEqual(MI1, MI2);
  bool IsEqual2 = MachineInstrExpressionTrait::isEqual(MI2, MI1);

  ASSERT_EQ(IsEqual1, IsEqual2);

  auto Hash1 = MachineInstrExpressionTrait::getHashValue(MI1);
  auto Hash2 = MachineInstrExpressionTrait::getHashValue(MI2);

  ASSERT_EQ(IsEqual1, Hash1 == Hash2);
}

// This test makes sure that MachineInstrExpressionTraits::isEqual is in sync
// with MachineInstrExpressionTraits::getHashValue.
TEST(MachineInstrExpressionTraitTest, IsEqualAgreesWithGetHashValue) {
  auto MF = createMachineFunction();

  unsigned short NumOps = 2;
  unsigned char NumDefs = 1;
  MCOperandInfo OpInfo[] = {
      {0, 0, MCOI::OPERAND_REGISTER, 0},
      {0, 1 << MCOI::OptionalDef, MCOI::OPERAND_REGISTER, 0}};
  MCInstrDesc MCID = {
      0, NumOps,  NumDefs, 0,      0, 1ULL << MCID::HasOptionalDef,
      0, nullptr, nullptr, OpInfo, 0, nullptr};

  // Define a series of instructions with different kinds of operands and make
  // sure that the hash function is consistent with isEqual for various
  // combinations of them.
  unsigned VirtualDef1 = -42;
  unsigned VirtualDef2 = -43;
  unsigned VirtualReg = -44;
  unsigned SentinelReg = 0;
  unsigned PhysicalReg = 45;

  auto VD1VU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));

  auto VD2VU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2VU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualReg, /*isDef*/ false));

  auto VD1SU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1SU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1SU->addOperand(*MF,
                    MachineOperand::CreateReg(SentinelReg, /*isDef*/ false));

  auto VD1SD = MF->CreateMachineInstr(MCID, DebugLoc());
  VD1SD->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef1, /*isDef*/ true));
  VD1SD->addOperand(*MF,
                    MachineOperand::CreateReg(SentinelReg, /*isDef*/ true));

  auto VD2PU = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2PU->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2PU->addOperand(*MF,
                    MachineOperand::CreateReg(PhysicalReg, /*isDef*/ false));

  auto VD2PD = MF->CreateMachineInstr(MCID, DebugLoc());
  VD2PD->addOperand(*MF,
                    MachineOperand::CreateReg(VirtualDef2, /*isDef*/ true));
  VD2PD->addOperand(*MF,
                    MachineOperand::CreateReg(PhysicalReg, /*isDef*/ true));

  checkHashAndIsEqualMatch(VD1VU, VD2VU);
  checkHashAndIsEqualMatch(VD1VU, VD1SU);
  checkHashAndIsEqualMatch(VD1VU, VD1SD);
  checkHashAndIsEqualMatch(VD1VU, VD2PU);
  checkHashAndIsEqualMatch(VD1VU, VD2PD);

  checkHashAndIsEqualMatch(VD2VU, VD1SU);
  checkHashAndIsEqualMatch(VD2VU, VD1SD);
  checkHashAndIsEqualMatch(VD2VU, VD2PU);
  checkHashAndIsEqualMatch(VD2VU, VD2PD);

  checkHashAndIsEqualMatch(VD1SU, VD1SD);
  checkHashAndIsEqualMatch(VD1SU, VD2PU);
  checkHashAndIsEqualMatch(VD1SU, VD2PD);

  checkHashAndIsEqualMatch(VD1SD, VD2PU);
  checkHashAndIsEqualMatch(VD1SD, VD2PD);

  checkHashAndIsEqualMatch(VD2PU, VD2PD);
}

TEST(MachineInstrPrintingTest, DebugLocPrinting) {
  auto MF = createMachineFunction();

  MCOperandInfo OpInfo{0, 0, MCOI::OPERAND_REGISTER, 0};
  MCInstrDesc MCID = {0, 1,       1,       0,       0, 0,
                      0, nullptr, nullptr, &OpInfo, 0, nullptr};

  LLVMContext Ctx;
  DIFile *DIF = DIFile::getDistinct(Ctx, "filename", "");
  DISubprogram *DIS = DISubprogram::getDistinct(
      Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero,
      DISubprogram::SPFlagZero, nullptr);
  DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS);
  DebugLoc DL(DIL);
  MachineInstr *MI = MF->CreateMachineInstr(MCID, DL);
  MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ true));

  std::string str;
  raw_string_ostream OS(str);
  MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
            /*AddNewLine*/false);
  ASSERT_TRUE(
      StringRef(OS.str()).startswith("$noreg = UNKNOWN debug-location "));
  ASSERT_TRUE(
      StringRef(OS.str()).endswith("filename:1:5"));
}

TEST(MachineInstrSpan, DistanceBegin) {
  auto MF = createMachineFunction();
  auto MBB = MF->CreateMachineBasicBlock();

  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
                      0, nullptr, nullptr, nullptr, 0, nullptr};

  auto MII = MBB->begin();
  MachineInstrSpan MIS(MII, MBB);
  ASSERT_TRUE(MIS.empty());

  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
  MBB->insert(MII, MI);
  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
}

TEST(MachineInstrSpan, DistanceEnd) {
  auto MF = createMachineFunction();
  auto MBB = MF->CreateMachineBasicBlock();

  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
                      0, nullptr, nullptr, nullptr, 0, nullptr};

  auto MII = MBB->end();
  MachineInstrSpan MIS(MII, MBB);
  ASSERT_TRUE(MIS.empty());

  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
  MBB->insert(MII, MI);
  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
}

static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");

} // end namespace
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ucblockbytes.hxx,v $
 *
 *  $Revision: 1.26 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-20 15:29:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _UNTOOLS_UCBLOCKBYTES_HXX
#define _UNTOOLS_UCBLOCKBYTES_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_
#include <com/sun/star/ucb/XContent.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef INCLUDED_UNOTOOLSDLLAPI_H
#include "unotools/unotoolsdllapi.h"
#endif

#include <vos/thread.hxx>
#include <vos/conditn.hxx>
#include <vos/mutex.hxx>
#include <tools/stream.hxx>
#include <tools/link.hxx>
#include <tools/errcode.hxx>
#include <tools/datetime.hxx>

namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace task
            {
                class XInteractionHandler;
            }
            namespace io
            {
                class XStream;
                class XInputStream;
                class XOutputStream;
                class XSeekable;
            }
            namespace ucb
            {
                class XContent;
            }
            namespace beans
            {
                struct PropertyValue;
            }
        }
    }
}

namespace utl
{
SV_DECL_REF( UcbLockBytes )

class UcbLockBytesHandler : public SvRefBase
{
    sal_Bool        m_bActive;
public:
    enum LoadHandlerItem
    {
        DATA_AVAILABLE,
        DONE,
        CANCEL
    };

                    UcbLockBytesHandler()
                        : m_bActive( sal_True )
                    {}

    virtual void    Handle( LoadHandlerItem nWhich, UcbLockBytesRef xLockBytes ) = 0;
    void            Activate( BOOL bActivate = sal_True ) { m_bActive = bActivate; }
    sal_Bool        IsActive() const { return m_bActive; }
};

SV_DECL_IMPL_REF( UcbLockBytesHandler )

#define NS_UNO ::com::sun::star::uno
#define NS_IO ::com::sun::star::io
#define NS_UCB ::com::sun::star::ucb
#define NS_BEANS ::com::sun::star::beans
#define NS_TASK ::com::sun::star::task

class UNOTOOLS_DLLPUBLIC UcbLockBytes : public virtual SvLockBytes
{
    vos::OCondition         m_aInitialized;
    vos::OCondition         m_aTerminated;
    vos::OMutex             m_aMutex;

    String                  m_aContentType;
    String                  m_aRealURL;
    DateTime                m_aExpireDate;

    NS_UNO::Reference < NS_IO::XInputStream >  m_xInputStream;
    NS_UNO::Reference < NS_IO::XOutputStream > m_xOutputStream;
    NS_UNO::Reference < NS_IO::XSeekable >     m_xSeekable;
    void*                   m_pCommandThread; // is alive only for compatibility reasons
    UcbLockBytesHandlerRef  m_xHandler;

    sal_uInt32              m_nRead;
    sal_uInt32              m_nSize;
    ErrCode                 m_nError;

    sal_Bool                m_bTerminated : 1;
    sal_Bool                m_bDontClose : 1;
    sal_Bool                m_bStreamValid : 1;

    DECL_LINK(              DataAvailHdl, void * );

                            UcbLockBytes( UcbLockBytesHandler* pHandler=NULL );
protected:
    virtual                 ~UcbLockBytes (void);

public:
                            // properties: Referer, PostMimeType
    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_UCB::XContent >& xContent,
                                            const ::rtl::OUString& rReferer,
                                            const ::rtl::OUString& rMediaType,
                                            const NS_UNO::Reference < NS_IO::XInputStream >& xPostData,
                                            const NS_UNO::Reference < NS_TASK::XInteractionHandler >& xInter,
                                            UcbLockBytesHandler* pHandler=0 );

    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_UCB::XContent >& xContent,
                                            const NS_UNO::Sequence < NS_BEANS::PropertyValue >& rProps,
                                            StreamMode eMode,
                                            const NS_UNO::Reference < NS_TASK::XInteractionHandler >& xInter,
                                            UcbLockBytesHandler* pHandler=0 );

    static UcbLockBytesRef  CreateInputLockBytes( const NS_UNO::Reference < NS_IO::XInputStream >& xContent );
    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_IO::XStream >& xContent );

    // SvLockBytes
    virtual void            SetSynchronMode (BOOL bSynchron);
    virtual ErrCode         ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const;
    virtual ErrCode         WriteAt ( ULONG, const void*, ULONG, ULONG *pWritten);
    virtual ErrCode         Flush (void) const;
    virtual ErrCode         SetSize (ULONG);
    virtual ErrCode         Stat ( SvLockBytesStat *pStat, SvLockBytesStatFlag) const;

    void                    SetError( ErrCode nError )
                            { m_nError = nError; }

    ErrCode                 GetError() const
                            { return m_nError; }

    void                    Cancel(); // is alive only for compatibility reasons

    // the following properties are available when and after the first DataAvailable callback has been executed
    String                  GetContentType() const;
    String                  GetRealURL() const;
    DateTime                GetExpireDate() const;

    // calling this method delegates the responsibility to call closeinput to the caller!
    NS_UNO::Reference < NS_IO::XInputStream > getInputStream();
    NS_UNO::Reference < NS_IO::XStream > getStream();

#if _SOLAR__PRIVATE
    sal_Bool                setInputStream_Impl( const NS_UNO::Reference < NS_IO::XInputStream > &rxInputStream,
                                                 sal_Bool bSetXSeekable = sal_True );
    sal_Bool                setStream_Impl( const NS_UNO::Reference < NS_IO::XStream > &rxStream );
    void                    terminate_Impl (void);

    NS_UNO::Reference < NS_IO::XInputStream > getInputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xInputStream;
                            }

    NS_UNO::Reference < NS_IO::XOutputStream > getOutputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xOutputStream;
                            }

    NS_UNO::Reference < NS_IO::XSeekable > getSeekable_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xSeekable;
                            }

    sal_Bool                hasInputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xInputStream.is();
                            }

    void                    setDontClose_Impl()
                            { m_bDontClose = sal_True; }

    void                    SetContentType_Impl( const String& rType ) { m_aContentType = rType; }
    void                    SetRealURL_Impl( const String& rURL )  { m_aRealURL = rURL; }
    void                    SetExpireDate_Impl( const DateTime& rDateTime )  { m_aExpireDate = rDateTime; }
    void                    SetStreamValid_Impl();
#endif
};

SV_IMPL_REF( UcbLockBytes );

}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.26.4); FILE MERGED 2008/04/01 16:03:29 thb 1.26.4.3: #i85898# Stripping all external header guards 2008/04/01 12:59:45 thb 1.26.4.2: #i85898# Stripping all external header guards 2008/03/31 13:03:36 rt 1.26.4.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ucblockbytes.hxx,v $
 * $Revision: 1.27 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _UNTOOLS_UCBLOCKBYTES_HXX
#define _UNTOOLS_UCBLOCKBYTES_HXX

#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include "unotools/unotoolsdllapi.h"

#include <vos/thread.hxx>
#include <vos/conditn.hxx>
#include <vos/mutex.hxx>
#include <tools/stream.hxx>
#include <tools/link.hxx>
#include <tools/errcode.hxx>
#include <tools/datetime.hxx>

namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace task
            {
                class XInteractionHandler;
            }
            namespace io
            {
                class XStream;
                class XInputStream;
                class XOutputStream;
                class XSeekable;
            }
            namespace ucb
            {
                class XContent;
            }
            namespace beans
            {
                struct PropertyValue;
            }
        }
    }
}

namespace utl
{
SV_DECL_REF( UcbLockBytes )

class UcbLockBytesHandler : public SvRefBase
{
    sal_Bool        m_bActive;
public:
    enum LoadHandlerItem
    {
        DATA_AVAILABLE,
        DONE,
        CANCEL
    };

                    UcbLockBytesHandler()
                        : m_bActive( sal_True )
                    {}

    virtual void    Handle( LoadHandlerItem nWhich, UcbLockBytesRef xLockBytes ) = 0;
    void            Activate( BOOL bActivate = sal_True ) { m_bActive = bActivate; }
    sal_Bool        IsActive() const { return m_bActive; }
};

SV_DECL_IMPL_REF( UcbLockBytesHandler )

#define NS_UNO ::com::sun::star::uno
#define NS_IO ::com::sun::star::io
#define NS_UCB ::com::sun::star::ucb
#define NS_BEANS ::com::sun::star::beans
#define NS_TASK ::com::sun::star::task

class UNOTOOLS_DLLPUBLIC UcbLockBytes : public virtual SvLockBytes
{
    vos::OCondition         m_aInitialized;
    vos::OCondition         m_aTerminated;
    vos::OMutex             m_aMutex;

    String                  m_aContentType;
    String                  m_aRealURL;
    DateTime                m_aExpireDate;

    NS_UNO::Reference < NS_IO::XInputStream >  m_xInputStream;
    NS_UNO::Reference < NS_IO::XOutputStream > m_xOutputStream;
    NS_UNO::Reference < NS_IO::XSeekable >     m_xSeekable;
    void*                   m_pCommandThread; // is alive only for compatibility reasons
    UcbLockBytesHandlerRef  m_xHandler;

    sal_uInt32              m_nRead;
    sal_uInt32              m_nSize;
    ErrCode                 m_nError;

    sal_Bool                m_bTerminated : 1;
    sal_Bool                m_bDontClose : 1;
    sal_Bool                m_bStreamValid : 1;

    DECL_LINK(              DataAvailHdl, void * );

                            UcbLockBytes( UcbLockBytesHandler* pHandler=NULL );
protected:
    virtual                 ~UcbLockBytes (void);

public:
                            // properties: Referer, PostMimeType
    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_UCB::XContent >& xContent,
                                            const ::rtl::OUString& rReferer,
                                            const ::rtl::OUString& rMediaType,
                                            const NS_UNO::Reference < NS_IO::XInputStream >& xPostData,
                                            const NS_UNO::Reference < NS_TASK::XInteractionHandler >& xInter,
                                            UcbLockBytesHandler* pHandler=0 );

    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_UCB::XContent >& xContent,
                                            const NS_UNO::Sequence < NS_BEANS::PropertyValue >& rProps,
                                            StreamMode eMode,
                                            const NS_UNO::Reference < NS_TASK::XInteractionHandler >& xInter,
                                            UcbLockBytesHandler* pHandler=0 );

    static UcbLockBytesRef  CreateInputLockBytes( const NS_UNO::Reference < NS_IO::XInputStream >& xContent );
    static UcbLockBytesRef  CreateLockBytes( const NS_UNO::Reference < NS_IO::XStream >& xContent );

    // SvLockBytes
    virtual void            SetSynchronMode (BOOL bSynchron);
    virtual ErrCode         ReadAt ( ULONG nPos, void *pBuffer, ULONG nCount, ULONG *pRead) const;
    virtual ErrCode         WriteAt ( ULONG, const void*, ULONG, ULONG *pWritten);
    virtual ErrCode         Flush (void) const;
    virtual ErrCode         SetSize (ULONG);
    virtual ErrCode         Stat ( SvLockBytesStat *pStat, SvLockBytesStatFlag) const;

    void                    SetError( ErrCode nError )
                            { m_nError = nError; }

    ErrCode                 GetError() const
                            { return m_nError; }

    void                    Cancel(); // is alive only for compatibility reasons

    // the following properties are available when and after the first DataAvailable callback has been executed
    String                  GetContentType() const;
    String                  GetRealURL() const;
    DateTime                GetExpireDate() const;

    // calling this method delegates the responsibility to call closeinput to the caller!
    NS_UNO::Reference < NS_IO::XInputStream > getInputStream();
    NS_UNO::Reference < NS_IO::XStream > getStream();

#if _SOLAR__PRIVATE
    sal_Bool                setInputStream_Impl( const NS_UNO::Reference < NS_IO::XInputStream > &rxInputStream,
                                                 sal_Bool bSetXSeekable = sal_True );
    sal_Bool                setStream_Impl( const NS_UNO::Reference < NS_IO::XStream > &rxStream );
    void                    terminate_Impl (void);

    NS_UNO::Reference < NS_IO::XInputStream > getInputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xInputStream;
                            }

    NS_UNO::Reference < NS_IO::XOutputStream > getOutputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xOutputStream;
                            }

    NS_UNO::Reference < NS_IO::XSeekable > getSeekable_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xSeekable;
                            }

    sal_Bool                hasInputStream_Impl() const
                            {
                                vos::OGuard aGuard( SAL_CONST_CAST(UcbLockBytes*, this)->m_aMutex );
                                return m_xInputStream.is();
                            }

    void                    setDontClose_Impl()
                            { m_bDontClose = sal_True; }

    void                    SetContentType_Impl( const String& rType ) { m_aContentType = rType; }
    void                    SetRealURL_Impl( const String& rURL )  { m_aRealURL = rURL; }
    void                    SetExpireDate_Impl( const DateTime& rDateTime )  { m_aExpireDate = rDateTime; }
    void                    SetStreamValid_Impl();
#endif
};

SV_IMPL_REF( UcbLockBytes );

}

#endif
<|endoftext|>


<commit_before>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

                Copyright (c) 2003-2019, Cauldron Development LLC
                   Copyright (c) 2003-2017, Stanford University
                               All rights reserved.

         The C! 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.

        The C! 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 the C! library.  If not, see
                         <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
           You may request written permission by emailing the authors.

                  For information regarding this software email:
                                 Joseph Coffland
                          joseph@cauldrondevelopment.com

\******************************************************************************/

#include "HTTPRequestHandler.h"

#include <cbang/json/Writer.h>
#include <cbang/log/Logger.h>

using namespace cb::Event;
using namespace std;

bool HTTPRequestJSONHandler::operator()(Request &req) {
  try {
    // Parse JSON message
    JSON::ValuePtr msg = req.getJSONMessage();

    // Log JSON call
    const string &path = req.getURI().getPath();
    if (msg.isNull()) LOG_DEBUG(5, "JSON Call: " << path << "()");
    else LOG_DEBUG(5, "JSON Call: " << path << '(' << *msg << ')');

    // Dispatch JSON call
    (*this)(req, msg);

    // Send reply
    req.reply();

  } catch (const Exception &e) {
    if (400 <= e.getCode() && e.getCode() < 600) LOG_WARNING(e.getMessages());
    else LOG_ERROR(e);

    req.setContentType("application/json");
    req.sendError(e);
  }

  return true;
}
<commit_msg>Don't send full exception information for normal HTTP errors<commit_after>/******************************************************************************\

          This file is part of the C! library.  A.K.A the cbang library.

                Copyright (c) 2003-2019, Cauldron Development LLC
                   Copyright (c) 2003-2017, Stanford University
                               All rights reserved.

         The C! 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.

        The C! 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 the C! library.  If not, see
                         <http://www.gnu.org/licenses/>.

        In addition, BSD licensing may be granted on a case by case basis
        by written permission from at least one of the copyright holders.
           You may request written permission by emailing the authors.

                  For information regarding this software email:
                                 Joseph Coffland
                          joseph@cauldrondevelopment.com

\******************************************************************************/

#include "HTTPRequestHandler.h"

#include <cbang/json/Writer.h>
#include <cbang/log/Logger.h>

using namespace cb::Event;
using namespace std;

bool HTTPRequestJSONHandler::operator()(Request &req) {
  try {
    // Parse JSON message
    JSON::ValuePtr msg = req.getJSONMessage();

    // Log JSON call
    const string &path = req.getURI().getPath();
    if (msg.isNull()) LOG_DEBUG(5, "JSON Call: " << path << "()");
    else LOG_DEBUG(5, "JSON Call: " << path << '(' << *msg << ')');

    // Dispatch JSON call
    (*this)(req, msg);

    // Send reply
    req.reply();

  } catch (const Exception &e) {
    req.setContentType("application/json");

    if (400 <= e.getCode() && e.getCode() < 600) {
      LOG_WARNING(e.getMessages());
      req.sendJSONError((HTTPStatus::enum_t)e.getCode(), e.getMessage());

    } else {
      LOG_ERROR(e);
      req.sendError(e);
    }
  }

  return true;
}
<|endoftext|>


<commit_before>#include "susi/HeartBeat.h"

HeartBeat::HeartBeat(std::string addr,short port, std::string key, std::string cert) :
  susi_{new Susi::SusiClient{addr,port,key,cert}} {
      runloop_ = std::move(std::thread{[this](){
          int count = 0;
          std::chrono::milliseconds interval{100};
          while( !this->stopVar_.load() ) {
              ++count %= 3000;
              if( count % 10 == 0) {
                  susi_->publish( susi_->createEvent( "heartbeat::one" ) );
              }
              if( count % 50 == 0 ) {
                  susi_->publish( susi_->createEvent( "heartbeat::five" ) );
              }
              if( count % 100 == 0 ) {
                  susi_->publish( susi_->createEvent( "heartbeat::ten" ) );
              }
              if( count % 600 == 0 ) {
                  susi_->publish( susi_->createEvent( "heartbeat::minute" ) );
              }
              if( count % 3000 == 0 ) {
                  susi_->publish( susi_->createEvent( "heartbeat::fiveMinute" ) );
              }
              std::this_thread::sleep_for(interval);
          }
      }});
}

void HeartBeat::join(){
	susi_->join();
}
<commit_msg>[heartbeat] added 'No-Ack' event control header to heartbeat events (we do not need an ack here);<commit_after>#include "susi/HeartBeat.h"

HeartBeat::HeartBeat(std::string addr,short port, std::string key, std::string cert) :
  susi_{new Susi::SusiClient{addr,port,key,cert}} {
      runloop_ = std::move(std::thread{[this](){
          int count = 0;
          std::chrono::milliseconds interval{100};
          while( !this->stopVar_.load() ) {
              ++count %= 3000;
              if( count % 10 == 0) {
                  auto event = susi_->createEvent("heartbeat::one");
                  event->headers.push_back({"Event-Control","No-Ack"});
                  susi_->publish(std::move(event));
              }
              if( count % 50 == 0 ) {
                  auto event = susi_->createEvent("heartbeat::five");
                  event->headers.push_back({"Event-Control","No-Ack"});
                  susi_->publish(std::move(event));
              }
              if( count % 100 == 0 ) {
                  auto event = susi_->createEvent("heartbeat::ten");
                  event->headers.push_back({"Event-Control","No-Ack"});
                  susi_->publish(std::move(event));
              }
              if( count % 600 == 0 ) {
                  auto event = susi_->createEvent("heartbeat::minute");
                  event->headers.push_back({"Event-Control","No-Ack"});
                  susi_->publish(std::move(event));
              }
              if( count % 3000 == 0 ) {
                  auto event = susi_->createEvent("heartbeat::fiveMinute");
                  event->headers.push_back({"Event-Control","No-Ack"});
                  susi_->publish(std::move(event));
              }
              std::this_thread::sleep_for(interval);
          }
      }});
}

void HeartBeat::join(){
	susi_->join();
}
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head) {
            for (ListNode *odd_tail = head, *cur = head->next;
                 cur && cur->next;
                 cur = cur->next) {

                ListNode *even_head = odd_tail->next;
                odd_tail->next = cur->next;
                odd_tail = odd_tail->next;
                cur->next = odd_tail->next;
                odd_tail->next = even_head;
            }
        }
        return head;
    }
};
<commit_msg>Update odd-even-linked-list.cpp<commit_after>// Time:  O(n)
// Space: O(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if (head) {
            for (ListNode *odd_tail = head, *cur = head->next;
                 cur && cur->next;
                 cur = cur->next) {
                ListNode *even_head = odd_tail->next;
                odd_tail->next = cur->next;
                odd_tail = odd_tail->next;
                cur->next = odd_tail->next;
                odd_tail->next = even_head;
            }
        }
        return head;
    }
};
<|endoftext|>