<commit_before>#include "AConfig.h"
#if(HAS_CAMERASERVO)

// Includes
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "CCameraServo.h"
#include "CServo.h"
#include "CPin.h"
#include "NConfigManager.h"
#include "NDataManager.h"
#include "NModuleManager.h"
#include "NCommManager.h"
#include "CTimer.h"

#include "CControllerBoard.h"

// Defines
#ifndef F_CPU
    #define F_CPU 16000000UL
#endif

// File local variables and methods
namespace
{
    // Helper functions specifically for the HITEC servo
    constexpr uint32_t DegreesToMicroseconds( float degreesIn, bool isInverted = false )
    {
        return static_cast<uint32_t>( ( kMicrosecPerDegree * ( isInverted ? -degreesIn : degreesIn ) ) + kZeroPosMicrosecs );
    }

    constexpr float MicrosecondsToDegrees( uint32_t microsecondsIn, bool isInverted = false )
    {
        return ( isInverted ?   -( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec )
                                :( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec ) );
    }

    constexpr float kZeroPosMicrosecs       = 1487.0f;
    constexpr float kMicrosecPerDegree      = 9.523809f;
    constexpr float kDegPerMicrosec         = ( 1 / kMicrosecPerDegree );

    constexpr float kNeutralPosition_deg    = 0.0f;
    constexpr uint32_t kNeutralPosition_us  = DegreesToMicroseconds( 0.0f );

    constexpr float kDefaultSpeed           = 50.0f;    // Degrees per sec

    // Attributes
    CTimer m_controlTimer;
    CTimer m_telemetryTimer;

    float m_targetPos_deg       = kNeutralPosition_deg;
    float m_currentPos_deg      = kNeutralPosition_deg;
    uint32_t m_targetPos_us     = kNeutralPosition_us;
    uint32_t m_currentPos_us    = kNeutralPosition_us;
    float m_fCurrentPos_us      = kZeroPosMicrosecs;

    uint32_t m_tDelta           = 0;
    uint32_t m_tLast            = 0;

    // Settings
    float m_speed_deg_per_s     = kDefaultSpeed;
    int m_isInverted            = 0;                // 0 - Not inverted, 1 - Inverted

    // Derived from settings
    float m_speed_us_per_ms     = ( kDefaultSpeed * 0.001f ) * kMicrosecPerDegree;

    // Float<->Int conversion helpers
    constexpr int32_t Encode( float valueIn )
    {
        return static_cast<int32_t>( valueIn * 1000.0f );
    }

    constexpr float Decode( int32_t valueIn )
    {
        return ( static_cast<float>( valueIn ) * 0.001f );
    }

    void SetServoPosition( uint32_t microsecondsIn )
    {
        // Set to 90° --> pulsewdith = 1.5ms
        OCR1A = microsecondsIn * 2;
    }
}

void CCameraServo::Initialize()
{
    // Set up the pin for the camera servo
    pinMode( CAMERAMOUNT_PIN, OUTPUT );

    // Set up the timers driving the PWM for the servo (AVR specific)
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1A |= ( 1 << COM1A1 ) | ( 1 << WGM11 );					// non-inverting mode for OC1A
    TCCR1B |= ( 1 << WGM13 ) | ( 1 << WGM12 ) | ( 1 << CS11 );	// Mode 14, Prescaler 8

    ICR1 = 40000; // 320000 / 8 = 40000

    // Set initial position
    SetServoPosition( kNeutralPosition_us );

    // Mark camera servo as enabled
    NConfigManager::m_capabilityBitmask |= ( 1 << CAMERA_MOUNT_1_AXIS_CAPABLE );

    // Reset timers
    m_controlTimer.Reset();
    m_telemetryTimer.Reset();
}

void CCameraServo::Update( CCommand& command )
{
    // Check for messages
    if( NCommManager::m_isCommandAvailable )
    {
        // Handle messages
        if( command.Equals( "camServ_tpos" ) )
        {
            // TODO: Ideally this unit would have the ability to autonomously set its own target and ack receipt with a separate mechanism
            // Acknowledge target position
            Serial.print( F( "camServ_tpos:" ) );
            Serial.print( command.m_arguments[1] );
            Serial.println( ';' );

            // Update the target position
            m_targetPos_deg = Decode( command.m_arguments[1] );

            // Update the target microseconds
            m_targetPos_us = DegreesToMicroseconds( m_targetPos_deg, m_isInverted );
        }
        else if( command.Equals( "camServ_spd" ) )
        {
            // Acknowledge receipt of command
            Serial.print( F( "camServ_spd:" ) );
            Serial.print( command.m_arguments[1] );
            Serial.println( ';' );

            // Decode the requested speed and update the setting
            m_speed_deg_per_s   = Decode( command.m_arguments[1] );
            m_speed_us_per_ms   = ( m_speed_deg_per_s * 0.001f ) * kMicrosecPerDegree;
        }
        else if( command.Equals( "camServ_inv" ) )
        {
            if( command.m_arguments[1] == 1 )
            {
                // Set inverted
                m_isInverted = 1;

                // Report back
                Serial.print( F( "camServ_inv:1;" ) );
            }
            else if( command.m_arguments[1] == 0 )
            {
                // Set uninverted
                m_isInverted = 0;

                // Report back
                Serial.print( F( "camServ_inv:0;" ) );
            }
        }
    }

    // Run servo adjustment at 200Hz
    if( m_controlTimer.HasElapsed( 5 ) )
    {
        // Get time elapsed since last position update
        m_tDelta = millis() - m_tLast;

        // Update position if not at desired location
        if( m_currentPos_us != m_targetPos_us )
        {
            float error = static_cast<float>( m_targetPos_us ) - m_fCurrentPos_us;

            // Check to see if the error/dT is smaller than the speed limit
            if( ( error / static_cast<float>( m_tDelta ) ) < m_speed_us_per_ms )
            {
                // Move directly to the target
                // NOTE: Cannot use the cast method like below, since the floating point
                // representation of the target pos might be comparatively less than the integer value.
                // I.e. target = 32, static_cast<float>( 32 ) -> 31.99999, static_cast<uint32_t>( 31.99999 ) -> 31
                // This could lead to the current position never reaching the target
                m_currentPos_us = m_targetPos_us;

                // Update the floating point representation as well, for use in future target updates
                m_fCurrentPos_us = static_cast<float>( m_targetPos_us );
            }
            else
            {
                // Move by the delta towards the target
                m_fCurrentPos_us += ( m_speed_us_per_ms * error );

                // Cast the floating point servo command to an integer
                m_currentPos_us = static_cast<uint32_t>( m_fCurrentPos_us );
            }

            // Set the servo to this target
            SetServoPosition( m_currentPos_us );

            // Update the position value in degrees
            m_currentPos_deg = MicrosecondsToDegrees( m_currentPos_us );
        }

        m_tLast = millis();
    }

    // Emit position telemetry at 10Hz
    if( m_telemetryTimer.HasElapsed( 100 ) )
    {
        Serial.print( F( "camServ_pos:" ) );
        Serial.print( Encode( m_currentPos_deg ) );
        Serial.println( ';' );
    }
}

#endif
<commit_msg>Fixed ordering of variables<commit_after>#include "AConfig.h"
#if(HAS_CAMERASERVO)

// Includes
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "CCameraServo.h"
#include "CServo.h"
#include "CPin.h"
#include "NConfigManager.h"
#include "NDataManager.h"
#include "NModuleManager.h"
#include "NCommManager.h"
#include "CTimer.h"

#include "CControllerBoard.h"

// Defines
#ifndef F_CPU
    #define F_CPU 16000000UL
#endif

// File local variables and methods
namespace
{
    constexpr float kZeroPosMicrosecs       = 1487.0f;
    constexpr float kMicrosecPerDegree      = 9.523809f;
    constexpr float kDegPerMicrosec         = ( 1 / kMicrosecPerDegree );

    // Helper functions specifically for the HITEC servo
    constexpr uint32_t DegreesToMicroseconds( float degreesIn, bool isInverted = false )
    {
        return static_cast<uint32_t>( ( kMicrosecPerDegree * ( isInverted ? -degreesIn : degreesIn ) ) + kZeroPosMicrosecs );
    }

    constexpr float MicrosecondsToDegrees( uint32_t microsecondsIn, bool isInverted = false )
    {
        return ( isInverted ?   -( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec )
                                :( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec ) );
    }

    constexpr float kNeutralPosition_deg    = 0.0f;
    constexpr uint32_t kNeutralPosition_us  = DegreesToMicroseconds( 0.0f );

    constexpr float kDefaultSpeed           = 50.0f;    // Degrees per sec

    // Attributes
    CTimer m_controlTimer;
    CTimer m_telemetryTimer;

    float m_targetPos_deg       = kNeutralPosition_deg;
    float m_currentPos_deg      = kNeutralPosition_deg;
    uint32_t m_targetPos_us     = kNeutralPosition_us;
    uint32_t m_currentPos_us    = kNeutralPosition_us;
    float m_fCurrentPos_us      = kZeroPosMicrosecs;

    uint32_t m_tDelta           = 0;
    uint32_t m_tLast            = 0;

    // Settings
    float m_speed_deg_per_s     = kDefaultSpeed;
    int m_isInverted            = 0;                // 0 - Not inverted, 1 - Inverted

    // Derived from settings
    float m_speed_us_per_ms     = ( kDefaultSpeed * 0.001f ) * kMicrosecPerDegree;

    // Float<->Int conversion helpers
    constexpr int32_t Encode( float valueIn )
    {
        return static_cast<int32_t>( valueIn * 1000.0f );
    }

    constexpr float Decode( int32_t valueIn )
    {
        return ( static_cast<float>( valueIn ) * 0.001f );
    }

    void SetServoPosition( uint32_t microsecondsIn )
    {
        // Set to 90° --> pulsewdith = 1.5ms
        OCR1A = microsecondsIn * 2;
    }
}

void CCameraServo::Initialize()
{
    // Set up the pin for the camera servo
    pinMode( CAMERAMOUNT_PIN, OUTPUT );

    // Set up the timers driving the PWM for the servo (AVR specific)
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1A |= ( 1 << COM1A1 ) | ( 1 << WGM11 );					// non-inverting mode for OC1A
    TCCR1B |= ( 1 << WGM13 ) | ( 1 << WGM12 ) | ( 1 << CS11 );	// Mode 14, Prescaler 8

    ICR1 = 40000; // 320000 / 8 = 40000

    // Set initial position
    SetServoPosition( kNeutralPosition_us );

    // Mark camera servo as enabled
    NConfigManager::m_capabilityBitmask |= ( 1 << CAMERA_MOUNT_1_AXIS_CAPABLE );

    // Reset timers
    m_controlTimer.Reset();
    m_telemetryTimer.Reset();
}

void CCameraServo::Update( CCommand& command )
{
    // Check for messages
    if( NCommManager::m_isCommandAvailable )
    {
        // Handle messages
        if( command.Equals( "camServ_tpos" ) )
        {
            // TODO: Ideally this unit would have the ability to autonomously set its own target and ack receipt with a separate mechanism
            // Acknowledge target position
            Serial.print( F( "camServ_tpos:" ) );
            Serial.print( command.m_arguments[1] );
            Serial.println( ';' );

            // Update the target position
            m_targetPos_deg = Decode( command.m_arguments[1] );

            // Update the target microseconds
            m_targetPos_us = DegreesToMicroseconds( m_targetPos_deg, m_isInverted );
        }
        else if( command.Equals( "camServ_spd" ) )
        {
            // Acknowledge receipt of command
            Serial.print( F( "camServ_spd:" ) );
            Serial.print( command.m_arguments[1] );
            Serial.println( ';' );

            // Decode the requested speed and update the setting
            m_speed_deg_per_s   = Decode( command.m_arguments[1] );
            m_speed_us_per_ms   = ( m_speed_deg_per_s * 0.001f ) * kMicrosecPerDegree;
        }
        else if( command.Equals( "camServ_inv" ) )
        {
            if( command.m_arguments[1] == 1 )
            {
                // Set inverted
                m_isInverted = 1;

                // Report back
                Serial.print( F( "camServ_inv:1;" ) );
            }
            else if( command.m_arguments[1] == 0 )
            {
                // Set uninverted
                m_isInverted = 0;

                // Report back
                Serial.print( F( "camServ_inv:0;" ) );
            }
        }
    }

    // Run servo adjustment at 200Hz
    if( m_controlTimer.HasElapsed( 5 ) )
    {
        // Get time elapsed since last position update
        m_tDelta = millis() - m_tLast;

        // Update position if not at desired location
        if( m_currentPos_us != m_targetPos_us )
        {
            float error = static_cast<float>( m_targetPos_us ) - m_fCurrentPos_us;

            // Check to see if the error/dT is smaller than the speed limit
            if( ( error / static_cast<float>( m_tDelta ) ) < m_speed_us_per_ms )
            {
                // Move directly to the target
                // NOTE: Cannot use the cast method like below, since the floating point
                // representation of the target pos might be comparatively less than the integer value.
                // I.e. target = 32, static_cast<float>( 32 ) -> 31.99999, static_cast<uint32_t>( 31.99999 ) -> 31
                // This could lead to the current position never reaching the target
                m_currentPos_us = m_targetPos_us;

                // Update the floating point representation as well, for use in future target updates
                m_fCurrentPos_us = static_cast<float>( m_targetPos_us );
            }
            else
            {
                // Move by the delta towards the target
                m_fCurrentPos_us += ( m_speed_us_per_ms * error );

                // Cast the floating point servo command to an integer
                m_currentPos_us = static_cast<uint32_t>( m_fCurrentPos_us );
            }

            // Set the servo to this target
            SetServoPosition( m_currentPos_us );

            // Update the position value in degrees
            m_currentPos_deg = MicrosecondsToDegrees( m_currentPos_us );
        }

        m_tLast = millis();
    }

    // Emit position telemetry at 10Hz
    if( m_telemetryTimer.HasElapsed( 100 ) )
    {
        Serial.print( F( "camServ_pos:" ) );
        Serial.print( Encode( m_currentPos_deg ) );
        Serial.println( ';' );
    }
}

#endif
<|endoftext|>


<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 "chrome/test/ui/ui_test.h"

#include "base/test/test_timeouts.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/browser/sync/signin_manager.h"
#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/testing_pref_service.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    set_homepage("");

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        ProxyLauncher::DEFAULT_THEME));
  }
};

TEST_F(NewTabUITest, NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // TopSites should return at least 3 non-filler pages.
  // 8 - 3 = max 5 filler pages.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('filler').length <= 5)",
      TestTimeouts::action_max_timeout_ms()));
}

// Sometimes hangs: http://crbug.com/70157
TEST_F(NewTabUITest, DISABLED_NTPHasLoginName) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  ASSERT_TRUE(window->SetStringPreference(prefs::kGoogleServicesUsername,
                                          "user@gmail.com"));
  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  std::wstring displayed_username;
  // The login span should be eventually populated and have the
  // correct value.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText.length > 0)",
      TestTimeouts::action_max_timeout_ms()));

  ASSERT_TRUE(tab->ExecuteAndExtractString(
      L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText)",
      &displayed_username));

  EXPECT_EQ(L"user@gmail.com", displayed_username);
}

// Loads chrome://hang/ into two NTP tabs, ensuring we don't crash.
// See http://crbug.com/59859.
TEST_F(NewTabUITest, ChromeHangInNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to chrome://hang/ to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));

  // Visit chrome://hang/ again in another NTP. Don't bother waiting for the
  // NTP to load, because it's hung.
  ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));
}

// Allows testing NTP in process-per-tab mode.
class NewTabUIProcessPerTabTest : public NewTabUITest {
 public:
  NewTabUIProcessPerTabTest() : NewTabUITest() {}

 protected:
  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kProcessPerTab);
    UITest::SetUp();
  }
};

// Navigates away from NTP before it commits, in process-per-tab mode.
// Ensures that we don't load the normal page in the NTP process (and thus
// crash), as in http://crbug.com/69224.
TEST_F(NewTabUIProcessPerTabTest, NavBeforeNTPCommits) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to chrome://hang/ to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));

  // Visit a normal URL in another NTP that hasn't committed.
  ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURL(GURL("data:text/html,hello world")));
}

// Fails about ~5% of the time on all platforms. http://crbug.com/45001
TEST_F(NewTabUITest, FLAKY_ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL("chrome-internal:")));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}

TEST_F(NewTabUITest, UpdateUserPrefsVersion) {
  // PrefService with JSON user-pref file only, no enforced or advised prefs.
  scoped_ptr<PrefService> prefs(new TestingPrefService);

  // Does the migration
  NewTabUI::RegisterUserPrefs(prefs.get());

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs->ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs->GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_FALSE(migrated);
}
<commit_msg>Mark NewTabUITest.NTPHasThumbnails as flaky on Linux.<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 "chrome/test/ui/ui_test.h"

#include "base/test/test_timeouts.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/browser/sync/signin_manager.h"
#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/testing_pref_service.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    set_homepage("");

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        ProxyLauncher::DEFAULT_THEME));
  }
};

#if defined(OS_LINUX)
// This test is flaky on Linux and CrOS: http://crbug/
#define MAYBE_NTPHasThumbnails FLAKY_NTPHasThumbnails
#else
#define MAYBE_NTPHasThumbnails NTPHasThumbnails
#endif
TEST_F(NewTabUITest, MAYBE_NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // TopSites should return at least 3 non-filler pages.
  // 8 - 3 = max 5 filler pages.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('filler').length <= 5)",
      TestTimeouts::action_max_timeout_ms()));
}

// Sometimes hangs: http://crbug.com/70157
TEST_F(NewTabUITest, DISABLED_NTPHasLoginName) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  ASSERT_TRUE(window->SetStringPreference(prefs::kGoogleServicesUsername,
                                          "user@gmail.com"));
  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  std::wstring displayed_username;
  // The login span should be eventually populated and have the
  // correct value.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText.length > 0)",
      TestTimeouts::action_max_timeout_ms()));

  ASSERT_TRUE(tab->ExecuteAndExtractString(
      L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText)",
      &displayed_username));

  EXPECT_EQ(L"user@gmail.com", displayed_username);
}

// Loads chrome://hang/ into two NTP tabs, ensuring we don't crash.
// See http://crbug.com/59859.
TEST_F(NewTabUITest, ChromeHangInNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to chrome://hang/ to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));

  // Visit chrome://hang/ again in another NTP. Don't bother waiting for the
  // NTP to load, because it's hung.
  ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));
}

// Allows testing NTP in process-per-tab mode.
class NewTabUIProcessPerTabTest : public NewTabUITest {
 public:
  NewTabUIProcessPerTabTest() : NewTabUITest() {}

 protected:
  virtual void SetUp() {
    launch_arguments_.AppendSwitch(switches::kProcessPerTab);
    UITest::SetUp();
  }
};

// Navigates away from NTP before it commits, in process-per-tab mode.
// Ensures that we don't load the normal page in the NTP process (and thus
// crash), as in http://crbug.com/69224.
TEST_F(NewTabUIProcessPerTabTest, NavBeforeNTPCommits) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to chrome://hang/ to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kChromeUIHangURL)));

  // Visit a normal URL in another NTP that hasn't committed.
  ASSERT_TRUE(window->RunCommandAsync(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURL(GURL("data:text/html,hello world")));
}

// Fails about ~5% of the time on all platforms. http://crbug.com/45001
TEST_F(NewTabUITest, FLAKY_ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL("chrome-internal:")));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}

TEST_F(NewTabUITest, UpdateUserPrefsVersion) {
  // PrefService with JSON user-pref file only, no enforced or advised prefs.
  scoped_ptr<PrefService> prefs(new TestingPrefService);

  // Does the migration
  NewTabUI::RegisterUserPrefs(prefs.get());

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs->ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs->GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_FALSE(migrated);
}
<|endoftext|>


<commit_before>#include "AConfig.h"
#if(HAS_CAMERASERVO)

// Includes
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "CCameraServo.h"
#include "CServo.h"
#include "CPin.h"
#include "NConfigManager.h"
#include "NDataManager.h"
#include "NModuleManager.h"
#include "NCommManager.h"
#include "CTimer.h"

#include "CControllerBoard.h"

// Defines
#ifndef F_CPU
    #define F_CPU 16000000UL
#endif

// File local variables and methods
namespace
{
    constexpr float kZeroPosMicrosecs       = 1487.0f;
    constexpr float kMicrosecPerDegree      = 9.523809f;
    constexpr float kDegPerMicrosec         = ( 1 / kMicrosecPerDegree );

    // Helper functions specifically for the HITEC servo
    constexpr uint32_t DegreesToMicroseconds( float degreesIn, bool isInverted = false )
    {
        return static_cast<uint32_t>( ( kMicrosecPerDegree * ( isInverted ? -degreesIn : degreesIn ) ) + kZeroPosMicrosecs );
    }

    constexpr float MicrosecondsToDegrees( uint32_t microsecondsIn, bool isInverted = false )
    {
        return ( isInverted ?   -( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec )
                                :( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec ) );
    }

    constexpr float kNeutralPosition_deg    = 0.0f;
    constexpr uint32_t kNeutralPosition_us  = DegreesToMicroseconds( 0.0f );

    constexpr float kDefaultSpeed           = 50.0f;    // Degrees per sec

    // Attributes
    CTimer m_controlTimer;
    CTimer m_telemetryTimer;

    float m_targetPos_deg       = kNeutralPosition_deg;
    float m_currentPos_deg      = kNeutralPosition_deg;
    uint32_t m_targetPos_us     = kNeutralPosition_us;
    uint32_t m_currentPos_us    = kNeutralPosition_us;
    float m_fCurrentPos_us      = kZeroPosMicrosecs;

    uint32_t m_tDelta           = 0;
    uint32_t m_tLast            = 0;

    // Settings
    float m_speed_deg_per_s     = kDefaultSpeed;
    int m_isInverted            = 0;                // 0 - Not inverted, 1 - Inverted

    // Derived from settings
    float m_speed_us_per_ms     = ( kDefaultSpeed * 0.001f ) * kMicrosecPerDegree;

    // Float<->Int conversion helpers
    constexpr int32_t Encode( float valueIn )
    {
        return static_cast<int32_t>( valueIn * 1000.0f );
    }

    constexpr float Decode( int32_t valueIn )
    {
        return ( static_cast<float>( valueIn ) * 0.001f );
    }

    void SetServoPosition( uint32_t microsecondsIn )
    {
        // Set to 90° --> pulsewdith = 1.5ms
        OCR1A = microsecondsIn * 2;
    }
}

void CCameraServo::Initialize()
{
    // Set up the pin for the camera servo
    pinMode( CAMERAMOUNT_PIN, OUTPUT );

    // Set up the timers driving the PWM for the servo (AVR specific)
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1A |= ( 1 << COM1A1 ) | ( 1 << WGM11 );					// non-inverting mode for OC1A
    TCCR1B |= ( 1 << WGM13 ) | ( 1 << WGM12 ) | ( 1 << CS11 );	// Mode 14, Prescaler 8

    ICR1 = 40000; // 320000 / 8 = 40000

    // Set initial position
    SetServoPosition( kNeutralPosition_us );

    // Mark camera servo as enabled
    NConfigManager::m_capabilityBitmask |= ( 1 << CAMERA_MOUNT_1_AXIS_CAPABLE );

    // Reset timers
    m_controlTimer.Reset();
    m_telemetryTimer.Reset();
}

void CCameraServo::Update( CCommand& command )
{
    // Check for messages
    if( NCommManager::m_isCommandAvailable )
    {
        // Handle messages
        if( command.Equals( "camServ_tpos" ) )
        {
            // TODO: Ideally this unit would have the ability to autonomously set its own target and ack receipt with a separate mechanism
            // Acknowledge target position
            Serial.print( F( "camServ_tpos:" ) );
            Serial.print( static_cast<int32_t>( command.m_arguments[1] ) );
            Serial.println( ';' );

            // Update the target position
            m_targetPos_deg = Decode( static_cast<int32_t>( command.m_arguments[1] ) );

            // Update the target microseconds
            m_targetPos_us = DegreesToMicroseconds( m_targetPos_deg, m_isInverted );
        }
        else if( command.Equals( "camServ_spd" ) )
        {
            // Acknowledge receipt of command
            Serial.print( F( "camServ_spd:" ) );
            Serial.print( static_cast<int32_t>( command.m_arguments[1] ) );
            Serial.println( ';' );

            // Decode the requested speed and update the setting
            m_speed_deg_per_s   = Decode( static_cast<int32_t>( command.m_arguments[1] ) );
            m_speed_us_per_ms   = ( m_speed_deg_per_s * 0.001f ) * kMicrosecPerDegree;
        }
        else if( command.Equals( "camServ_inv" ) )
        {
            if( command.m_arguments[1] == 1 )
            {
                // Set inverted
                m_isInverted = 1;

                // Report back
                Serial.print( F( "camServ_inv:1;" ) );
            }
            else if( command.m_arguments[1] == 0 )
            {
                // Set uninverted
                m_isInverted = 0;

                // Report back
                Serial.print( F( "camServ_inv:0;" ) );
            }
        }
    }

    // Run servo adjustment at 200Hz
    if( m_controlTimer.HasElapsed( 5 ) )
    {
        // Get time elapsed since last position update
        m_tDelta = millis() - m_tLast;

        // Update position if not at desired location
        if( m_currentPos_us != m_targetPos_us )
        {
            float error = static_cast<float>( m_targetPos_us ) - m_fCurrentPos_us;

            // Check to see if the error/dT is smaller than the speed limit
            if( ( error / static_cast<float>( m_tDelta ) ) < m_speed_us_per_ms )
            {
                // Move directly to the target
                // NOTE: Cannot use the cast method like below, since the floating point
                // representation of the target pos might be comparatively less than the integer value.
                // I.e. target = 32, static_cast<float>( 32 ) -> 31.99999, static_cast<uint32_t>( 31.99999 ) -> 31
                // This could lead to the current position never reaching the target
                m_currentPos_us = m_targetPos_us;

                // Update the floating point representation as well, for use in future target updates
                m_fCurrentPos_us = static_cast<float>( m_targetPos_us );
            }
            else
            {
                // Move by the delta towards the target
                m_fCurrentPos_us += ( m_speed_us_per_ms * static_cast<float>( m_tDelta ) );

                // Cast the floating point servo command to an integer
                m_currentPos_us = static_cast<uint32_t>( m_fCurrentPos_us );
            }

            // Set the servo to this target
            SetServoPosition( m_currentPos_us );

            // Update the position value in degrees
            m_currentPos_deg = MicrosecondsToDegrees( m_currentPos_us );
        }

        m_tLast = millis();
    }

    // Emit position telemetry at 10Hz
    if( m_telemetryTimer.HasElapsed( 100 ) )
    {
        Serial.print( F( "camServ_pos:" ) );
        Serial.print( Encode( m_currentPos_deg ) );
        Serial.println( ';' );
    }
}

#endif
<commit_msg>Took absolute of error which was causing immediate snaps on negative transitions<commit_after>#include "AConfig.h"
#if(HAS_CAMERASERVO)

// Includes
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "CCameraServo.h"
#include "CServo.h"
#include "CPin.h"
#include "NConfigManager.h"
#include "NDataManager.h"
#include "NModuleManager.h"
#include "NCommManager.h"
#include "CTimer.h"

#include "CControllerBoard.h"

#include <math.h>

// Defines
#ifndef F_CPU
    #define F_CPU 16000000UL
#endif

// File local variables and methods
namespace
{
    constexpr float kZeroPosMicrosecs       = 1487.0f;
    constexpr float kMicrosecPerDegree      = 9.523809f;
    constexpr float kDegPerMicrosec         = ( 1 / kMicrosecPerDegree );

    // Helper functions specifically for the HITEC servo
    constexpr uint32_t DegreesToMicroseconds( float degreesIn, bool isInverted = false )
    {
        return static_cast<uint32_t>( ( kMicrosecPerDegree * ( isInverted ? -degreesIn : degreesIn ) ) + kZeroPosMicrosecs );
    }

    constexpr float MicrosecondsToDegrees( uint32_t microsecondsIn, bool isInverted = false )
    {
        return ( isInverted ?   -( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec )
                                :( ( static_cast<float>( microsecondsIn ) - kZeroPosMicrosecs ) * kDegPerMicrosec ) );
    }

    constexpr float kNeutralPosition_deg    = 0.0f;
    constexpr uint32_t kNeutralPosition_us  = DegreesToMicroseconds( 0.0f );

    constexpr float kDefaultSpeed           = 50.0f;    // Degrees per sec

    // Attributes
    CTimer m_controlTimer;
    CTimer m_telemetryTimer;

    float m_targetPos_deg       = kNeutralPosition_deg;
    float m_currentPos_deg      = kNeutralPosition_deg;
    uint32_t m_targetPos_us     = kNeutralPosition_us;
    uint32_t m_currentPos_us    = kNeutralPosition_us;
    float m_fCurrentPos_us      = kZeroPosMicrosecs;

    uint32_t m_tDelta           = 0;
    uint32_t m_tLast            = 0;

    // Settings
    float m_speed_deg_per_s     = kDefaultSpeed;
    int m_isInverted            = 0;                // 0 - Not inverted, 1 - Inverted

    // Derived from settings
    float m_speed_us_per_ms     = ( kDefaultSpeed * 0.001f ) * kMicrosecPerDegree;

    // Float<->Int conversion helpers
    constexpr int32_t Encode( float valueIn )
    {
        return static_cast<int32_t>( valueIn * 1000.0f );
    }

    constexpr float Decode( int32_t valueIn )
    {
        return ( static_cast<float>( valueIn ) * 0.001f );
    }

    void SetServoPosition( uint32_t microsecondsIn )
    {
        // Set to 90° --> pulsewdith = 1.5ms
        OCR1A = microsecondsIn * 2;
    }
}

void CCameraServo::Initialize()
{
    // Set up the pin for the camera servo
    pinMode( CAMERAMOUNT_PIN, OUTPUT );

    // Set up the timers driving the PWM for the servo (AVR specific)
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1A |= ( 1 << COM1A1 ) | ( 1 << WGM11 );					// non-inverting mode for OC1A
    TCCR1B |= ( 1 << WGM13 ) | ( 1 << WGM12 ) | ( 1 << CS11 );	// Mode 14, Prescaler 8

    ICR1 = 40000; // 320000 / 8 = 40000

    // Set initial position
    SetServoPosition( kNeutralPosition_us );

    // Mark camera servo as enabled
    NConfigManager::m_capabilityBitmask |= ( 1 << CAMERA_MOUNT_1_AXIS_CAPABLE );

    // Reset timers
    m_controlTimer.Reset();
    m_telemetryTimer.Reset();
}

void CCameraServo::Update( CCommand& command )
{
    // Check for messages
    if( NCommManager::m_isCommandAvailable )
    {
        // Handle messages
        if( command.Equals( "camServ_tpos" ) )
        {
            // TODO: Ideally this unit would have the ability to autonomously set its own target and ack receipt with a separate mechanism
            // Acknowledge target position
            Serial.print( F( "camServ_tpos:" ) );
            Serial.print( static_cast<int32_t>( command.m_arguments[1] ) );
            Serial.println( ';' );

            // Update the target position
            m_targetPos_deg = Decode( static_cast<int32_t>( command.m_arguments[1] ) );

            // Update the target microseconds
            m_targetPos_us = DegreesToMicroseconds( m_targetPos_deg, m_isInverted );
        }
        else if( command.Equals( "camServ_spd" ) )
        {
            // Acknowledge receipt of command
            Serial.print( F( "camServ_spd:" ) );
            Serial.print( static_cast<int32_t>( command.m_arguments[1] ) );
            Serial.println( ';' );

            // Decode the requested speed and update the setting
            m_speed_deg_per_s   = Decode( static_cast<int32_t>( command.m_arguments[1] ) );
            m_speed_us_per_ms   = ( m_speed_deg_per_s * 0.001f ) * kMicrosecPerDegree;
        }
        else if( command.Equals( "camServ_inv" ) )
        {
            if( command.m_arguments[1] == 1 )
            {
                // Set inverted
                m_isInverted = 1;

                // Report back
                Serial.print( F( "camServ_inv:1;" ) );
            }
            else if( command.m_arguments[1] == 0 )
            {
                // Set uninverted
                m_isInverted = 0;

                // Report back
                Serial.print( F( "camServ_inv:0;" ) );
            }
        }
    }

    // Run servo adjustment at 200Hz
    if( m_controlTimer.HasElapsed( 5 ) )
    {
        // Get time elapsed since last position update
        m_tDelta = millis() - m_tLast;

        // Update position if not at desired location
        if( m_currentPos_us != m_targetPos_us )
        {
            float error = static_cast<float>( m_targetPos_us ) - m_fCurrentPos_us;

            // Check to see if the error/dT is smaller than the speed limit
            if( abs( error / static_cast<float>( m_tDelta ) ) < m_speed_us_per_ms )
            {
                // Move directly to the target
                // NOTE: Cannot use the cast method like below, since the floating point
                // representation of the target pos might be comparatively less than the integer value.
                // I.e. target = 32, static_cast<float>( 32 ) -> 31.99999, static_cast<uint32_t>( 31.99999 ) -> 31
                // This could lead to the current position never reaching the target
                m_currentPos_us = m_targetPos_us;

                // Update the floating point representation as well, for use in future target updates
                m_fCurrentPos_us = static_cast<float>( m_targetPos_us );
            }
            else
            {
                // Move by the delta towards the target
                m_fCurrentPos_us += ( m_speed_us_per_ms * static_cast<float>( m_tDelta ) );

                // Cast the floating point servo command to an integer
                m_currentPos_us = static_cast<uint32_t>( m_fCurrentPos_us );
            }

            // Set the servo to this target
            SetServoPosition( m_currentPos_us );

            // Update the position value in degrees
            m_currentPos_deg = MicrosecondsToDegrees( m_currentPos_us );
        }

        m_tLast = millis();
    }

    // Emit position telemetry at 10Hz
    if( m_telemetryTimer.HasElapsed( 100 ) )
    {
        Serial.print( F( "camServ_pos:" ) );
        Serial.print( Encode( m_currentPos_deg ) );
        Serial.println( ';' );
    }
}

#endif
<|endoftext|>


<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 "chrome/browser/ui/webui/print_preview_handler.h"

#include "base/threading/thread.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/browser_thread.h"
#include "printing/backend/print_backend.h"

class EnumeratePrintersTaskProxy
    : public base::RefCountedThreadSafe<EnumeratePrintersTaskProxy> {
 public:
  EnumeratePrintersTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler,
                             printing::PrintBackend* print_backend)
      : handler_(handler),
        print_backend_(print_backend) {
  }

  void EnumeratePrinters() {
    ListValue* printers = new ListValue;

    printing::PrinterList printer_list;
    print_backend_->EnumeratePrinters(&printer_list);
    for (printing::PrinterList::iterator index = printer_list.begin();
         index != printer_list.end(); ++index) {
      printers->Append(new StringValue(index->printer_name));
    }

    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &EnumeratePrintersTaskProxy::SendPrinterList,
                          printers));
  }

  void SendPrinterList(ListValue* printers) {
    if (handler_)
      handler_->SendPrinterList(*printers);
    delete printers;
  }

 private:
  base::WeakPtr<PrintPreviewHandler> handler_;

  scoped_refptr<printing::PrintBackend> print_backend_;

  DISALLOW_COPY_AND_ASSIGN(EnumeratePrintersTaskProxy);
};

PrintPreviewHandler::PrintPreviewHandler()
    : print_backend_(printing::PrintBackend::CreateInstance(NULL)) {
}

PrintPreviewHandler::~PrintPreviewHandler() {
}

void PrintPreviewHandler::RegisterMessages() {
  web_ui_->RegisterMessageCallback("getPrinters",
      NewCallback(this, &PrintPreviewHandler::HandleGetPrinters));
  web_ui_->RegisterMessageCallback("print",
      NewCallback(this, &PrintPreviewHandler::HandlePrint));
}

void PrintPreviewHandler::HandleGetPrinters(const ListValue*) {
  scoped_refptr<EnumeratePrintersTaskProxy> task =
      new EnumeratePrintersTaskProxy(AsWeakPtr(), print_backend_.get());
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(task.get(),
                        &EnumeratePrintersTaskProxy::EnumeratePrinters));
}

void PrintPreviewHandler::HandlePrint(const ListValue*) {
  web_ui_->GetRenderViewHost()->PrintForPrintPreview();
}

void PrintPreviewHandler::SendPrinterList(const ListValue& printers) {
  web_ui_->CallJavascriptFunction(L"setPrinters", printers);
}
<commit_msg>Print Preview: Make sure EnumeratePrintersTaskProxy gets deleted on the right thread.<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 "chrome/browser/ui/webui/print_preview_handler.h"

#include "base/threading/thread.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/browser_thread.h"
#include "printing/backend/print_backend.h"

class EnumeratePrintersTaskProxy
    : public base::RefCountedThreadSafe<EnumeratePrintersTaskProxy,
                                        BrowserThread::DeleteOnUIThread> {
 public:
  EnumeratePrintersTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler,
                             printing::PrintBackend* print_backend)
      : handler_(handler),
        print_backend_(print_backend) {
  }

  void EnumeratePrinters() {
    ListValue* printers = new ListValue;

    printing::PrinterList printer_list;
    print_backend_->EnumeratePrinters(&printer_list);
    for (printing::PrinterList::iterator index = printer_list.begin();
         index != printer_list.end(); ++index) {
      printers->Append(new StringValue(index->printer_name));
    }

    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &EnumeratePrintersTaskProxy::SendPrinterList,
                          printers));
  }

  void SendPrinterList(ListValue* printers) {
    if (handler_)
      handler_->SendPrinterList(*printers);
    delete printers;
  }

 private:
  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
  friend class DeleteTask<EnumeratePrintersTaskProxy>;

  ~EnumeratePrintersTaskProxy() {}

  base::WeakPtr<PrintPreviewHandler> handler_;

  scoped_refptr<printing::PrintBackend> print_backend_;

  DISALLOW_COPY_AND_ASSIGN(EnumeratePrintersTaskProxy);
};

PrintPreviewHandler::PrintPreviewHandler()
    : print_backend_(printing::PrintBackend::CreateInstance(NULL)) {
}

PrintPreviewHandler::~PrintPreviewHandler() {
}

void PrintPreviewHandler::RegisterMessages() {
  web_ui_->RegisterMessageCallback("getPrinters",
      NewCallback(this, &PrintPreviewHandler::HandleGetPrinters));
  web_ui_->RegisterMessageCallback("print",
      NewCallback(this, &PrintPreviewHandler::HandlePrint));
}

void PrintPreviewHandler::HandleGetPrinters(const ListValue*) {
  scoped_refptr<EnumeratePrintersTaskProxy> task =
      new EnumeratePrintersTaskProxy(AsWeakPtr(), print_backend_.get());
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(task.get(),
                        &EnumeratePrintersTaskProxy::EnumeratePrinters));
}

void PrintPreviewHandler::HandlePrint(const ListValue*) {
  web_ui_->GetRenderViewHost()->PrintForPrintPreview();
}

void PrintPreviewHandler::SendPrinterList(const ListValue& printers) {
  web_ui_->CallJavascriptFunction(L"setPrinters", printers);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "chrome/nacl/nacl_main_platform_delegate.h"

#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"
#include "seccompsandbox/sandbox.h"

NaClMainPlatformDelegate::NaClMainPlatformDelegate(
    const MainFunctionParams& parameters)
    : parameters_(parameters), sandbox_test_module_(NULL) {
}

NaClMainPlatformDelegate::~NaClMainPlatformDelegate() {
}

void NaClMainPlatformDelegate::PlatformInitialize() {
}

void NaClMainPlatformDelegate::PlatformUninitialize() {
}

void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
  // The sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  return;
}

void NaClMainPlatformDelegate::EnableSandbox() {
  // The setuid sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  //
  // The seccomp sandbox is started in the renderer.
  // http://code.google.com/p/seccompsandbox/
#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX) && \
    !defined(__clang__)
  // N.b. SupportsSeccompSandbox() returns a cached result, as we already
  // called it earlier in the zygote. Thus, it is OK for us to not pass in
  // a file descriptor for "/proc".
  if (switches::SeccompSandboxEnabled() && SupportsSeccompSandbox(-1))
    StartSeccompSandbox();
#endif
}

bool NaClMainPlatformDelegate::RunSandboxTests() {
  // The sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  return true;
}
<commit_msg>nacl: disable seccomp initialization in NaClMain()<commit_after>// Copyright (c) 2010 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 "chrome/nacl/nacl_main_platform_delegate.h"

#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"
#include "seccompsandbox/sandbox.h"

NaClMainPlatformDelegate::NaClMainPlatformDelegate(
    const MainFunctionParams& parameters)
    : parameters_(parameters), sandbox_test_module_(NULL) {
}

NaClMainPlatformDelegate::~NaClMainPlatformDelegate() {
}

void NaClMainPlatformDelegate::PlatformInitialize() {
}

void NaClMainPlatformDelegate::PlatformUninitialize() {
}

void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
  // The sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  return;
}

void NaClMainPlatformDelegate::EnableSandbox() {
  // The setuid sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  //
  // The seccomp sandbox is started in the renderer.
  // http://code.google.com/p/seccompsandbox/
  // seccomp is currently disabled for nacl.
  // http://code.google.com/p/chromium/issues/detail?id=59423
  // See the code in chrome/renderer/renderer_main_platform_delegate_linux.cc
  // for how to turn seccomp on.
  //
  // The seccomp sandbox should not be enabled for Native Client until
  // all of these issues are fixed:
  // http://code.google.com/p/nativeclient/issues/list?q=label:Seccomp
  // At best, NaCl will not work.  At worst, enabling the seccomp sandbox
  // could create a hole in the NaCl sandbox.
}

bool NaClMainPlatformDelegate::RunSandboxTests() {
  // The sandbox is started in the zygote process: zygote_main_linux.cc
  // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
  return true;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkStreamingImageIOBase.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

#include <itksys/SystemTools.hxx>

namespace itk
{

StreamingImageIOBase::StreamingImageIOBase()
  : ImageIOBase()
{
}

void StreamingImageIOBase::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

bool StreamingImageIOBase
::StreamReadBufferAsBinary(std::istream& file, void *_buffer)
{
  itkDebugMacro( << "StreamingReadBufferAsBinary called" );

  char *buffer = static_cast<char*>(_buffer);
  // Offset into file
  std::streampos dataPos = this->GetDataPosition();

  std::streamsize sizeOfRegion = static_cast<std::streamsize>( m_IORegion.GetNumberOfPixels() )
    *this->GetPixelSize();

  // compute the number of continuous bytes to be read
  std::streamsize sizeOfChunk = 1;
  unsigned int movingDirection = 0;
  do
    {
    sizeOfChunk *= m_IORegion.GetSize(movingDirection);
    ++movingDirection;
    }
  while ( movingDirection < m_IORegion.GetImageDimension() &&
          m_IORegion.GetSize(movingDirection-1) == this->GetDimensions(movingDirection-1) );
  sizeOfChunk *= this->GetPixelSize();

  ImageIORegion::IndexType currentIndex = m_IORegion.GetIndex();
  std::streamsize gcount = 0;
  while ( m_IORegion.IsInside(currentIndex) )
    {
    // calculate the position to seek to in the file
    std::streampos seekPos = 0;
    size_t subDimensionQuantity = 1;
    for ( unsigned int i = 0; i < m_IORegion.GetImageDimension(); ++i )
      {
      seekPos += subDimensionQuantity*this->GetPixelSize()*currentIndex[i];
      subDimensionQuantity *= this->GetDimensions(i);
      }

    itkDebugMacro(<< "Reading " << sizeOfChunk << " of " << sizeOfRegion << " bytes for " << m_FileName << " at " << dataPos+seekPos << " position in file");

    file.seekg( dataPos+seekPos, std::ios::beg );
    this->ReadBufferAsBinary( file, buffer, sizeOfChunk );

    // increment the buffer pointer
    buffer += sizeOfChunk;
    gcount += file.gcount();

    if ( file.fail() )
      {
      itkExceptionMacro(<<"Fail reading");
      }

    if (movingDirection == m_IORegion.GetImageDimension())
      break;

    // increment index to next chunk
    ++currentIndex[movingDirection];
    for (unsigned int i = movingDirection; i < m_IORegion.GetImageDimension()-1; ++i)
      {
      // when reaching the end of the moving index dimension carry to
      // higher dimensions
      if (static_cast<ImageIORegion::SizeValueType>(currentIndex[i]  - m_IORegion.GetIndex(i)) >= m_IORegion.GetSize(i) )
        {
        currentIndex[i] = m_IORegion.GetIndex(i);
        ++currentIndex[i+1];
        }
      }
    }

  if ( gcount != sizeOfRegion )
    {
    itkExceptionMacro("Data not read completely. Expected = " << sizeOfRegion << ", but only read " <<  gcount <<  " bytes.");
    }

  return true;
}

bool StreamingImageIOBase::ReadBufferAsBinary( std::istream& is, void *buffer, StreamingImageIOBase::SizeType num )
{

  // some systems have a limit of 2GB to be read at once
  const SizeType maxChunk = 1024*1024*1024;

  std::streamsize bytesRemaining = static_cast<std::streamsize>( num );

  while (bytesRemaining)
    {

    std::streamsize bytesToRead = bytesRemaining > maxChunk ? maxChunk : bytesRemaining;

    itkDebugMacro(<< "Reading " << bytesToRead << " of " << bytesRemaining << " bytes for " << m_FileName);

    is.read( static_cast<char *>( buffer ) ,  bytesToRead );

    if ( (is.gcount() != bytesToRead) || is.fail() )
      {
      return false;
      }
    buffer =  static_cast<char *>( buffer ) + bytesToRead;
    bytesRemaining -= bytesToRead;
    }

  return true;
}

bool StreamingImageIOBase::WriteBufferAsBinary( std::ostream& os, const void *buffer, StreamingImageIOBase::SizeType num )
{
  // some systems have a limit of 2GB to be written at once
  const SizeType maxChunk = 1024*1024*1024;

  std::streamsize bytesRemaining = num;
  while (bytesRemaining)
    {

    SizeType bytesToWrite = bytesRemaining > maxChunk ? maxChunk : bytesRemaining;

    itkDebugMacro(<< "Writing " << bytesToWrite << " of " << bytesRemaining << " bytes for " << m_FileName);

    os.write(static_cast<const char*>(buffer) , bytesToWrite);
    if ( os.fail() )
      {
      return false;
      }

    buffer =  static_cast<const char *>( buffer ) + bytesToWrite;
    bytesRemaining -= bytesToWrite;
    }

  return true;
}

bool StreamingImageIOBase::StreamWriteBufferAsBinary(std::ostream& file, const void *_buffer)
{
  itkDebugMacro( << "StreamingWriteBufferAsBinary called" );

  const char *buffer = static_cast< const char* >( _buffer );
  // Offset into file
  std::streampos dataPos = this->GetDataPosition();

  // compute the number of continuous bytes to be written
  std::streamsize sizeOfChunk = 1;
  unsigned int movingDirection = 0;
  do
    {
    sizeOfChunk *= m_IORegion.GetSize(movingDirection);
    ++movingDirection;
    }
  while ( movingDirection < m_IORegion.GetImageDimension() &&
          m_IORegion.GetSize(movingDirection-1) == this->GetDimensions(movingDirection-1) );
  sizeOfChunk *= this->GetPixelSize();

  ImageIORegion::IndexType currentIndex = m_IORegion.GetIndex();
  while ( m_IORegion.IsInside(currentIndex) )
    {
    // calculate the position to seek to in the file
    std::streampos seekPos = 0;
    size_t subDimensionQuantity = 1;
    for ( unsigned int i = 0; i < m_IORegion.GetImageDimension(); ++i )
      {
      seekPos += subDimensionQuantity*this->GetPixelSize()*currentIndex[i];
      subDimensionQuantity *= this->GetDimensions(i);
      }

    file.seekp( dataPos+seekPos, std::ios::beg );
    this->WriteBufferAsBinary( file, buffer, sizeOfChunk );

    // increment the buffer pointer
    buffer += sizeOfChunk;

    itkDebugMacro(<< "Writing " << sizeOfChunk << " of " <<  " ?? bytes for " << m_FileName << " at " << dataPos+seekPos << " position in file");

    if ( file.fail() )
      {
      itkExceptionMacro(<<"Fail writing");
      }

    if (movingDirection == m_IORegion.GetImageDimension())
      break;

    // increment index to next chunk
    ++currentIndex[movingDirection];
    for (unsigned int i = movingDirection; i < m_IORegion.GetImageDimension()-1; ++i)
      {
      // when reaching the end of the movingDirection dimension carry to
      // higher dimensions
      if ( static_cast<ImageIORegion::SizeValueType>(currentIndex[i] - m_IORegion.GetIndex(i))
           >=  m_IORegion.GetSize(i) )
        {
        currentIndex[i] = m_IORegion.GetIndex(i);
        ++currentIndex[i+1];
        }
      }
    }

  return true;
}

void StreamingImageIOBase::OpenFileForReading(std::ifstream& os, const char* filename)
{
  // Make sure that we have a file to
  if ( *filename == 0 )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  os.open(filename,  std::ios::in | std::ios::binary  );
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for reading: " << filename);
    }

}

void StreamingImageIOBase::OpenFileForWriting(std::ofstream& os, const char* filename, bool truncate)
{
  // Make sure that we have a file to
  if ( *filename == 0 )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

 if (truncate)
    {
    // truncate
    os.open( m_FileName.c_str(), std::ios::out | std::ios::binary | std::ios::trunc );

    }
  else
    {
    os.open( m_FileName.c_str(), std::ios::out | std::ios::binary | std::ios::in );
    }

  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    }

}

bool StreamingImageIOBase::CanStreamRead( void )
{
  return true;
}

bool StreamingImageIOBase::CanStreamWrite( void )
{
  return true;
}

unsigned int
StreamingImageIOBase::GetActualNumberOfSplitsForWriting(unsigned int numberOfRequestedSplits,
                                               const ImageIORegion &pasteRegion,
                                               const ImageIORegion &largestPossibleRegion)
{
  if (!itksys::SystemTools::FileExists( m_FileName.c_str() ))
    {
    // file doesn't exits so we don't have potential problems
    }
  else if (pasteRegion != largestPossibleRegion)
    {
    // we are going to be pasting (may be streaming too)

    // need to check to see if the file is compatible
    std::string errorMessage;
    Pointer headerImageIOReader = dynamic_cast<StreamingImageIOBase*>(this->CreateAnother().GetPointer());

    try
      {
      headerImageIOReader->SetFileName(m_FileName.c_str());
      headerImageIOReader->ReadImageInformation();
      }
    catch (...)
      {
      errorMessage = "Unable to read information from file: " + m_FileName;
      }

    // we now need to check that the following match:
    // 2)pixel type
    // 3)dimensions
    // 4)size/origin/spacing
    // 5)direction cosines
    //
    // todo check for byte order

    if (errorMessage.size())
      {
      // 0) Can't read file
      }
    // 2)pixel type
    // this->GetPixelType() is not verified becasue the metaio file format
    // stores all multi-component types as arrays, so it does not
    // distinguish between pixel types. Also as long as the compoent
    // and number of compoents match we should be able to paste, that
    // is the numbers should be the same it is just the interpretation
    // that is not matching
    else if ( headerImageIOReader->GetNumberOfComponents() != this->GetNumberOfComponents() ||
              headerImageIOReader->GetComponentType() != this->GetComponentType() )
      {
      errorMessage = "Component type does not match in file: " + m_FileName;
      }
    // 3)dimensions/size
    else if (headerImageIOReader->GetNumberOfDimensions() != this->GetNumberOfDimensions())
      {
      errorMessage = "Dimensions does not match in file: " + m_FileName;
      }
    else
      {
      for (unsigned int i = 0; i < this->GetNumberOfDimensions(); ++i)
        {
        // 4)size/origin/spacing
        if (headerImageIOReader->GetDimensions(i) != this->GetDimensions(i) ||
            headerImageIOReader->GetSpacing(i) != this->GetSpacing(i) ||
            headerImageIOReader->GetOrigin(i) != this->GetOrigin(i))
          {
          errorMessage = "Size, spacing or origin does not match in file: " + m_FileName;
          break;
          }
        // 5)direction cosines
        if (headerImageIOReader->GetDirection(i) != this->GetDirection(i))
          {
          errorMessage = "Direction cosines does not match in file: " + m_FileName;
          break;
          }
        }
      }

    if (errorMessage.size())
      {
      itkExceptionMacro("Unable to paste because pasting file exists and is different. " << errorMessage);
      }
    else if ( headerImageIOReader->GetPixelType() != this->GetPixelType() )
      {
      // since there is currently poor support for pixel types in
      // MetaIO we will just warn when it does not match
      itkWarningMacro("Pixel types does not match file, but component type and number of components do.");
      }
    }
  else if (numberOfRequestedSplits != 1)
    {
    // we are going be streaming

    // need to remove the file incase the file doesn't match our
    // current header/meta data information
    if (!itksys::SystemTools::RemoveFile(m_FileName.c_str()))
      itkExceptionMacro("Unable to remove file for streaming: " << m_FileName);
    }

  return GetActualNumberOfSplitsForWritingCanStreamWrite(numberOfRequestedSplits, pasteRegion);

}

ImageIORegion StreamingImageIOBase::GenerateStreamableReadRegionFromRequestedRegion( const ImageIORegion & requestedRegion ) const
{
  // This implementation returns the requestedRegion if
  // "UseStreamedReading" is enabled

  ImageIORegion streamableRegion(this->m_NumberOfDimensions);
  if( !m_UseStreamedReading )
    {
    for( unsigned int i=0; i < this->m_NumberOfDimensions; i++ )
      {
      streamableRegion.SetSize( i, this->m_Dimensions[i] );
      streamableRegion.SetIndex( i, 0 );
      }
    }
  else
    {
    streamableRegion = requestedRegion;
    }

  return streamableRegion;
}

bool StreamingImageIOBase::RequestedToStream( void ) const
{
  // we choose the max dimension and then pad the smaller with ones
  //
  // This enables a 2D request from a 3D volume to get the first slice,
  // and a 4D with a 1-sized 4th dimension to equal the 3D volume
  // aswell.
  unsigned int maxNumberOfDimension = vnl_math_max( this->GetNumberOfDimensions(), this->GetIORegion().GetImageDimension() );

  ImageIORegion ioregion( maxNumberOfDimension );
  ImageIORegion largestRegion( maxNumberOfDimension );
  for(unsigned int i=0; i<maxNumberOfDimension; i++)
    {

    largestRegion.SetIndex(i, 0);
    if ( i < this->GetNumberOfDimensions() )
      {
      largestRegion.SetSize( i, this->GetDimensions(i) );
      }
    else
      {
      largestRegion.SetSize( i, 1 );
      }

    if ( i < this->GetIORegion().GetImageDimension() )
      {
      ioregion.SetIndex( i, this->GetIORegion().GetIndex(i) );
      ioregion.SetSize( i, this->GetIORegion().GetSize(i) );
      }
    else
      {
      ioregion.SetIndex( i, 0 );
      ioregion.SetSize( i, 1 );
      }

    }

  return (largestRegion != ioregion);
}

} // namespace itk
<commit_msg>COMP: at least for Borland, must cast arg to std::fpos += operator to std::streamoff to avoid ambiguity.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkStreamingImageIOBase.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

#include <itksys/SystemTools.hxx>

namespace itk
{

StreamingImageIOBase::StreamingImageIOBase()
  : ImageIOBase()
{
}

void StreamingImageIOBase::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

bool StreamingImageIOBase
::StreamReadBufferAsBinary(std::istream& file, void *_buffer)
{
  itkDebugMacro( << "StreamingReadBufferAsBinary called" );

  char *buffer = static_cast<char*>(_buffer);
  // Offset into file
  std::streampos dataPos = this->GetDataPosition();

  std::streamsize sizeOfRegion = static_cast<std::streamsize>( m_IORegion.GetNumberOfPixels() )
    *this->GetPixelSize();

  // compute the number of continuous bytes to be read
  std::streamsize sizeOfChunk = 1;
  unsigned int movingDirection = 0;
  do
    {
    sizeOfChunk *= m_IORegion.GetSize(movingDirection);
    ++movingDirection;
    }
  while ( movingDirection < m_IORegion.GetImageDimension() &&
          m_IORegion.GetSize(movingDirection-1) == this->GetDimensions(movingDirection-1) );
  sizeOfChunk *= this->GetPixelSize();

  ImageIORegion::IndexType currentIndex = m_IORegion.GetIndex();
  std::streamsize gcount = 0;
  while ( m_IORegion.IsInside(currentIndex) )
    {
    // calculate the position to seek to in the file
    std::streampos seekPos = 0;
    size_t subDimensionQuantity = 1;
    for ( unsigned int i = 0; i < m_IORegion.GetImageDimension(); ++i )
      {
      seekPos += static_cast<std::streamoff> (subDimensionQuantity *
                                              this->GetPixelSize() *
                                              currentIndex[i]);
      subDimensionQuantity *= this->GetDimensions(i);
      }

    itkDebugMacro(<< "Reading " << sizeOfChunk << " of " << sizeOfRegion << " bytes for " << m_FileName << " at " << dataPos+seekPos << " position in file");

    file.seekg( dataPos+seekPos, std::ios::beg );
    this->ReadBufferAsBinary( file, buffer, sizeOfChunk );

    // increment the buffer pointer
    buffer += sizeOfChunk;
    gcount += file.gcount();

    if ( file.fail() )
      {
      itkExceptionMacro(<<"Fail reading");
      }

    if (movingDirection == m_IORegion.GetImageDimension())
      break;

    // increment index to next chunk
    ++currentIndex[movingDirection];
    for (unsigned int i = movingDirection; i < m_IORegion.GetImageDimension()-1; ++i)
      {
      // when reaching the end of the moving index dimension carry to
      // higher dimensions
      if (static_cast<ImageIORegion::SizeValueType>(currentIndex[i]  - m_IORegion.GetIndex(i)) >= m_IORegion.GetSize(i) )
        {
        currentIndex[i] = m_IORegion.GetIndex(i);
        ++currentIndex[i+1];
        }
      }
    }

  if ( gcount != sizeOfRegion )
    {
    itkExceptionMacro("Data not read completely. Expected = " << sizeOfRegion << ", but only read " <<  gcount <<  " bytes.");
    }

  return true;
}

bool StreamingImageIOBase::ReadBufferAsBinary( std::istream& is, void *buffer, StreamingImageIOBase::SizeType num )
{

  // some systems have a limit of 2GB to be read at once
  const SizeType maxChunk = 1024*1024*1024;

  std::streamsize bytesRemaining = static_cast<std::streamsize>( num );

  while (bytesRemaining)
    {

    std::streamsize bytesToRead = bytesRemaining > maxChunk ? maxChunk : bytesRemaining;

    itkDebugMacro(<< "Reading " << bytesToRead << " of " << bytesRemaining << " bytes for " << m_FileName);

    is.read( static_cast<char *>( buffer ) ,  bytesToRead );

    if ( (is.gcount() != bytesToRead) || is.fail() )
      {
      return false;
      }
    buffer =  static_cast<char *>( buffer ) + bytesToRead;
    bytesRemaining -= bytesToRead;
    }

  return true;
}

bool StreamingImageIOBase::WriteBufferAsBinary( std::ostream& os, const void *buffer, StreamingImageIOBase::SizeType num )
{
  // some systems have a limit of 2GB to be written at once
  const SizeType maxChunk = 1024*1024*1024;

  std::streamsize bytesRemaining = num;
  while (bytesRemaining)
    {

    SizeType bytesToWrite = bytesRemaining > maxChunk ? maxChunk : bytesRemaining;

    itkDebugMacro(<< "Writing " << bytesToWrite << " of " << bytesRemaining << " bytes for " << m_FileName);

    os.write(static_cast<const char*>(buffer) , bytesToWrite);
    if ( os.fail() )
      {
      return false;
      }

    buffer =  static_cast<const char *>( buffer ) + bytesToWrite;
    bytesRemaining -= bytesToWrite;
    }

  return true;
}

bool StreamingImageIOBase::StreamWriteBufferAsBinary(std::ostream& file, const void *_buffer)
{
  itkDebugMacro( << "StreamingWriteBufferAsBinary called" );

  const char *buffer = static_cast< const char* >( _buffer );
  // Offset into file
  std::streampos dataPos = this->GetDataPosition();

  // compute the number of continuous bytes to be written
  std::streamsize sizeOfChunk = 1;
  unsigned int movingDirection = 0;
  do
    {
    sizeOfChunk *= m_IORegion.GetSize(movingDirection);
    ++movingDirection;
    }
  while ( movingDirection < m_IORegion.GetImageDimension() &&
          m_IORegion.GetSize(movingDirection-1) == this->GetDimensions(movingDirection-1) );
  sizeOfChunk *= this->GetPixelSize();

  ImageIORegion::IndexType currentIndex = m_IORegion.GetIndex();
  while ( m_IORegion.IsInside(currentIndex) )
    {
    // calculate the position to seek to in the file
    std::streampos seekPos = 0;
    size_t subDimensionQuantity = 1;
    for ( unsigned int i = 0; i < m_IORegion.GetImageDimension(); ++i )
      {
      seekPos += static_cast<std::streamoff> (subDimensionQuantity *
                                              this->GetPixelSize() *
                                              currentIndex[i]);
      subDimensionQuantity *= this->GetDimensions(i);
      }

    file.seekp( dataPos+seekPos, std::ios::beg );
    this->WriteBufferAsBinary( file, buffer, sizeOfChunk );

    // increment the buffer pointer
    buffer += sizeOfChunk;

    itkDebugMacro(<< "Writing " << sizeOfChunk << " of " <<  " ?? bytes for " << m_FileName << " at " << dataPos+seekPos << " position in file");

    if ( file.fail() )
      {
      itkExceptionMacro(<<"Fail writing");
      }

    if (movingDirection == m_IORegion.GetImageDimension())
      break;

    // increment index to next chunk
    ++currentIndex[movingDirection];
    for (unsigned int i = movingDirection; i < m_IORegion.GetImageDimension()-1; ++i)
      {
      // when reaching the end of the movingDirection dimension carry to
      // higher dimensions
      if ( static_cast<ImageIORegion::SizeValueType>(currentIndex[i] - m_IORegion.GetIndex(i))
           >=  m_IORegion.GetSize(i) )
        {
        currentIndex[i] = m_IORegion.GetIndex(i);
        ++currentIndex[i+1];
        }
      }
    }

  return true;
}

void StreamingImageIOBase::OpenFileForReading(std::ifstream& os, const char* filename)
{
  // Make sure that we have a file to
  if ( *filename == 0 )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  os.open(filename,  std::ios::in | std::ios::binary  );
  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for reading: " << filename);
    }

}

void StreamingImageIOBase::OpenFileForWriting(std::ofstream& os, const char* filename, bool truncate)
{
  // Make sure that we have a file to
  if ( *filename == 0 )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

 if (truncate)
    {
    // truncate
    os.open( m_FileName.c_str(), std::ios::out | std::ios::binary | std::ios::trunc );

    }
  else
    {
    os.open( m_FileName.c_str(), std::ios::out | std::ios::binary | std::ios::in );
    }

  if ( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    }

}

bool StreamingImageIOBase::CanStreamRead( void )
{
  return true;
}

bool StreamingImageIOBase::CanStreamWrite( void )
{
  return true;
}

unsigned int
StreamingImageIOBase::GetActualNumberOfSplitsForWriting(unsigned int numberOfRequestedSplits,
                                               const ImageIORegion &pasteRegion,
                                               const ImageIORegion &largestPossibleRegion)
{
  if (!itksys::SystemTools::FileExists( m_FileName.c_str() ))
    {
    // file doesn't exits so we don't have potential problems
    }
  else if (pasteRegion != largestPossibleRegion)
    {
    // we are going to be pasting (may be streaming too)

    // need to check to see if the file is compatible
    std::string errorMessage;
    Pointer headerImageIOReader = dynamic_cast<StreamingImageIOBase*>(this->CreateAnother().GetPointer());

    try
      {
      headerImageIOReader->SetFileName(m_FileName.c_str());
      headerImageIOReader->ReadImageInformation();
      }
    catch (...)
      {
      errorMessage = "Unable to read information from file: " + m_FileName;
      }

    // we now need to check that the following match:
    // 2)pixel type
    // 3)dimensions
    // 4)size/origin/spacing
    // 5)direction cosines
    //
    // todo check for byte order

    if (errorMessage.size())
      {
      // 0) Can't read file
      }
    // 2)pixel type
    // this->GetPixelType() is not verified becasue the metaio file format
    // stores all multi-component types as arrays, so it does not
    // distinguish between pixel types. Also as long as the compoent
    // and number of compoents match we should be able to paste, that
    // is the numbers should be the same it is just the interpretation
    // that is not matching
    else if ( headerImageIOReader->GetNumberOfComponents() != this->GetNumberOfComponents() ||
              headerImageIOReader->GetComponentType() != this->GetComponentType() )
      {
      errorMessage = "Component type does not match in file: " + m_FileName;
      }
    // 3)dimensions/size
    else if (headerImageIOReader->GetNumberOfDimensions() != this->GetNumberOfDimensions())
      {
      errorMessage = "Dimensions does not match in file: " + m_FileName;
      }
    else
      {
      for (unsigned int i = 0; i < this->GetNumberOfDimensions(); ++i)
        {
        // 4)size/origin/spacing
        if (headerImageIOReader->GetDimensions(i) != this->GetDimensions(i) ||
            headerImageIOReader->GetSpacing(i) != this->GetSpacing(i) ||
            headerImageIOReader->GetOrigin(i) != this->GetOrigin(i))
          {
          errorMessage = "Size, spacing or origin does not match in file: " + m_FileName;
          break;
          }
        // 5)direction cosines
        if (headerImageIOReader->GetDirection(i) != this->GetDirection(i))
          {
          errorMessage = "Direction cosines does not match in file: " + m_FileName;
          break;
          }
        }
      }

    if (errorMessage.size())
      {
      itkExceptionMacro("Unable to paste because pasting file exists and is different. " << errorMessage);
      }
    else if ( headerImageIOReader->GetPixelType() != this->GetPixelType() )
      {
      // since there is currently poor support for pixel types in
      // MetaIO we will just warn when it does not match
      itkWarningMacro("Pixel types does not match file, but component type and number of components do.");
      }
    }
  else if (numberOfRequestedSplits != 1)
    {
    // we are going be streaming

    // need to remove the file incase the file doesn't match our
    // current header/meta data information
    if (!itksys::SystemTools::RemoveFile(m_FileName.c_str()))
      itkExceptionMacro("Unable to remove file for streaming: " << m_FileName);
    }

  return GetActualNumberOfSplitsForWritingCanStreamWrite(numberOfRequestedSplits, pasteRegion);

}

ImageIORegion StreamingImageIOBase::GenerateStreamableReadRegionFromRequestedRegion( const ImageIORegion & requestedRegion ) const
{
  // This implementation returns the requestedRegion if
  // "UseStreamedReading" is enabled

  ImageIORegion streamableRegion(this->m_NumberOfDimensions);
  if( !m_UseStreamedReading )
    {
    for( unsigned int i=0; i < this->m_NumberOfDimensions; i++ )
      {
      streamableRegion.SetSize( i, this->m_Dimensions[i] );
      streamableRegion.SetIndex( i, 0 );
      }
    }
  else
    {
    streamableRegion = requestedRegion;
    }

  return streamableRegion;
}

bool StreamingImageIOBase::RequestedToStream( void ) const
{
  // we choose the max dimension and then pad the smaller with ones
  //
  // This enables a 2D request from a 3D volume to get the first slice,
  // and a 4D with a 1-sized 4th dimension to equal the 3D volume
  // aswell.
  unsigned int maxNumberOfDimension = vnl_math_max( this->GetNumberOfDimensions(), this->GetIORegion().GetImageDimension() );

  ImageIORegion ioregion( maxNumberOfDimension );
  ImageIORegion largestRegion( maxNumberOfDimension );
  for(unsigned int i=0; i<maxNumberOfDimension; i++)
    {

    largestRegion.SetIndex(i, 0);
    if ( i < this->GetNumberOfDimensions() )
      {
      largestRegion.SetSize( i, this->GetDimensions(i) );
      }
    else
      {
      largestRegion.SetSize( i, 1 );
      }

    if ( i < this->GetIORegion().GetImageDimension() )
      {
      ioregion.SetIndex( i, this->GetIORegion().GetIndex(i) );
      ioregion.SetSize( i, this->GetIORegion().GetSize(i) );
      }
    else
      {
      ioregion.SetIndex( i, 0 );
      ioregion.SetSize( i, 1 );
      }

    }

  return (largestRegion != ioregion);
}

} // namespace itk
<|endoftext|>


<commit_before>/**
 * @file
 * @brief Example of using new and delete operators
 * @date 12.07.12
 * @author Ilia Vaprol
 */

#include <new>

#include <embox/test.h>

EMBOX_TEST_SUITE("c++ memory test");

#if 0
TEST_SETUP_SUITE(suite_setup);

static int base_ctor;
static int base_dtor;

class Base {
public:
	Base() { ++base_ctor; }
	~Base() { ++base_dtor; }
};

TEST_CASE("Class can allocated on stack") {
	{
		Base base;
		test_assert_equal(base_ctor, 1);
		test_assert_equal(base_dtor, 0);
	}
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated one stack using placement new") {
	char storage[sizeof(Base)];
	Base *base_ptr = new(storage) Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	base_ptr->~Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated on heap using nothrow new") {
	Base *base_ptr = new(std::nothrow) Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	delete base_ptr;
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated on heap using throwing new") {
	Base *base_ptr = new Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	delete base_ptr;
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

static int case_setup(void) {
	base_ctor = base_dtor = 0;
}
#endif
<commit_msg>tests: c++: Fix memory test<commit_after>/**
 * @file
 * @brief Example of using new and delete operators
 * @date 12.07.12
 * @author Ilia Vaprol
 */

#include <new>

#include <embox/test.h>

EMBOX_TEST_SUITE("c++ memory test");

TEST_SETUP(case_setup);

static int base_ctor;
static int base_dtor;

class Base {
public:
	Base() { ++base_ctor; }
	~Base() { ++base_dtor; }
};

TEST_CASE("Class can allocated on stack") {
	{
		Base base;
		test_assert_equal(base_ctor, 1);
		test_assert_equal(base_dtor, 0);
	}
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated one stack using placement new") {
	char storage[sizeof(Base)];
	Base *base_ptr = new(storage) Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	base_ptr->~Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated on heap using nothrow new") {
	Base *base_ptr = new(std::nothrow) Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	delete base_ptr;
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

TEST_CASE("Class can allocated on heap using throwing new") {
	Base *base_ptr = new Base();
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 0);
	delete base_ptr;
	test_assert_equal(base_ctor, 1);
	test_assert_equal(base_dtor, 1);
}

static int case_setup(void) {
	base_ctor = base_dtor = 0;
}
<|endoftext|>


<commit_before>#include "Transcriptome.h"
#include "ReadAlign.h"
#include "serviceFuns.cpp"

int alignToTranscript(Transcript &aG, uint trS1, uint8 trStr1, uint32 *exSE1, uint32 *exLenCum1, uint16 exN1, Transcript &aT) {

    //find exon that overlaps beginning of the read
    uint32 g1=aG.exons[0][EX_G]-trS1;//start of the transcript
    uint32 ex1=binarySearch1<uint32>(g1, exSE1, 2*exN1);
    if (ex1>=2*exN1) return 0; //align start is to the right of all exons

    if (ex1%2==1) {//beginning of the read >=end of an exon
        if (exSE1[ex1]==g1) {//first base of the read is exactly the last base of the exon
            --ex1;
        } else {
            return 0;//beginning of the read is past the end of an exon, align does not belong to this transcript
        };
    };
    ex1=ex1/2; //this is the first exon of the alignment

    aT.nExons=0;
    aT.primaryFlag=false;

    aG.canonSJ[aG.nExons-1]=-999; //marks the last exons
    for (uint32 iab=0; iab<aG.nExons; iab++) {//scan through all blocks of the align
        if (aG.exons[iab][EX_G]+aG.exons[iab][EX_L]>exSE1[2*ex1+1]+trS1+1) {//block extends past exon end
            return 0;
        };

        if (iab==0 || aG.canonSJ[iab-1]<0) {
            aT.exons[aT.nExons][EX_R]=aG.exons[iab][EX_R];
            aT.exons[aT.nExons][EX_G]=aG.exons[iab][EX_G]-trS1-exSE1[2*ex1]+exLenCum1[ex1];
            aT.exons[aT.nExons][EX_L]=aG.exons[iab][EX_L];
            aT.exons[aT.nExons][EX_iFrag]=aG.exons[iab][EX_iFrag];
            if (aT.nExons>0) aT.canonSJ[aT.nExons-1]=aG.canonSJ[iab-1];
            ++aT.nExons;
        } else {
            aT.exons[aT.nExons-1][EX_L]+=aG.exons[iab][EX_L];
        };
        switch (aG.canonSJ[iab]) {
            case -999: //last exon
                if (trStr1==2) {//convert align coordinates if on the -strand
                    uint32 trlength=exLenCum1[exN1-1]+exSE1[2*exN1-1]-exSE1[2*exN1-2]+1; //transcript length
                    for (uint32 iex=0; iex<aT.nExons; iex++) {
                        aT.exons[iex][EX_R]=aG.Lread-(aT.exons[iex][EX_R]+aT.exons[iex][EX_L]);
                        aT.exons[iex][EX_G]=trlength-(aT.exons[iex][EX_G]+aT.exons[iex][EX_L]);
                    };
                    for (uint32 iex=0; iex<aT.nExons/2; iex++) {
                        swap(aT.exons[iex][EX_R],aT.exons[aT.nExons-1-iex][EX_R]);
                        swap(aT.exons[iex][EX_G],aT.exons[aT.nExons-1-iex][EX_G]);
                        swap(aT.exons[iex][EX_L],aT.exons[aT.nExons-1-iex][EX_L]);
                        swap(aT.exons[iex][EX_iFrag],aT.exons[aT.nExons-1-iex][EX_iFrag]);
                    };
                    for (uint32 iex=0; iex<(aT.nExons-1)/2; iex++) {
                        swap(aT.canonSJ[iex],aT.canonSJ[aT.nExons-2-iex]);
                    };
                };
                for (uint32 iex=0; iex<aT.nExons; iex++) {//no junctions in the transcritomic coordinates
                    aT.sjAnnot[iex]=0;
                    aT.shiftSJ[iex][0]=0;
                    aT.shiftSJ[iex][1]=0;
                    aT.sjStr[iex]=0;
                };

                return 1; //reached the end of blocks, align is consistent with this transcript
                break;
            case -3: //mate connection
                ex1=binarySearch1<uint32>(aG.exons[iab+1][EX_G]-trS1, exSE1, 2*exN1);
                if (ex1%2==1) {//beginning of the mext mate in the middle of the exon?
                    return 0; //align does not belong to this transcript
                } else {
                    ex1=ex1/2; //this is the first exon of the second mate
                };
                break;
            case -2: //insertion
                break;
            case -1: //deletion
                break;
            default://junctions
                if ( aG.exons[iab][EX_G]+aG.exons[iab][EX_L]==exSE1[2*ex1+1]+trS1+1 && aG.exons[iab+1][EX_G]==exSE1[2*(ex1+1)]+trS1 ) {
                    //junction matches transcript junction
                    ++ex1;
                } else {
                    return 0;
                };
        };
    };
    return 0; //this should not happen
};

uint32 Transcriptome::quantAlign (Transcript &aG, Transcript *aTall, vector<array<uint32,2>> &readTranscripts, set<uint32> &readGenes) {
    uint32 nAtr=0; //number of alignments to the transcriptome

    //binary search through transcript starts
    uint32 tr1=binarySearch1a<uint>(aG.exons[0][EX_G], trS, nTr);
    if (tr1==(uint32) -1) return 0; //alignment outside of range of all transcripts

    uint aGend=aG.exons[aG.nExons-1][EX_G];

    ++tr1;
    do {//cycle back through all the transcripts
        --tr1;
        if (aGend<=trE[tr1]) {//this transcript contains the read
                int aStatus=alignToTranscript(aG, trS[tr1], trStr[tr1], exSE+2*trExI[tr1], exLenCum+trExI[tr1], trExN[tr1], aTall[nAtr]);
                if (aStatus==1) {//align conforms with the transcript
                    aTall[nAtr].Chr = tr1;
                    aTall[nAtr].Str = trStr[tr1]==1 ? aG.Str : 1-aG.Str; //TODO strandedness
                    if (P.pSolo.strand==-1 || (int32) aTall[nAtr].Str == P.pSolo.strand) {//correct strand
                        uint32 distTTS=trLen[tr1]-(aTall[nAtr].exons[aTall[nAtr].nExons-1][EX_G] + aTall[nAtr].exons[aTall[nAtr].nExons-1][EX_L]);
                        readTranscripts.push_back({tr1,distTTS});
                        readGenes.insert(trGene[tr1]);//genes for all alignments
                        aG.alignGenes.insert(trGene[tr1]);//genes for each alignmentset
                    };
                    ++nAtr;
                };
        };
    } while (trEmax[tr1]>=aGend && tr1>0);

    return nAtr;
};
<commit_msg>Finished implementing CR3 CB/UMI processing. Passed Lane 1 tests.<commit_after>#include "Transcriptome.h"
#include "ReadAlign.h"
#include "serviceFuns.cpp"

int alignToTranscript(Transcript &aG, uint trS1, uint8 trStr1, uint32 *exSE1, uint32 *exLenCum1, uint16 exN1, Transcript &aT) {

    //find exon that overlaps beginning of the read
    uint32 g1=aG.exons[0][EX_G]-trS1;//start of the align
    uint32 ex1=binarySearch1<uint32>(g1, exSE1, 2*exN1);
    //this sholud not be possible - we check before we call this function
    if (ex1>=2*exN1) return 0; //align start is to the right of all exons

    if (ex1%2==1) {//beginning of the read >=end of an exon
        if (exSE1[ex1]==g1) {//first base of the read is exactly the last base of the exon
            --ex1;
        } else {
            return 0;//beginning of the read is past the end of an exon, align does not belong to this transcript
        };
    };
    ex1=ex1/2; //this is the first exon of the alignment

    aT.nExons=0;
    aT.primaryFlag=false;

    aG.canonSJ[aG.nExons-1]=-999; //marks the last exons
    for (uint32 iab=0; iab<aG.nExons; iab++) {//scan through all blocks of the align
        if (aG.exons[iab][EX_G]+aG.exons[iab][EX_L]>exSE1[2*ex1+1]+trS1+1) {//block extends past exon end
            return 0;
        };
        if (iab==0 || aG.canonSJ[iab-1]<0) {
            aT.exons[aT.nExons][EX_R]=aG.exons[iab][EX_R];
            aT.exons[aT.nExons][EX_G]=aG.exons[iab][EX_G]-trS1-exSE1[2*ex1]+exLenCum1[ex1];
            aT.exons[aT.nExons][EX_L]=aG.exons[iab][EX_L];
            aT.exons[aT.nExons][EX_iFrag]=aG.exons[iab][EX_iFrag];
            if (aT.nExons>0) aT.canonSJ[aT.nExons-1]=aG.canonSJ[iab-1];
            ++aT.nExons;
        } else {
            aT.exons[aT.nExons-1][EX_L]+=aG.exons[iab][EX_L];
        };
        switch (aG.canonSJ[iab]) {
            case -999: //last exon
                if (trStr1==2) {//convert align coordinates if on the -strand
                    uint32 trlength=exLenCum1[exN1-1]+exSE1[2*exN1-1]-exSE1[2*exN1-2]+1; //transcript length
                    for (uint32 iex=0; iex<aT.nExons; iex++) {
                        aT.exons[iex][EX_R]=aG.Lread-(aT.exons[iex][EX_R]+aT.exons[iex][EX_L]);
                        aT.exons[iex][EX_G]=trlength-(aT.exons[iex][EX_G]+aT.exons[iex][EX_L]);
                    };
                    for (uint32 iex=0; iex<aT.nExons/2; iex++) {
                        swap(aT.exons[iex][EX_R],aT.exons[aT.nExons-1-iex][EX_R]);
                        swap(aT.exons[iex][EX_G],aT.exons[aT.nExons-1-iex][EX_G]);
                        swap(aT.exons[iex][EX_L],aT.exons[aT.nExons-1-iex][EX_L]);
                        swap(aT.exons[iex][EX_iFrag],aT.exons[aT.nExons-1-iex][EX_iFrag]);
                    };
                    for (uint32 iex=0; iex<(aT.nExons-1)/2; iex++) {
                        swap(aT.canonSJ[iex],aT.canonSJ[aT.nExons-2-iex]);
                    };
                };
                for (uint32 iex=0; iex<aT.nExons; iex++) {//no junctions in the transcritomic coordinates
                    aT.sjAnnot[iex]=0;
                    aT.shiftSJ[iex][0]=0;
                    aT.shiftSJ[iex][1]=0;
                    aT.sjStr[iex]=0;
                };

                return 1; //reached the end of blocks, align is consistent with this transcript
                break;
            case -3: //mate connection
                ex1=binarySearch1<uint32>(aG.exons[iab+1][EX_G]-trS1, exSE1, 2*exN1);
                if (ex1%2==1) {//beginning of the mext mate in the middle of the exon?
                    return 0; //align does not belong to this transcript
                } else {
                    ex1=ex1/2; //this is the first exon of the second mate
                };
                break;
            case -2: //insertion
                break;
            case -1: //deletion
                break;
            default://junctions
                if ( aG.exons[iab][EX_G]+aG.exons[iab][EX_L]==exSE1[2*ex1+1]+trS1+1 && aG.exons[iab+1][EX_G]==exSE1[2*(ex1+1)]+trS1 ) {
                    //junction matches transcript junction
                    ++ex1;
                } else {
                    return 0;
                };
        };
    };
    return 0; //this should not happen
};

uint32 Transcriptome::quantAlign (Transcript &aG, Transcript *aTall, vector<array<uint32,2>> &readTranscripts, set<uint32> &readGenes) {
    uint32 nAtr=0; //number of alignments to the transcriptome

    //binary search through transcript starts
    uint32 tr1=binarySearch1a<uint>(aG.exons[0][EX_G], trS, nTr);//tr1 has the maximum transcript start such that it is still <= align start
    if (tr1==(uint32) -1) return 0; //alignment outside of range of all transcripts

    uint aGend=aG.exons[aG.nExons-1][EX_G];

    ++tr1;
    do {//cycle back through all the transcripts
        --tr1;
        if (aGend<=trE[tr1]) {//this transcript contains the read
                int aStatus=alignToTranscript(aG, trS[tr1], trStr[tr1], exSE+2*trExI[tr1], exLenCum+trExI[tr1], trExN[tr1], aTall[nAtr]);
                if (aStatus==1) {//align conforms with the transcript
                    aTall[nAtr].Chr = tr1;
                    aTall[nAtr].Str = trStr[tr1]==1 ? aG.Str : 1-aG.Str; //TODO strandedness
                    if (P.pSolo.strand==-1 || (int32) aTall[nAtr].Str == P.pSolo.strand) {//correct strand
                        uint32 distTTS=trLen[tr1]-(aTall[nAtr].exons[aTall[nAtr].nExons-1][EX_G] + aTall[nAtr].exons[aTall[nAtr].nExons-1][EX_L]);
                        readTranscripts.push_back({tr1,distTTS});
                        readGenes.insert(trGene[tr1]);//genes for all alignments
                        aG.alignGenes.insert(trGene[tr1]);//genes for each alignmentset
                    };
                    ++nAtr;
                };
        };
    } while (trEmax[tr1]>=aGend && tr1>0);

    return nAtr;
};
<|endoftext|>