<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_privsep_helper.h"
#include "condor_debug.h"

// the methods in this file are all stubbed out for now, until we
// have support for privilege separation on Windows

bool CondorPrivSepHelper::s_instantiated = false;

CondorPrivSepHelper::CondorPrivSepHelper() :
	m_user_initialized(false),
	m_user_name(NULL),
	m_sandbox_initialized(false),
	m_sandbox_path(NULL)
{
	ASSERT(!s_instantiated);
	s_instantiated = true;
}

CondorPrivSepHelper::~CondorPrivSepHelper()
{
	if (m_sandbox_path != NULL) {
		free(m_sandbox_path);
	}
	if( m_user_name ) {
		free(m_user_name);
	}
}

void
CondorPrivSepHelper::initialize_user(const char* name)
{
	m_user_name = strdup(name);

	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::initialize_sandbox(const char* path)
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::chown_sandbox_to_user()
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::chown_sandbox_to_condor()
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

int
CondorPrivSepHelper::create_process(const char*,
                                     ArgList&,
                                     Env&,
                                     const char*,
                                     int[3],
                                     const char*[3],
                                     int,
                                     size_t*,
                                     int,
                                     int,
                                     FamilyInfo*,
                                     int *affinity_mask,
                                     MyString *  error_msg = NULL)
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
	return 0;
}
<commit_msg>fix windows build break in condor_privsep_helper.WINDOWS.cpp<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_privsep_helper.h"
#include "condor_debug.h"

// the methods in this file are all stubbed out for now, until we
// have support for privilege separation on Windows

bool CondorPrivSepHelper::s_instantiated = false;

CondorPrivSepHelper::CondorPrivSepHelper() :
	m_user_initialized(false),
	m_user_name(NULL),
	m_sandbox_initialized(false),
	m_sandbox_path(NULL)
{
	ASSERT(!s_instantiated);
	s_instantiated = true;
}

CondorPrivSepHelper::~CondorPrivSepHelper()
{
	if (m_sandbox_path != NULL) {
		free(m_sandbox_path);
	}
	if( m_user_name ) {
		free(m_user_name);
	}
}

void
CondorPrivSepHelper::initialize_user(const char* name)
{
	m_user_name = strdup(name);

	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::initialize_sandbox(const char* path)
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::chown_sandbox_to_user()
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

void
CondorPrivSepHelper::chown_sandbox_to_condor()
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
}

int
CondorPrivSepHelper::create_process(const char*,
                                     ArgList&,
                                     Env&,
                                     const char*,
                                     int[3],
                                     const char*[3],
                                     int,
                                     size_t*,
                                     int,
                                     int,
                                     FamilyInfo*,
                                     int *affinity_mask,
                                     MyString *  error_msg /*= NULL*/)
{
	EXCEPT("CondorPrivSepHelper: Windows support not implemented");
	return 0;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file rcd_load_ddr4.C
/// @brief Run and manage the DDR4 rcd loading
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/rcd_load_ddr4.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/workarounds/draminit_workarounds.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

///
/// @brief Perform the rcd_load_ddr4 operations - TARGET_TYPE_DIMM specialization
/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                                 std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
    FAPI_INF("rcd_load_ddr4 %s", mss::c_str(i_target));

    constexpr uint64_t CKE_HIGH = mss::ON;
    constexpr uint64_t CKE_LOW = mss::OFF;

    // Per DDR4RCD02, tSTAB is us. We want this in cycles for the CCS.
    const uint64_t tSTAB = mss::us_to_cycles(i_target, mss::tstab());
    constexpr uint8_t FS0 = 0; // Function space 0

    // RCD 4-bit data - integral represents rc#
    static const std::vector< cw_data > l_rcd_4bit_data =
    {
        { FS0, 0,  eff_dimm_ddr4_rc00,    mss::tmrd()    },
        { FS0, 1,  eff_dimm_ddr4_rc01,    mss::tmrd()    },
        { FS0, 2,  eff_dimm_ddr4_rc02,    tSTAB          },
        { FS0, 3,  eff_dimm_ddr4_rc03,    mss::tmrd_l()  },
        { FS0, 4,  eff_dimm_ddr4_rc04,    mss::tmrd_l()  },
        { FS0, 5,  eff_dimm_ddr4_rc05,    mss::tmrd_l()  },
        // Note: the tMRC1 timing as it is larger for saftey's sake
        // The concern is that if geardown mode is ever required in the future, we would need the longer timing
        { FS0, 6,  eff_dimm_ddr4_rc06_07, mss::tmrc1()   },
        { FS0, 8,  eff_dimm_ddr4_rc08,    mss::tmrd()    },
        { FS0, 10, eff_dimm_ddr4_rc0a,    tSTAB          },
        { FS0, 11, eff_dimm_ddr4_rc0b,    mss::tmrd_l()  },
        { FS0, 12, eff_dimm_ddr4_rc0c,    mss::tmrd()    },
        { FS0, 13, eff_dimm_ddr4_rc0d,    mss::tmrd_l2() },
        { FS0, 14, eff_dimm_ddr4_rc0e,    mss::tmrd()    },
        { FS0, 15, eff_dimm_ddr4_rc0f,    mss::tmrd_l2() },
    };

    // RCD 4-bit data - integral represents rc#
    static const cw_data l_rc09_4bit_data( FS0, 9, eff_dimm_ddr4_rc09, mss::tmrd() );

    // RCD 8-bit data - integral represents rc#
    static const std::vector< cw_data > l_rcd_8bit_data =
    {
        { FS0, 1,  eff_dimm_ddr4_rc_1x, mss::tmrd()   },
        { FS0, 2,  eff_dimm_ddr4_rc_2x, mss::tmrd()   },
        { FS0, 3,  eff_dimm_ddr4_rc_3x, tSTAB         },
        { FS0, 4,  eff_dimm_ddr4_rc_4x, mss::tmrd()   },
        { FS0, 5,  eff_dimm_ddr4_rc_5x, mss::tmrd()   },
        { FS0, 6,  eff_dimm_ddr4_rc_6x, mss::tmrd()   },
        { FS0, 7,  eff_dimm_ddr4_rc_7x, mss::tmrd_l() },
        { FS0, 8,  eff_dimm_ddr4_rc_8x, mss::tmrd()   },
        { FS0, 9,  eff_dimm_ddr4_rc_9x, mss::tmrd()   },
        { FS0, 10, eff_dimm_ddr4_rc_ax, mss::tmrd()   },
        { FS0, 11, eff_dimm_ddr4_rc_bx, mss::tmrd_l() },
    };

    // Secret sauce : insider knowledge
    // The JEDEC spec doesn't mention anything about ordering of RCWs
    // but a supplier informed us that we need to send with CKE low:
    // 4-bit RCWs first (excluding RC09), followed by 8-bit RCWs.
    // Then with CKE high (We raise it w/the RCW): 4-bit RC09

    // Load 4-bit data
    FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, io_inst, CKE_LOW),
              "Failed to load 4-bit control words for %s",
              mss::c_str(i_target));

    // Load 8-bit data
    FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, io_inst, CKE_LOW),
              "Failed to load 8-bit control words for %s",
              mss::c_str(i_target));

    // Load RC09
    FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, io_inst, CKE_HIGH),
              "Failed to load 4-bit RC09 control word for %s",
              mss::c_str(i_target));

    // Toggle RC06 again to ensure the DRAM is reset properly
    FAPI_TRY( mss::workarounds::rcw_reset_dram(i_target, io_inst), "%s failed to add reset workaround functionality",
              mss::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

} // namespace
<commit_msg>Fixes CKE levels during RCD initialization<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file rcd_load_ddr4.C
/// @brief Run and manage the DDR4 rcd loading
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/rcd_load_ddr4.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/workarounds/draminit_workarounds.H>
#include <lib/workarounds/ccs_workarounds.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

///
/// @brief Perform the rcd_load_ddr4 operations - TARGET_TYPE_DIMM specialization
/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in] i_sim, true IFF in simulation mode
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                                 const bool i_sim,
                                 std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
    FAPI_INF("rcd_load_ddr4 %s", mss::c_str(i_target));

    constexpr uint64_t CKE_HIGH = mss::ON;
    constexpr uint64_t CKE_LOW = mss::OFF;

    // Per DDR4RCD02, tSTAB is us. We want this in cycles for the CCS.
    const uint64_t tSTAB = mss::us_to_cycles(i_target, mss::tstab());
    constexpr uint8_t FS0 = 0; // Function space 0

    // RCD 4-bit data - integral represents rc#
    static const std::vector< cw_data > l_rcd_4bit_data =
    {
        { FS0, 0,  eff_dimm_ddr4_rc00,    mss::tmrd()    },
        { FS0, 1,  eff_dimm_ddr4_rc01,    mss::tmrd()    },
        { FS0, 2,  eff_dimm_ddr4_rc02,    tSTAB          },
        { FS0, 3,  eff_dimm_ddr4_rc03,    mss::tmrd_l()  },
        { FS0, 4,  eff_dimm_ddr4_rc04,    mss::tmrd_l()  },
        { FS0, 5,  eff_dimm_ddr4_rc05,    mss::tmrd_l()  },
        // Note: the tMRC1 timing as it is larger for saftey's sake
        // The concern is that if geardown mode is ever required in the future, we would need the longer timing
        { FS0, 6,  eff_dimm_ddr4_rc06_07, mss::tmrc1()   },
        { FS0, 8,  eff_dimm_ddr4_rc08,    mss::tmrd()    },
        { FS0, 10, eff_dimm_ddr4_rc0a,    tSTAB          },
        { FS0, 11, eff_dimm_ddr4_rc0b,    mss::tmrd_l()  },
        { FS0, 12, eff_dimm_ddr4_rc0c,    mss::tmrd()    },
        { FS0, 13, eff_dimm_ddr4_rc0d,    mss::tmrd_l2() },
        { FS0, 14, eff_dimm_ddr4_rc0e,    mss::tmrd()    },
        { FS0, 15, eff_dimm_ddr4_rc0f,    mss::tmrd_l2() },
    };

    // RCD 4-bit data - integral represents rc#
    static const cw_data l_rc09_4bit_data( FS0, 9, eff_dimm_ddr4_rc09, mss::tmrd() );

    // RCD 8-bit data - integral represents rc#
    static const std::vector< cw_data > l_rcd_8bit_data =
    {
        { FS0, 1,  eff_dimm_ddr4_rc_1x, mss::tmrd()   },
        { FS0, 2,  eff_dimm_ddr4_rc_2x, mss::tmrd()   },
        { FS0, 3,  eff_dimm_ddr4_rc_3x, tSTAB         },
        { FS0, 4,  eff_dimm_ddr4_rc_4x, mss::tmrd()   },
        { FS0, 5,  eff_dimm_ddr4_rc_5x, mss::tmrd()   },
        { FS0, 6,  eff_dimm_ddr4_rc_6x, mss::tmrd()   },
        { FS0, 7,  eff_dimm_ddr4_rc_7x, mss::tmrd_l() },
        { FS0, 8,  eff_dimm_ddr4_rc_8x, mss::tmrd()   },
        { FS0, 9,  eff_dimm_ddr4_rc_9x, mss::tmrd()   },
        { FS0, 10, eff_dimm_ddr4_rc_ax, mss::tmrd()   },
        { FS0, 11, eff_dimm_ddr4_rc_bx, mss::tmrd_l() },
    };

    // Secret sauce : insider knowledge
    // The JEDEC spec doesn't mention anything about ordering of RCWs
    // but a supplier informed us that we need to send with CKE low:
    // 4-bit RCWs first (excluding RC09), followed by 8-bit RCWs.
    // Then with CKE high (We raise it w/the RCW): 4-bit RC09

    // Load 4-bit data
    FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, i_sim, io_inst, CKE_LOW),
              "Failed to load 4-bit control words for %s",
              mss::c_str(i_target));

    // Load 8-bit data
    FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, i_sim, io_inst, CKE_LOW),
              "Failed to load 8-bit control words for %s",
              mss::c_str(i_target));

    // Load RC09
    FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, i_sim, io_inst, CKE_HIGH),
              "Failed to load 4-bit RC09 control word for %s",
              mss::c_str(i_target));

    // Toggle RC06 again to ensure the DRAM is reset properly
    FAPI_TRY( mss::workarounds::rcw_reset_dram(i_target, i_sim, io_inst), "%s failed to add reset workaround functionality",
              mss::c_str(i_target));

    // Now, hold the CKE's high, so we don't power down the RCD and re power it back up
    mss::ccs::workarounds::hold_cke_high(io_inst);

fapi_try_exit:
    return fapi2::current_err;
}

} // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "ash/system/power/tray_power.h"

#include "ash/shell.h"
#include "ash/system/date/date_view.h"
#include "ash/system/power/power_supply_status.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "unicode/fieldpos.h"
#include "unicode/fmtable.h"

namespace ash {
namespace internal {

namespace {
// Width and height of battery images.
const int kBatteryImageHeight = 25;
const int kBatteryImageWidth = 25;
// Number of different power states.
const int kNumPowerImages = 15;
}

namespace tray {

// This view is used only for the tray.
class PowerTrayView : public views::ImageView {
 public:
  PowerTrayView() {
    UpdateImage();
  }

  virtual ~PowerTrayView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateImage();
    SetVisible(status.battery_is_present);
  }

 private:
  void UpdateImage() {
    SkBitmap image;
    gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_AURA_UBER_TRAY_POWER_SMALL);

    int image_index = 0;
    if (supply_status_.battery_percentage >= 100) {
      image_index = kNumPowerImages - 1;
    } else if (!supply_status_.battery_is_present) {
      image_index = kNumPowerImages;
    } else {
      image_index = static_cast<int> (
          supply_status_.battery_percentage / 100.0 *
          (kNumPowerImages - 1));
      image_index =
        std::max(std::min(image_index, kNumPowerImages - 2), 0);
    }

    // TODO(mbolohan): Remove the 2px offset when the assets are centered. See
    // crbug.com/119832.
    SkIRect region = SkIRect::MakeXYWH(
        (supply_status_.line_power_on ? kBatteryImageWidth : 0) + 2,
        image_index * kBatteryImageHeight,
        kBatteryImageWidth - 2, kBatteryImageHeight);
    all.ToSkBitmap()->extractSubset(&image, region);

    SetImage(image);
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
};

// This view is used only for the popup.
class PowerPopupView : public views::Label {
 public:
  PowerPopupView() {
    SetHorizontalAlignment(ALIGN_RIGHT);
    UpdateText();
  }

  virtual ~PowerPopupView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateText();
  }

 private:
  void UpdateText() {
    base::TimeDelta time = base::TimeDelta::FromSeconds(
        supply_status_.line_power_on ?
        supply_status_.battery_seconds_to_full :
        supply_status_.battery_seconds_to_empty);
    int hour = time.InHours();
    int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    if (hour || min) {
      SetText(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_BATTERY_STATUS,
          base::IntToString16(
              static_cast<int>(supply_status_.battery_percentage)),
          base::IntToString16(hour),
          base::IntToString16(min)));
    } else {
      if (supply_status_.line_power_on) {
        SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL));
      } else {
        // Completely discharged? ... ha?
        SetText(string16());
      }
    }
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerPopupView);
};

}  // namespace tray

TrayPower::TrayPower()
    : power_(NULL),
      power_tray_(NULL) {
}

TrayPower::~TrayPower() {
}

views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
  // There may not be enough information when this is created about whether
  // there is a battery or not. So always create this, and adjust visibility as
  // necessary.
  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  power_tray_.reset(new tray::PowerTrayView());
  power_tray_->UpdatePowerStatus(power_status);
  return power_tray_.get();
}

views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
  date_.reset(new tray::DateView(tray::DateView::DATE));
  if (status != user::LOGGED_IN_NONE && status != user::LOGGED_IN_LOCKED)
    date_->set_actionable(true);

  views::View* container = new views::View;
  views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal,
      kTrayPopupPaddingHorizontal, 10, 0);
  layout->set_spread_blank_space(true);
  container->SetLayoutManager(layout);
  container->set_background(views::Background::CreateSolidBackground(
      SkColorSetRGB(0xf1, 0xf1, 0xf1)));
  container->AddChildView(date_.get());

  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  if (power_status.battery_is_present) {
    power_.reset(new tray::PowerPopupView());
    power_->UpdatePowerStatus(power_status);
    container->AddChildView(power_.get());
  }
  return container;
}

views::View* TrayPower::CreateDetailedView(user::LoginStatus status) {
  return NULL;
}

void TrayPower::DestroyTrayView() {
  power_tray_.reset();
}

void TrayPower::DestroyDefaultView() {
  date_.reset();
  power_.reset();
}

void TrayPower::DestroyDetailedView() {
}

void TrayPower::OnPowerStatusChanged(const PowerSupplyStatus& status) {
  if (power_tray_.get())
    power_tray_->UpdatePowerStatus(status);
  if (power_.get())
    power_->UpdatePowerStatus(status);
}

}  // namespace internal
}  // namespace ash
<commit_msg>ash: Fix right-alignment of power-status text.<commit_after>// Copyright (c) 2012 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 "ash/system/power/tray_power.h"

#include "ash/shell.h"
#include "ash/system/date/date_view.h"
#include "ash/system/power/power_supply_status.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "unicode/fieldpos.h"
#include "unicode/fmtable.h"

namespace ash {
namespace internal {

namespace {
// Width and height of battery images.
const int kBatteryImageHeight = 25;
const int kBatteryImageWidth = 25;
// Number of different power states.
const int kNumPowerImages = 15;
}

namespace tray {

// This view is used only for the tray.
class PowerTrayView : public views::ImageView {
 public:
  PowerTrayView() {
    UpdateImage();
  }

  virtual ~PowerTrayView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateImage();
    SetVisible(status.battery_is_present);
  }

 private:
  void UpdateImage() {
    SkBitmap image;
    gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_AURA_UBER_TRAY_POWER_SMALL);

    int image_index = 0;
    if (supply_status_.battery_percentage >= 100) {
      image_index = kNumPowerImages - 1;
    } else if (!supply_status_.battery_is_present) {
      image_index = kNumPowerImages;
    } else {
      image_index = static_cast<int> (
          supply_status_.battery_percentage / 100.0 *
          (kNumPowerImages - 1));
      image_index =
        std::max(std::min(image_index, kNumPowerImages - 2), 0);
    }

    // TODO(mbolohan): Remove the 2px offset when the assets are centered. See
    // crbug.com/119832.
    SkIRect region = SkIRect::MakeXYWH(
        (supply_status_.line_power_on ? kBatteryImageWidth : 0) + 2,
        image_index * kBatteryImageHeight,
        kBatteryImageWidth - 2, kBatteryImageHeight);
    all.ToSkBitmap()->extractSubset(&image, region);

    SetImage(image);
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
};

// This view is used only for the popup.
class PowerPopupView : public views::Label {
 public:
  PowerPopupView() {
    SetHorizontalAlignment(ALIGN_RIGHT);
    SetMultiLine(true);
    UpdateText();
  }

  virtual ~PowerPopupView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateText();
  }

 private:
  void UpdateText() {
    base::TimeDelta time = base::TimeDelta::FromSeconds(
        supply_status_.line_power_on ?
        supply_status_.battery_seconds_to_full :
        supply_status_.battery_seconds_to_empty);
    int hour = time.InHours();
    int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    if (hour || min) {
      SetText(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_BATTERY_STATUS,
          base::IntToString16(
              static_cast<int>(supply_status_.battery_percentage)),
          base::IntToString16(hour),
          base::IntToString16(min)));
    } else {
      if (supply_status_.line_power_on) {
        SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL));
      } else {
        // Completely discharged? ... ha?
        SetText(string16());
      }
    }
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerPopupView);
};

}  // namespace tray

TrayPower::TrayPower()
    : power_(NULL),
      power_tray_(NULL) {
}

TrayPower::~TrayPower() {
}

views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
  // There may not be enough information when this is created about whether
  // there is a battery or not. So always create this, and adjust visibility as
  // necessary.
  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  power_tray_.reset(new tray::PowerTrayView());
  power_tray_->UpdatePowerStatus(power_status);
  return power_tray_.get();
}

views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
  date_.reset(new tray::DateView(tray::DateView::DATE));
  if (status != user::LOGGED_IN_NONE && status != user::LOGGED_IN_LOCKED)
    date_->set_actionable(true);

  views::View* container = new views::View;
  views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal,
      kTrayPopupPaddingHorizontal, 10, 0);
  layout->set_spread_blank_space(true);
  container->SetLayoutManager(layout);
  container->set_background(views::Background::CreateSolidBackground(
      SkColorSetRGB(0xf1, 0xf1, 0xf1)));
  container->AddChildView(date_.get());

  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  if (power_status.battery_is_present) {
    power_.reset(new tray::PowerPopupView());
    power_->UpdatePowerStatus(power_status);
    container->AddChildView(power_.get());
  }
  return container;
}

views::View* TrayPower::CreateDetailedView(user::LoginStatus status) {
  return NULL;
}

void TrayPower::DestroyTrayView() {
  power_tray_.reset();
}

void TrayPower::DestroyDefaultView() {
  date_.reset();
  power_.reset();
}

void TrayPower::DestroyDetailedView() {
}

void TrayPower::OnPowerStatusChanged(const PowerSupplyStatus& status) {
  if (power_tray_.get())
    power_tray_->UpdatePowerStatus(status);
  if (power_.get())
    power_->UpdatePowerStatus(status);
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


<commit_before>#include "RunThreshold.h"

/**
 * Prints the command-line usage instructions for the similarity command
 */
void RunThreshold::printUsage() {
  printf("\n");
  printf("Usage: ./kinc threshold [options]\n");
  printf("The list of required options:\n");
  printf("  --ematrix|-e     The file name that contains the expression matrix.\n");
  printf("                   The rows must be genes or probe sets and columns are samples\n");
  printf("  --method|-m      The correlation methods used. Supported methods include\n");
  printf("                   Pearson's correlation ('pc'), Spearman's rank ('sc')\n");
  printf("                   and Mutual Information ('mi'). Provide the methods that\n");
  printf("                   were used in the 'similarity' step.  The methods must appear\n");
  printf("                   in the same order.");
  printf("  --th_method|-t   The method to be used for thresholding.  Only one method can\n");
  printf("                   be used for thresholding even if multiple methods are provided\n");
  printf("                   for the --method argument.\n");
  printf("  --rows|-r        The number of lines in the input file including the header\n");
  printf("                   column if it exists\n");
  printf("  --cols|-c        The number of columns in the input file minus the first\n");
  printf("                   column that contains gene names\n");
  printf("\n");
  printf("Optional expression matrix arguments:\n");
  printf("  --omit_na        Provide this flag to ignore missing values.\n");
  printf("  --na_val|-n      A string representing the missing values in the input file\n");
  printf("                   (e.g. NA or 0.000)\n");
  printf("  --func|-f        A transformation function to apply to elements of the ematrix.\n");
  printf("                   Values include: log, log2 or log10. Default is to not perform\n");
  printf("                   any transformation.\n");
  printf("  --headers        Provide this flag if the first line of the matrix contains\n");
  printf("                   headers.\n");
  printf("\n");
  printf("Optional RMT arguments:\n");
  printf("  --th|-t          A decimal indicating the start threshold. For Pearson's.\n");
  printf("                   and Spearman's, the default is 0.99. For Mutual\n");
  printf("                   information (--method mi), the default is the maximum MI value\n");
  printf("                   in the similarity matrix\n");
  printf("  --step|-s        The threshold step size, to subtract at each iteration of RMT.\n");
  printf("                   The default is 0.001\n");
  printf("  --chi|-i         The Chi-square test value which when encountered RMT will stop.\n");
  printf("                   The algorithm will only stop if it first encounters a Chi-square\n");
  printf("                   value of 99.607 (df = 60, p-value = 0.001).\n");
  printf("\n");
  printf("Optional clustered data arguments:\n");
  printf("  --clustering|-l  The type of clustering that was performed during construction\n");
  printf("                   of the similarity matrix (e.g. 'mixmod').\n");
  printf("  --missing|-g     The total number of allowed missing values.  Each gene\n");
  printf("                   comparision can potentially have a missing value in any\n");
  printf("                   sample.  When the maximum number of missing values exceeds\n");
  printf("                   this value the clusters are ignored.\n");
  printf("                   If not provided, no limit is set.\n");
  printf("  --min_csize|-z   The minimum cluster size (number of samples per cluster).\n");
  printf("                   Default is 30\n");
  printf("  --max_modes|-d   The maximum number of modes. If a pair-wise comparision\n");
  printf("                   has multiple modes (i.e. multiple clusters) then only clusters from those\n");
  printf("                   comparisions with modes equal to or less than the value specified are\n");
  printf("                   included. Default is 1.\n");
  printf("\n");
  printf("For Help:\n");
  printf("  --help|-h     Print these usage instructions\n");
  printf("\n");
}

/**
 *
 */
RunThreshold::RunThreshold(int argc, char *argv[]) {
  // initialize some of the program parameters
  max_missing = INFINITY;
  max_modes = 1;
  min_cluster_size = 30;

  thresholdStart = 0.99;
  thresholdStep  = 0.001;
  chiSoughtValue = 200;

  // Initialize the array of method names. We set it to 10 as max. We'll
  // most likely never have this many of similarity methods available.
  method = (char **) malloc(sizeof(char *) * 10);

  // The concatenated method.
  char * cmethod;

  // The value returned by getopt_long.
  int c;

  // loop through the incoming arguments until the
  // getopt_long function returns -1. Then we break out of the loop
  while(1) {
    int option_index = 0;

    // specify the long options. The values returned are specified to be the
    // short options which are then handled by the case statement below
    static struct option long_options[] = {
      {"help",         no_argument,       0,  'h' },
      {"method",       required_argument, 0,  'm' },
      {"th_method",    required_argument, 0,  'p' },
      {"missing",      required_argument, 0,  'g' },
      {"size",         required_argument, 0,  'z' },
      // Expression matrix options.
      {"rows",         required_argument, 0,  'r' },
      {"cols",         required_argument, 0,  'c' },
      {"headers",      no_argument,       &headers,  1 },
      {"omit_na",      no_argument,       &omit_na,  1 },
      {"func",         required_argument, 0,  'f' },
      {"na_val",       required_argument, 0,  'n' },
      {"ematrix",      required_argument, 0,  'e' },
      // Clustered options
      {"clustering",   required_argument, 0,  'l' },
      {"max_missing",  required_argument, 0,  'g' },
      {"min_csize",    required_argument, 0,  'z' },
      {"max_modes",    required_argument, 0,  'd' },
      // RMT Threshold options.
      {"chi",          required_argument, 0,  'i' },
      {"th",           required_argument, 0,  't' },
      {"step",         required_argument, 0,  's' },

      // Last element required to be all zeros.
      {0, 0, 0,  0 }
    };

    // get the next option
    c = getopt_long(argc, argv, "m:g:z:r:c:f:n:e:t:d:l:h", long_options, &option_index);

    // if the index is -1 then we have reached the end of the options list
    // and we break out of the while loop
    if (c == -1) {
      break;
    }

    // handle the options
    switch (c) {
      case 0:
        break;
      case 'm':
        cmethod = optarg;
        break;
      case 'p':
        th_method = optarg;
        break;
      // Clustering options.
      case 'l':
        clustering = optarg;
        break;
      case 'z':
        min_cluster_size = atoi(optarg);
        break;
      case 'g':
        max_missing = atoi(optarg);
        break;
      case 'd':
        max_modes = atoi(optarg);
        break;
      // RMT threshold options.
      case 't':
        thresholdStart = atof(optarg);
        break;
      case 'i':
        chiSoughtValue = atof(optarg);
        break;
      case 's':
        thresholdStep = atof(optarg);
        break;
      // Expression matrix options.
      case 'e':
        infilename = optarg;
        break;
      case 'r':
        rows = atoi(optarg);
        break;
      case 'c':
        cols = atoi(optarg);
        break;
      case 'n':
        na_val = optarg;
        break;
      case 'f':
        strcpy(func, optarg);
        break;
      // Help and catch-all options.
      case 'h':
        printUsage();
        exit(-1);
        break;
      case '?':
        exit(-1);
        break;
      case ':':
        printUsage();
        exit(-1);
        break;
      default:
        printUsage();
    }
  }

  // Make sure the similarity method is valid.
  if (!cmethod) {
    fprintf(stderr,"Please provide the method (--method option).\n");
    exit(-1);
  }
  parseMethods(cmethod);

  if (clustering) {
    // Make sure the clustering method is valid.
    if (strcmp(clustering, "mixmod") != 0) {
      fprintf(stderr,"Error: The clustering type (--clustering option) must be 'mixmod'. It is currently the only clustering method supported.\n");
          exit(-1);
    }

    if (max_missing < -1) {
      fprintf(stderr, "Please provide a positive integer value for maximum missing values (--max_missing option).\n");
      exit(-1);
    }
    if (max_modes < 1) {
      fprintf(stderr, "Please provide a positive integer greater than 1 for the maximum modes values (--max_modes option).\n");
      exit(-1);
    }
    if (min_cluster_size < 0 || min_cluster_size == 0) {
      fprintf(stderr, "Please provide a positive integer value for the minimum cluster size (--min_cluster_size option).\n");
      exit(-1);
    }
  }

  // Make sure we have a positive integer for the rows and columns of the matrix.
  if (rows < 0 || rows == 0) {
    fprintf(stderr, "Please provide a positive integer value for the number of rows in the \n");
    fprintf(stderr, "expression matrix (--rows option).\n");
    exit(-1);
  }
  if (cols < 0 || cols == 0) {
    fprintf(stderr, "Please provide a positive integer value for the number of columns in\n");
    fprintf(stderr, "the expression matrix (--cols option).\n");
    exit(-1);
  }

  if (omit_na && !na_val) {
    fprintf(stderr, "Error: The missing value string should be provided (--na_val option).\n");
    exit(-1);
  }

  // make sure the required arguments are set and appropriate
  if (!infilename) {
    fprintf(stderr,"Please provide an expression matrix (--ematrix option).\n");
    exit(-1);
  }

  // TODO: make sure the th_method is in the method array.

  // Load the input expression matrix.
  ematrix = new EMatrix(infilename, rows, cols, headers, omit_na, na_val, func);

  if (headers) {
    printf("  Skipping header lines\n");
  }
  printf("  Performing transformation: %s \n", func);
  if (omit_na) {
    printf("  Missing values are: '%s'\n", na_val);
  }
  for(int i = 0; i < this->num_methods; i++) {
    printf("  Expecting similarity methods: '%s'\n", method[i]);
  }
  printf("  Method for thresholding: %s\n", th_method);
  printf("  Start threshold: %f\n", thresholdStart);
  printf("  Stopping Chi-square %f\n", chiSoughtValue);
  printf("  Step per iteration: %f\n", thresholdStep);
}
/**
 *
 */
void RunThreshold::parseMethods(char * methods_str) {
  // Split the method into as many parts
  char * tmp;
  int i = 0;
  tmp = strstr(methods_str, ",");
  while (tmp) {
    // Get the method and make sure it's valid.
    method[i] = (char *) malloc(sizeof(char) * (tmp - methods_str + 1));
    strncpy(method[i], methods_str, (tmp - methods_str));
    methods_str = tmp + 1;
    tmp = strstr(methods_str, ",");
    i++;
  }
  // Get the last element of the methods_str.
  method[i] = (char *) malloc(sizeof(char) * strlen(methods_str) + 1);
  strcpy(method[i], methods_str);
  i++;

  this->num_methods = i;

  for (i = 0; i < this->num_methods; i++) {
    if (strcmp(method[i], "pc") != 0 &&
        strcmp(method[i], "mi") != 0 &&
        strcmp(method[i], "sc") != 0 ) {
      fprintf(stderr,"Error: The method (--method option) must contain only 'pc', 'sc' or 'mi'.\n");
      exit(-1);
    }
    // Make sure the method isn't specified more than once.
    for (int j = 0; j < i; j++) {
      if (strcmp(method[i], method[j]) == 0) {
        fprintf(stderr,"Error: You may only specify a similarity method once (--method option).\n");
        exit(-1);
      }
    }
  }
}
/**
 *
 */
RunThreshold::~RunThreshold() {
  delete ematrix;
}

/**
 *
 */
void RunThreshold::execute() {

  // Find the RMT threshold.
  RMTThreshold * rmt = new RMTThreshold(ematrix, method, num_methods, th_method, thresholdStart,
      thresholdStep, chiSoughtValue, clustering, min_cluster_size, max_missing,
      max_modes);
  rmt->findThreshold();
  printf("Done.\n");
}
<commit_msg>Fixed bug when --th_method arg is not provided<commit_after>#include "RunThreshold.h"

/**
 * Prints the command-line usage instructions for the similarity command
 */
void RunThreshold::printUsage() {
  printf("\n");
  printf("Usage: ./kinc threshold [options]\n");
  printf("The list of required options:\n");
  printf("  --ematrix|-e     The file name that contains the expression matrix.\n");
  printf("                   The rows must be genes or probe sets and columns are samples\n");
  printf("  --method|-m      The correlation methods used. Supported methods include\n");
  printf("                   Pearson's correlation ('pc'), Spearman's rank ('sc')\n");
  printf("                   and Mutual Information ('mi'). Provide the methods that\n");
  printf("                   were used in the 'similarity' step.  The methods must appear\n");
  printf("                   in the same order.\n");
  printf("  --th_method|-t   The method to be used for thresholding.  Only one method can\n");
  printf("                   be used for thresholding even if multiple methods are provided\n");
  printf("                   for the --method argument.\n");
  printf("  --rows|-r        The number of lines in the input file including the header\n");
  printf("                   column if it exists\n");
  printf("  --cols|-c        The number of columns in the input file minus the first\n");
  printf("                   column that contains gene names\n");
  printf("\n");
  printf("Optional expression matrix arguments:\n");
  printf("  --omit_na        Provide this flag to ignore missing values.\n");
  printf("  --na_val|-n      A string representing the missing values in the input file\n");
  printf("                   (e.g. NA or 0.000)\n");
  printf("  --func|-f        A transformation function to apply to elements of the ematrix.\n");
  printf("                   Values include: log, log2 or log10. Default is to not perform\n");
  printf("                   any transformation.\n");
  printf("  --headers        Provide this flag if the first line of the matrix contains\n");
  printf("                   headers.\n");
  printf("\n");
  printf("Optional RMT arguments:\n");
  printf("  --th|-t          A decimal indicating the start threshold. For Pearson's.\n");
  printf("                   and Spearman's, the default is 0.99. For Mutual\n");
  printf("                   information (--method mi), the default is the maximum MI value\n");
  printf("                   in the similarity matrix\n");
  printf("  --step|-s        The threshold step size, to subtract at each iteration of RMT.\n");
  printf("                   The default is 0.001\n");
  printf("  --chi|-i         The Chi-square test value which when encountered RMT will stop.\n");
  printf("                   The algorithm will only stop if it first encounters a Chi-square\n");
  printf("                   value of 99.607 (df = 60, p-value = 0.001).\n");
  printf("\n");
  printf("Optional clustered data arguments:\n");
  printf("  --clustering|-l  The type of clustering that was performed during construction\n");
  printf("                   of the similarity matrix (e.g. 'mixmod').\n");
  printf("  --missing|-g     The total number of allowed missing values.  Each gene\n");
  printf("                   comparision can potentially have a missing value in any\n");
  printf("                   sample.  When the maximum number of missing values exceeds\n");
  printf("                   this value the clusters are ignored.\n");
  printf("                   If not provided, no limit is set.\n");
  printf("  --min_csize|-z   The minimum cluster size (number of samples per cluster).\n");
  printf("                   Default is 30\n");
  printf("  --max_modes|-d   The maximum number of modes. If a pair-wise comparision\n");
  printf("                   has multiple modes (i.e. multiple clusters) then only clusters from those\n");
  printf("                   comparisions with modes equal to or less than the value specified are\n");
  printf("                   included. Default is 1.\n");
  printf("\n");
  printf("For Help:\n");
  printf("  --help|-h     Print these usage instructions\n");
  printf("\n");
}

/**
 *
 */
RunThreshold::RunThreshold(int argc, char *argv[]) {
  // initialize some of the program parameters
  max_missing = INFINITY;
  max_modes = 1;
  min_cluster_size = 30;

  thresholdStart = 0.99;
  thresholdStep  = 0.001;
  chiSoughtValue = 200;

  // Initialize the array of method names. We set it to 10 as max. We'll
  // most likely never have this many of similarity methods available.
  method = (char **) malloc(sizeof(char *) * 10);

  // The concatenated method.
  char * cmethod;

  // The value returned by getopt_long.
  int c;

  // loop through the incoming arguments until the
  // getopt_long function returns -1. Then we break out of the loop
  while(1) {
    int option_index = 0;

    // specify the long options. The values returned are specified to be the
    // short options which are then handled by the case statement below
    static struct option long_options[] = {
      {"help",         no_argument,       0,  'h' },
      {"method",       required_argument, 0,  'm' },
      {"th_method",    required_argument, 0,  'p' },
      {"missing",      required_argument, 0,  'g' },
      {"size",         required_argument, 0,  'z' },
      // Expression matrix options.
      {"rows",         required_argument, 0,  'r' },
      {"cols",         required_argument, 0,  'c' },
      {"headers",      no_argument,       &headers,  1 },
      {"omit_na",      no_argument,       &omit_na,  1 },
      {"func",         required_argument, 0,  'f' },
      {"na_val",       required_argument, 0,  'n' },
      {"ematrix",      required_argument, 0,  'e' },
      // Clustered options
      {"clustering",   required_argument, 0,  'l' },
      {"max_missing",  required_argument, 0,  'g' },
      {"min_csize",    required_argument, 0,  'z' },
      {"max_modes",    required_argument, 0,  'd' },
      // RMT Threshold options.
      {"chi",          required_argument, 0,  'i' },
      {"th",           required_argument, 0,  't' },
      {"step",         required_argument, 0,  's' },

      // Last element required to be all zeros.
      {0, 0, 0,  0 }
    };

    // get the next option
    c = getopt_long(argc, argv, "m:g:z:r:c:f:n:e:t:d:l:h", long_options, &option_index);

    // if the index is -1 then we have reached the end of the options list
    // and we break out of the while loop
    if (c == -1) {
      break;
    }

    // handle the options
    switch (c) {
      case 0:
        break;
      case 'm':
        cmethod = optarg;
        break;
      case 'p':
        th_method = optarg;
        break;
      // Clustering options.
      case 'l':
        clustering = optarg;
        break;
      case 'z':
        min_cluster_size = atoi(optarg);
        break;
      case 'g':
        max_missing = atoi(optarg);
        break;
      case 'd':
        max_modes = atoi(optarg);
        break;
      // RMT threshold options.
      case 't':
        thresholdStart = atof(optarg);
        break;
      case 'i':
        chiSoughtValue = atof(optarg);
        break;
      case 's':
        thresholdStep = atof(optarg);
        break;
      // Expression matrix options.
      case 'e':
        infilename = optarg;
        break;
      case 'r':
        rows = atoi(optarg);
        break;
      case 'c':
        cols = atoi(optarg);
        break;
      case 'n':
        na_val = optarg;
        break;
      case 'f':
        strcpy(func, optarg);
        break;
      // Help and catch-all options.
      case 'h':
        printUsage();
        exit(-1);
        break;
      case '?':
        exit(-1);
        break;
      case ':':
        printUsage();
        exit(-1);
        break;
      default:
        printUsage();
    }
  }

  // Make sure the similarity method is valid.
  if (!cmethod) {
    fprintf(stderr,"Please provide the method (--method option).\n");
    exit(-1);
  }
  parseMethods(cmethod);

  if (clustering) {
    // Make sure the clustering method is valid.
    if (strcmp(clustering, "mixmod") != 0) {
      fprintf(stderr,"Error: The clustering type (--clustering option) must be 'mixmod'. It is currently the only clustering method supported.\n");
          exit(-1);
    }

    if (max_missing < -1) {
      fprintf(stderr, "Please provide a positive integer value for maximum missing values (--max_missing option).\n");
      exit(-1);
    }
    if (max_modes < 1) {
      fprintf(stderr, "Please provide a positive integer greater than 1 for the maximum modes values (--max_modes option).\n");
      exit(-1);
    }
    if (min_cluster_size < 0 || min_cluster_size == 0) {
      fprintf(stderr, "Please provide a positive integer value for the minimum cluster size (--min_cluster_size option).\n");
      exit(-1);
    }
  }

  // Make sure we have a positive integer for the rows and columns of the matrix.
  if (rows < 0 || rows == 0) {
    fprintf(stderr, "Please provide a positive integer value for the number of rows in the \n");
    fprintf(stderr, "expression matrix (--rows option).\n");
    exit(-1);
  }
  if (cols < 0 || cols == 0) {
    fprintf(stderr, "Please provide a positive integer value for the number of columns in\n");
    fprintf(stderr, "the expression matrix (--cols option).\n");
    exit(-1);
  }

  if (omit_na && !na_val) {
    fprintf(stderr, "Error: The missing value string should be provided (--na_val option).\n");
    exit(-1);
  }

  // make sure the required arguments are set and appropriate
  if (!infilename) {
    fprintf(stderr,"Please provide an expression matrix (--ematrix option).\n");
    exit(-1);
  }

  if (!th_method) {
    fprintf(stderr,"Please provide the method to use for thresholding (e.g. pc, sc, or mi) (--th_method option).\n");
    exit(-1);
  }

  // TODO: make sure the th_method is in the method array.

  if (headers) {
    printf("  Skipping header lines\n");
  }
  printf("  Performing transformation: %s \n", func);
  if (omit_na) {
    printf("  Missing values are: '%s'\n", na_val);
  }
  for(int i = 0; i < this->num_methods; i++) {
    printf("  Expecting similarity methods: '%s'\n", method[i]);
  }
  printf("  Method for thresholding: %s\n", th_method);
  printf("  Start threshold: %f\n", thresholdStart);
  printf("  Stopping Chi-square %f\n", chiSoughtValue);
  printf("  Step per iteration: %f\n", thresholdStep);

  // Load the input expression matrix.
  printf("  Reading expression matrix...\n");
  ematrix = new EMatrix(infilename, rows, cols, headers, omit_na, na_val, func);
}
/**
 *
 */
void RunThreshold::parseMethods(char * methods_str) {
  // Split the method into as many parts
  char * tmp;
  int i = 0;
  tmp = strstr(methods_str, ",");
  while (tmp) {
    // Get the method and make sure it's valid.
    method[i] = (char *) malloc(sizeof(char) * (tmp - methods_str + 1));
    strncpy(method[i], methods_str, (tmp - methods_str));
    methods_str = tmp + 1;
    tmp = strstr(methods_str, ",");
    i++;
  }
  // Get the last element of the methods_str.
  method[i] = (char *) malloc(sizeof(char) * strlen(methods_str) + 1);
  strcpy(method[i], methods_str);
  i++;

  this->num_methods = i;

  for (i = 0; i < this->num_methods; i++) {
    if (strcmp(method[i], "pc") != 0 &&
        strcmp(method[i], "mi") != 0 &&
        strcmp(method[i], "sc") != 0 ) {
      fprintf(stderr,"Error: The method (--method option) must contain only 'pc', 'sc' or 'mi'.\n");
      exit(-1);
    }
    // Make sure the method isn't specified more than once.
    for (int j = 0; j < i; j++) {
      if (strcmp(method[i], method[j]) == 0) {
        fprintf(stderr,"Error: You may only specify a similarity method once (--method option).\n");
        exit(-1);
      }
    }
  }
}
/**
 *
 */
RunThreshold::~RunThreshold() {
  delete ematrix;
}

/**
 *
 */
void RunThreshold::execute() {

  // Find the RMT threshold.
  RMTThreshold * rmt = new RMTThreshold(ematrix, method, num_methods, th_method, thresholdStart,
      thresholdStep, chiSoughtValue, clustering, min_cluster_size, max_missing,
      max_modes);
  rmt->findThreshold();
  printf("Done.\n");
}
<|endoftext|>


<commit_before><commit_msg>BUG: Disable GVN by default.<commit_after><|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <gflags/gflags.h>

#include "xenia/app/emulator_window.h"
#include "xenia/base/debugging.h"
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/base/profiling.h"
#include "xenia/base/threading.h"
#include "xenia/debug/ui/debug_window.h"
#include "xenia/emulator.h"
#include "xenia/ui/file_picker.h"

// Available audio systems:
#include "xenia/apu/nop/nop_audio_system.h"
#if XE_PLATFORM_WIN32
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
#endif  // XE_PLATFORM_WIN32

// Available graphics systems:
#include "xenia/gpu/gl4/gl4_graphics_system.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"

// Available input drivers:
#include "xenia/hid/nop/nop_hid.h"
#if XE_PLATFORM_WIN32
#include "xenia/hid/winkey/winkey_hid.h"
#include "xenia/hid/xinput/xinput_hid.h"
#endif  // XE_PLATFORM_WIN32

DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]");
DEFINE_string(gpu, "any", "Graphics system. Use: [any, gl4, vulkan]");
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");

DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");

namespace xe {
namespace app {

std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
  if (FLAGS_apu.compare("nop") == 0) {
    return apu::nop::NopAudioSystem::Create(processor);
#if XE_PLATFORM_WIN32
  } else if (FLAGS_apu.compare("xaudio2") == 0) {
    return apu::xaudio2::XAudio2AudioSystem::Create(processor);
#endif  // XE_PLATFORM_WIN32
  } else {
    // Create best available.
    std::unique_ptr<apu::AudioSystem> best;

#if XE_PLATFORM_WIN32
    best = apu::xaudio2::XAudio2AudioSystem::Create(processor);
    if (best) {
      return best;
    }
#endif  // XE_PLATFORM_WIN32

    // Fallback to nop.
    return apu::nop::NopAudioSystem::Create(processor);
  }
}

std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
  if (FLAGS_gpu.compare("gl4") == 0) {
    return std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::gl4::GL4GraphicsSystem());
  } else if (FLAGS_gpu.compare("vulkan") == 0) {
    return std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::vulkan::VulkanGraphicsSystem());
  } else {
    // Create best available.
    std::unique_ptr<gpu::GraphicsSystem> best;

    best = std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::gl4::GL4GraphicsSystem());
    if (best) {
      return best;
    }

    // Nothing!
    return nullptr;
  }
}

std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
    ui::Window* window) {
  std::vector<std::unique_ptr<hid::InputDriver>> drivers;
  if (FLAGS_hid.compare("nop") == 0) {
    drivers.emplace_back(xe::hid::nop::Create(window));
#if XE_PLATFORM_WIN32
  } else if (FLAGS_hid.compare("winkey") == 0) {
    drivers.emplace_back(xe::hid::winkey::Create(window));
  } else if (FLAGS_hid.compare("xinput") == 0) {
    drivers.emplace_back(xe::hid::xinput::Create(window));
#endif  // XE_PLATFORM_WIN32
  } else {
#if XE_PLATFORM_WIN32
    auto xinput_driver = xe::hid::xinput::Create(window);
    if (xinput_driver) {
      drivers.emplace_back(std::move(xinput_driver));
    }
    auto winkey_driver = xe::hid::winkey::Create(window);
    if (winkey_driver) {
      drivers.emplace_back(std::move(winkey_driver));
    }
#endif  // XE_PLATFORM_WIN32
    if (drivers.empty()) {
      // Fallback to nop if none created.
      drivers.emplace_back(xe::hid::nop::Create(window));
    }
  }
  return drivers;
}

int xenia_main(const std::vector<std::wstring>& args) {
  Profiler::Initialize();
  Profiler::ThreadEnter("main");

  // Create the emulator but don't initialize so we can setup the window.
  auto emulator = std::make_unique<Emulator>(L"");

  // Main emulator display window.
  auto emulator_window = EmulatorWindow::Create(emulator.get());

  // Setup and initialize all subsystems. If we can't do something
  // (unsupported system, memory issues, etc) this will fail early.
  X_STATUS result =
      emulator->Setup(emulator_window->window(), CreateAudioSystem,
                      CreateGraphicsSystem, CreateInputDrivers);
  if (XFAILED(result)) {
    XELOGE("Failed to setup emulator: %.8X", result);
    return 1;
  }

  // Set a debug handler.
  // This will respond to debugging requests so we can open the debug UI.
  std::unique_ptr<xe::debug::ui::DebugWindow> debug_window;
  if (FLAGS_debug) {
    emulator->processor()->set_debug_listener_request_handler([&](
        xe::cpu::Processor* processor) {
      if (debug_window) {
        return debug_window.get();
      }
      emulator_window->loop()->PostSynchronous([&]() {
        debug_window = xe::debug::ui::DebugWindow::Create(
            emulator.get(), emulator_window->loop());
        debug_window->window()->on_closed.AddListener([&](xe::ui::UIEvent* e) {
          emulator->processor()->set_debug_listener(nullptr);
          emulator_window->loop()->Post([&]() { debug_window.reset(); });
        });
      });
      return debug_window.get();
    });
  }

  auto evt = xe::threading::Event::CreateAutoResetEvent(false);
  emulator->on_launch.AddListener([&]() {
    emulator_window->UpdateTitle();
    evt->Set();
  });

  bool exiting = false;
  emulator_window->loop()->on_quit.AddListener([&](ui::UIEvent* e) {
    exiting = true;
    evt->Set();
  });

  // Grab path from the flag or unnamed argument.
  std::wstring path;
  if (!FLAGS_target.empty() || args.size() >= 2) {
    if (!FLAGS_target.empty()) {
      // Passed as a named argument.
      // TODO(benvanik): find something better than gflags that supports
      // unicode.
      path = xe::to_wstring(FLAGS_target);
    } else {
      // Passed as an unnamed argument.
      path = args[1];
    }
  }

  if (!path.empty()) {
    // Normalize the path and make absolute.
    std::wstring abs_path = xe::to_absolute_path(path);
    result = emulator->LaunchPath(abs_path);
    if (XFAILED(result)) {
      XELOGE("Failed to launch target: %.8X", result);
      emulator.reset();
      emulator_window.reset();
      return 1;
    }
  }

  // Now, we're going to use the main thread to drive events related to
  // emulation.
  while (!exiting) {
    xe::threading::Wait(evt.get(), false);
    emulator->WaitUntilExit();
  }

  debug_window.reset();
  emulator.reset();
  emulator_window.reset();

  Profiler::Dump();
  Profiler::Shutdown();
  return 0;
}

}  // namespace app
}  // namespace xe

DEFINE_ENTRY_POINT(L"xenia", L"xenia some.xex", xe::app::xenia_main);
<commit_msg>Handle load requests made by the guest<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <gflags/gflags.h>

#include "xenia/app/emulator_window.h"
#include "xenia/base/debugging.h"
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/base/profiling.h"
#include "xenia/base/threading.h"
#include "xenia/debug/ui/debug_window.h"
#include "xenia/emulator.h"
#include "xenia/ui/file_picker.h"

// Available audio systems:
#include "xenia/apu/nop/nop_audio_system.h"
#if XE_PLATFORM_WIN32
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
#endif  // XE_PLATFORM_WIN32

// Available graphics systems:
#include "xenia/gpu/gl4/gl4_graphics_system.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"

// Available input drivers:
#include "xenia/hid/nop/nop_hid.h"
#if XE_PLATFORM_WIN32
#include "xenia/hid/winkey/winkey_hid.h"
#include "xenia/hid/xinput/xinput_hid.h"
#endif  // XE_PLATFORM_WIN32

DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]");
DEFINE_string(gpu, "any", "Graphics system. Use: [any, gl4, vulkan]");
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");

DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");

namespace xe {
namespace app {

std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
  if (FLAGS_apu.compare("nop") == 0) {
    return apu::nop::NopAudioSystem::Create(processor);
#if XE_PLATFORM_WIN32
  } else if (FLAGS_apu.compare("xaudio2") == 0) {
    return apu::xaudio2::XAudio2AudioSystem::Create(processor);
#endif  // XE_PLATFORM_WIN32
  } else {
    // Create best available.
    std::unique_ptr<apu::AudioSystem> best;

#if XE_PLATFORM_WIN32
    best = apu::xaudio2::XAudio2AudioSystem::Create(processor);
    if (best) {
      return best;
    }
#endif  // XE_PLATFORM_WIN32

    // Fallback to nop.
    return apu::nop::NopAudioSystem::Create(processor);
  }
}

std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
  if (FLAGS_gpu.compare("gl4") == 0) {
    return std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::gl4::GL4GraphicsSystem());
  } else if (FLAGS_gpu.compare("vulkan") == 0) {
    return std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::vulkan::VulkanGraphicsSystem());
  } else {
    // Create best available.
    std::unique_ptr<gpu::GraphicsSystem> best;

    best = std::unique_ptr<gpu::GraphicsSystem>(
        new xe::gpu::gl4::GL4GraphicsSystem());
    if (best) {
      return best;
    }

    // Nothing!
    return nullptr;
  }
}

std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
    ui::Window* window) {
  std::vector<std::unique_ptr<hid::InputDriver>> drivers;
  if (FLAGS_hid.compare("nop") == 0) {
    drivers.emplace_back(xe::hid::nop::Create(window));
#if XE_PLATFORM_WIN32
  } else if (FLAGS_hid.compare("winkey") == 0) {
    drivers.emplace_back(xe::hid::winkey::Create(window));
  } else if (FLAGS_hid.compare("xinput") == 0) {
    drivers.emplace_back(xe::hid::xinput::Create(window));
#endif  // XE_PLATFORM_WIN32
  } else {
#if XE_PLATFORM_WIN32
    auto xinput_driver = xe::hid::xinput::Create(window);
    if (xinput_driver) {
      drivers.emplace_back(std::move(xinput_driver));
    }
    auto winkey_driver = xe::hid::winkey::Create(window);
    if (winkey_driver) {
      drivers.emplace_back(std::move(winkey_driver));
    }
#endif  // XE_PLATFORM_WIN32
    if (drivers.empty()) {
      // Fallback to nop if none created.
      drivers.emplace_back(xe::hid::nop::Create(window));
    }
  }
  return drivers;
}

int xenia_main(const std::vector<std::wstring>& args) {
  Profiler::Initialize();
  Profiler::ThreadEnter("main");

  // Create the emulator but don't initialize so we can setup the window.
  auto emulator = std::make_unique<Emulator>(L"");

  // Main emulator display window.
  auto emulator_window = EmulatorWindow::Create(emulator.get());

  // Setup and initialize all subsystems. If we can't do something
  // (unsupported system, memory issues, etc) this will fail early.
  X_STATUS result =
      emulator->Setup(emulator_window->window(), CreateAudioSystem,
                      CreateGraphicsSystem, CreateInputDrivers);
  if (XFAILED(result)) {
    XELOGE("Failed to setup emulator: %.8X", result);
    return 1;
  }

  // Set a debug handler.
  // This will respond to debugging requests so we can open the debug UI.
  std::unique_ptr<xe::debug::ui::DebugWindow> debug_window;
  if (FLAGS_debug) {
    emulator->processor()->set_debug_listener_request_handler([&](
        xe::cpu::Processor* processor) {
      if (debug_window) {
        return debug_window.get();
      }
      emulator_window->loop()->PostSynchronous([&]() {
        debug_window = xe::debug::ui::DebugWindow::Create(
            emulator.get(), emulator_window->loop());
        debug_window->window()->on_closed.AddListener([&](xe::ui::UIEvent* e) {
          emulator->processor()->set_debug_listener(nullptr);
          emulator_window->loop()->Post([&]() { debug_window.reset(); });
        });
      });
      return debug_window.get();
    });
  }

  auto evt = xe::threading::Event::CreateAutoResetEvent(false);
  emulator->on_launch.AddListener([&]() {
    emulator_window->UpdateTitle();
    evt->Set();
  });

  bool exiting = false;
  emulator_window->loop()->on_quit.AddListener([&](ui::UIEvent* e) {
    exiting = true;
    evt->Set();
  });

  // Grab path from the flag or unnamed argument.
  std::wstring path;
  if (!FLAGS_target.empty() || args.size() >= 2) {
    if (!FLAGS_target.empty()) {
      // Passed as a named argument.
      // TODO(benvanik): find something better than gflags that supports
      // unicode.
      path = xe::to_wstring(FLAGS_target);
    } else {
      // Passed as an unnamed argument.
      path = args[1];
    }
  }

  if (!path.empty()) {
    // Normalize the path and make absolute.
    std::wstring abs_path = xe::to_absolute_path(path);
    result = emulator->LaunchPath(abs_path);
    if (XFAILED(result)) {
      XELOGE("Failed to launch target: %.8X", result);
      emulator.reset();
      emulator_window.reset();
      return 1;
    }
  }

  // Now, we're going to use the main thread to drive events related to
  // emulation.
  while (!exiting) {
    xe::threading::Wait(evt.get(), false);

    while (true) {
      emulator->WaitUntilExit();
      if (emulator->TitleRequested()) {
        emulator->LaunchNextTitle();
      } else {
        break;
      }
    }
  }

  debug_window.reset();
  emulator.reset();
  emulator_window.reset();

  Profiler::Dump();
  Profiler::Shutdown();
  return 0;
}

}  // namespace app
}  // namespace xe

DEFINE_ENTRY_POINT(L"xenia", L"xenia some.xex", xe::app::xenia_main);
<|endoftext|>


<commit_before>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/net/atom_network_delegate.h"

#include <utility>

#include "atom/common/native_mate_converters/net_converter.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "brightray/browser/net/devtools_network_transaction.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request.h"

using brightray::DevToolsNetworkTransaction;
using content::BrowserThread;

namespace atom {

const char* ResourceTypeToString(content::ResourceType type) {
  switch (type) {
    case content::RESOURCE_TYPE_MAIN_FRAME:
      return "mainFrame";
    case content::RESOURCE_TYPE_SUB_FRAME:
      return "subFrame";
    case content::RESOURCE_TYPE_STYLESHEET:
      return "stylesheet";
    case content::RESOURCE_TYPE_SCRIPT:
      return "script";
    case content::RESOURCE_TYPE_IMAGE:
      return "image";
    case content::RESOURCE_TYPE_OBJECT:
      return "object";
    case content::RESOURCE_TYPE_XHR:
      return "xhr";
    default:
      return "other";
  }
}

namespace {

using ResponseHeadersContainer =
    std::pair<scoped_refptr<net::HttpResponseHeaders>*, const std::string&>;

void RunSimpleListener(const AtomNetworkDelegate::SimpleListener& listener,
                       std::unique_ptr<base::DictionaryValue> details) {
  return listener.Run(*(details.get()));
}

void RunResponseListener(
    const AtomNetworkDelegate::ResponseListener& listener,
    std::unique_ptr<base::DictionaryValue> details,
    const AtomNetworkDelegate::ResponseCallback& callback) {
  return listener.Run(*(details.get()), callback);
}

// Test whether the URL of |request| matches |patterns|.
bool MatchesFilterCondition(net::URLRequest* request,
                            const URLPatterns& patterns) {
  if (patterns.empty())
    return true;

  for (const auto& pattern : patterns) {
    if (pattern.MatchesURL(request->url()))
      return true;
  }
  return false;
}

// Overloaded by multiple types to fill the |details| object.
void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) {
  FillRequestDetails(details, request);
  details->SetInteger("id", request->identifier());
  details->SetDouble("timestamp", base::Time::Now().ToDoubleT() * 1000);
  auto info = content::ResourceRequestInfo::ForRequest(request);
  details->SetString("resourceType",
                     info ? ResourceTypeToString(info->GetResourceType())
                          : "other");
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HttpRequestHeaders& headers) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  net::HttpRequestHeaders::Iterator it(headers);
  while (it.GetNext())
    dict->SetString(it.name(), it.value());
  details->Set("requestHeaders", std::move(dict));
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HttpResponseHeaders* headers) {
  if (!headers)
    return;

  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  size_t iter = 0;
  std::string key;
  std::string value;
  while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
    if (dict->HasKey(key)) {
      base::ListValue* values = nullptr;
      if (dict->GetList(key, &values))
        values->AppendString(value);
    } else {
      std::unique_ptr<base::ListValue> values(new base::ListValue);
      values->AppendString(value);
      dict->Set(key, std::move(values));
    }
  }
  details->Set("responseHeaders", std::move(dict));
  details->SetString("statusLine", headers->GetStatusLine());
  details->SetInteger("statusCode", headers->response_code());
}

void ToDictionary(base::DictionaryValue* details, const GURL& location) {
  details->SetString("redirectURL", location.spec());
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HostPortPair& host_port) {
  if (host_port.host().empty())
    details->SetString("ip", host_port.host());
}

void ToDictionary(base::DictionaryValue* details, bool from_cache) {
  details->SetBoolean("fromCache", from_cache);
}

void ToDictionary(base::DictionaryValue* details,
                  const net::URLRequestStatus& status) {
  details->SetString("error", net::ErrorToString(status.error()));
}

// Helper function to fill |details| with arbitrary |args|.
template<typename Arg>
void FillDetailsObject(base::DictionaryValue* details, Arg arg) {
  ToDictionary(details, arg);
}

template<typename Arg, typename... Args>
void FillDetailsObject(base::DictionaryValue* details, Arg arg, Args... args) {
  ToDictionary(details, arg);
  FillDetailsObject(details, args...);
}

// Fill the native types with the result from the response object.
void ReadFromResponseObject(const base::DictionaryValue& response,
                            GURL* new_location) {
  std::string url;
  if (response.GetString("redirectURL", &url))
    *new_location = GURL(url);
}

void ReadFromResponseObject(const base::DictionaryValue& response,
                            net::HttpRequestHeaders* headers) {
  const base::DictionaryValue* dict;
  if (response.GetDictionary("requestHeaders", &dict)) {
    headers->Clear();
    for (base::DictionaryValue::Iterator it(*dict);
         !it.IsAtEnd();
         it.Advance()) {
      std::string value;
      if (it.value().GetAsString(&value))
        headers->SetHeader(it.key(), value);
    }
  }
}

void ReadFromResponseObject(const base::DictionaryValue& response,
                            const ResponseHeadersContainer& container) {
  const base::DictionaryValue* dict;
  std::string status_line;
  if (!response.GetString("statusLine", &status_line))
    status_line = container.second;
  if (response.GetDictionary("responseHeaders", &dict)) {
    auto headers = container.first;
    *headers = new net::HttpResponseHeaders("");
    (*headers)->ReplaceStatusLine(status_line);
    for (base::DictionaryValue::Iterator it(*dict);
         !it.IsAtEnd();
         it.Advance()) {
      const base::ListValue* list;
      if (it.value().GetAsList(&list)) {
        (*headers)->RemoveHeader(it.key());
        for (size_t i = 0; i < list->GetSize(); ++i) {
          std::string value;
          if (list->GetString(i, &value))
            (*headers)->AddHeader(it.key() + " : " + value);
        }
      }
    }
  }
}

}  // namespace

AtomNetworkDelegate::AtomNetworkDelegate() {
}

AtomNetworkDelegate::~AtomNetworkDelegate() {
}

void AtomNetworkDelegate::SetSimpleListenerInIO(
    SimpleEvent type,
    const URLPatterns& patterns,
    const SimpleListener& callback) {
  if (callback.is_null())
    simple_listeners_.erase(type);
  else
    simple_listeners_[type] = { patterns, callback };
}

void AtomNetworkDelegate::SetResponseListenerInIO(
    ResponseEvent type,
    const URLPatterns& patterns,
    const ResponseListener& callback) {
  if (callback.is_null())
    response_listeners_.erase(type);
  else
    response_listeners_[type] = { patterns, callback };
}

void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
    const std::string& client_id) {
  base::AutoLock auto_lock(lock_);
  client_id_ = client_id;
}

int AtomNetworkDelegate::OnBeforeURLRequest(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    GURL* new_url) {
  if (!ContainsKey(response_listeners_, kOnBeforeRequest))
    return brightray::NetworkDelegate::OnBeforeURLRequest(
        request, callback, new_url);

  return HandleResponseEvent(kOnBeforeRequest, request, callback, new_url);
}

int AtomNetworkDelegate::OnBeforeSendHeaders(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    net::HttpRequestHeaders* headers) {
  std::string client_id;
  {
    base::AutoLock auto_lock(lock_);
    client_id = client_id_;
  }

  if (!client_id.empty())
    headers->SetHeader(
        DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId,
        client_id);
  if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders))
    return brightray::NetworkDelegate::OnBeforeSendHeaders(
        request, callback, headers);

  return HandleResponseEvent(
      kOnBeforeSendHeaders, request, callback, headers, *headers);
}

void AtomNetworkDelegate::OnSendHeaders(
    net::URLRequest* request,
    const net::HttpRequestHeaders& headers) {
  if (!ContainsKey(simple_listeners_, kOnSendHeaders)) {
    brightray::NetworkDelegate::OnSendHeaders(request, headers);
    return;
  }

  HandleSimpleEvent(kOnSendHeaders, request, headers);
}

int AtomNetworkDelegate::OnHeadersReceived(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    const net::HttpResponseHeaders* original,
    scoped_refptr<net::HttpResponseHeaders>* override,
    GURL* allowed) {
  if (!ContainsKey(response_listeners_, kOnHeadersReceived))
    return brightray::NetworkDelegate::OnHeadersReceived(
        request, callback, original, override, allowed);

  return HandleResponseEvent(
      kOnHeadersReceived, request, callback,
      std::make_pair(override, original->GetStatusLine()), original);
}

void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
                                           const GURL& new_location) {
  if (!ContainsKey(simple_listeners_, kOnBeforeRedirect)) {
    brightray::NetworkDelegate::OnBeforeRedirect(request, new_location);
    return;
  }

  HandleSimpleEvent(kOnBeforeRedirect, request, new_location,
                    request->response_headers(), request->GetSocketAddress(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
  if (!ContainsKey(simple_listeners_, kOnResponseStarted)) {
    brightray::NetworkDelegate::OnResponseStarted(request);
    return;
  }

  if (request->status().status() != net::URLRequestStatus::SUCCESS)
    return;

  HandleSimpleEvent(kOnResponseStarted, request, request->response_headers(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
  // OnCompleted may happen before other events.
  callbacks_.erase(request->identifier());

  if (request->status().status() == net::URLRequestStatus::FAILED ||
      request->status().status() == net::URLRequestStatus::CANCELED) {
    // Error event.
    OnErrorOccurred(request, started);
    return;
  } else if (request->response_headers() &&
             net::HttpResponseHeaders::IsRedirectResponseCode(
                 request->response_headers()->response_code())) {
    // Redirect event.
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  if (!ContainsKey(simple_listeners_, kOnCompleted)) {
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  HandleSimpleEvent(kOnCompleted, request, request->response_headers(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
  callbacks_.erase(request->identifier());
}

void AtomNetworkDelegate::OnErrorOccurred(
    net::URLRequest* request, bool started) {
  if (!ContainsKey(simple_listeners_, kOnErrorOccurred)) {
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  HandleSimpleEvent(kOnErrorOccurred, request, request->was_cached(),
                    request->status());
}

template<typename Out, typename... Args>
int AtomNetworkDelegate::HandleResponseEvent(
    ResponseEvent type,
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    Out out,
    Args... args) {
  const auto& info = response_listeners_[type];
  if (!MatchesFilterCondition(request, info.url_patterns))
    return net::OK;

  std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue);
  FillDetailsObject(details.get(), request, args...);

  // The |request| could be destroyed before the |callback| is called.
  callbacks_[request->identifier()] = callback;

  ResponseCallback response =
      base::Bind(&AtomNetworkDelegate::OnListenerResultInUI<Out>,
                 base::Unretained(this), request->identifier(), out);
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(RunResponseListener, info.listener, base::Passed(&details),
                 response));
  return net::ERR_IO_PENDING;
}

template<typename...Args>
void AtomNetworkDelegate::HandleSimpleEvent(
    SimpleEvent type, net::URLRequest* request, Args... args) {
  const auto& info = simple_listeners_[type];
  if (!MatchesFilterCondition(request, info.url_patterns))
    return;

  std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue);
  FillDetailsObject(details.get(), request, args...);

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(RunSimpleListener, info.listener, base::Passed(&details)));
}

template<typename T>
void AtomNetworkDelegate::OnListenerResultInIO(
    uint64_t id, T out, std::unique_ptr<base::DictionaryValue> response) {
  // The request has been destroyed.
  if (!ContainsKey(callbacks_, id))
    return;

  ReadFromResponseObject(*response.get(), out);

  bool cancel = false;
  response->GetBoolean("cancel", &cancel);
  callbacks_[id].Run(cancel ? net::ERR_BLOCKED_BY_CLIENT : net::OK);
}

template<typename T>
void AtomNetworkDelegate::OnListenerResultInUI(
    uint64_t id, T out, const base::DictionaryValue& response) {
  std::unique_ptr<base::DictionaryValue> copy = response.CreateDeepCopy();
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&AtomNetworkDelegate::OnListenerResultInIO<T>,
                 base::Unretained(this),  id, out, base::Passed(&copy)));
}

}  // namespace atom
<commit_msg>don't convert header names to nested values fixes #6855<commit_after>// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/net/atom_network_delegate.h"

#include <utility>

#include "atom/common/native_mate_converters/net_converter.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "brightray/browser/net/devtools_network_transaction.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request.h"

using brightray::DevToolsNetworkTransaction;
using content::BrowserThread;

namespace atom {

const char* ResourceTypeToString(content::ResourceType type) {
  switch (type) {
    case content::RESOURCE_TYPE_MAIN_FRAME:
      return "mainFrame";
    case content::RESOURCE_TYPE_SUB_FRAME:
      return "subFrame";
    case content::RESOURCE_TYPE_STYLESHEET:
      return "stylesheet";
    case content::RESOURCE_TYPE_SCRIPT:
      return "script";
    case content::RESOURCE_TYPE_IMAGE:
      return "image";
    case content::RESOURCE_TYPE_OBJECT:
      return "object";
    case content::RESOURCE_TYPE_XHR:
      return "xhr";
    default:
      return "other";
  }
}

namespace {

using ResponseHeadersContainer =
    std::pair<scoped_refptr<net::HttpResponseHeaders>*, const std::string&>;

void RunSimpleListener(const AtomNetworkDelegate::SimpleListener& listener,
                       std::unique_ptr<base::DictionaryValue> details) {
  return listener.Run(*(details.get()));
}

void RunResponseListener(
    const AtomNetworkDelegate::ResponseListener& listener,
    std::unique_ptr<base::DictionaryValue> details,
    const AtomNetworkDelegate::ResponseCallback& callback) {
  return listener.Run(*(details.get()), callback);
}

// Test whether the URL of |request| matches |patterns|.
bool MatchesFilterCondition(net::URLRequest* request,
                            const URLPatterns& patterns) {
  if (patterns.empty())
    return true;

  for (const auto& pattern : patterns) {
    if (pattern.MatchesURL(request->url()))
      return true;
  }
  return false;
}

// Overloaded by multiple types to fill the |details| object.
void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) {
  FillRequestDetails(details, request);
  details->SetInteger("id", request->identifier());
  details->SetDouble("timestamp", base::Time::Now().ToDoubleT() * 1000);
  auto info = content::ResourceRequestInfo::ForRequest(request);
  details->SetString("resourceType",
                     info ? ResourceTypeToString(info->GetResourceType())
                          : "other");
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HttpRequestHeaders& headers) {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  net::HttpRequestHeaders::Iterator it(headers);
  while (it.GetNext())
    dict->SetStringWithoutPathExpansion(it.name(), it.value());
  details->Set("requestHeaders", std::move(dict));
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HttpResponseHeaders* headers) {
  if (!headers)
    return;

  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  size_t iter = 0;
  std::string key;
  std::string value;
  while (headers->EnumerateHeaderLines(&iter, &key, &value)) {
    if (dict->HasKey(key)) {
      base::ListValue* values = nullptr;
      if (dict->GetList(key, &values))
        values->AppendString(value);
    } else {
      std::unique_ptr<base::ListValue> values(new base::ListValue);
      values->AppendString(value);
      dict->Set(key, std::move(values));
    }
  }
  details->Set("responseHeaders", std::move(dict));
  details->SetString("statusLine", headers->GetStatusLine());
  details->SetInteger("statusCode", headers->response_code());
}

void ToDictionary(base::DictionaryValue* details, const GURL& location) {
  details->SetString("redirectURL", location.spec());
}

void ToDictionary(base::DictionaryValue* details,
                  const net::HostPortPair& host_port) {
  if (host_port.host().empty())
    details->SetString("ip", host_port.host());
}

void ToDictionary(base::DictionaryValue* details, bool from_cache) {
  details->SetBoolean("fromCache", from_cache);
}

void ToDictionary(base::DictionaryValue* details,
                  const net::URLRequestStatus& status) {
  details->SetString("error", net::ErrorToString(status.error()));
}

// Helper function to fill |details| with arbitrary |args|.
template<typename Arg>
void FillDetailsObject(base::DictionaryValue* details, Arg arg) {
  ToDictionary(details, arg);
}

template<typename Arg, typename... Args>
void FillDetailsObject(base::DictionaryValue* details, Arg arg, Args... args) {
  ToDictionary(details, arg);
  FillDetailsObject(details, args...);
}

// Fill the native types with the result from the response object.
void ReadFromResponseObject(const base::DictionaryValue& response,
                            GURL* new_location) {
  std::string url;
  if (response.GetString("redirectURL", &url))
    *new_location = GURL(url);
}

void ReadFromResponseObject(const base::DictionaryValue& response,
                            net::HttpRequestHeaders* headers) {
  const base::DictionaryValue* dict;
  if (response.GetDictionary("requestHeaders", &dict)) {
    headers->Clear();
    for (base::DictionaryValue::Iterator it(*dict);
         !it.IsAtEnd();
         it.Advance()) {
      std::string value;
      if (it.value().GetAsString(&value))
        headers->SetHeader(it.key(), value);
    }
  }
}

void ReadFromResponseObject(const base::DictionaryValue& response,
                            const ResponseHeadersContainer& container) {
  const base::DictionaryValue* dict;
  std::string status_line;
  if (!response.GetString("statusLine", &status_line))
    status_line = container.second;
  if (response.GetDictionary("responseHeaders", &dict)) {
    auto headers = container.first;
    *headers = new net::HttpResponseHeaders("");
    (*headers)->ReplaceStatusLine(status_line);
    for (base::DictionaryValue::Iterator it(*dict);
         !it.IsAtEnd();
         it.Advance()) {
      const base::ListValue* list;
      if (it.value().GetAsList(&list)) {
        (*headers)->RemoveHeader(it.key());
        for (size_t i = 0; i < list->GetSize(); ++i) {
          std::string value;
          if (list->GetString(i, &value))
            (*headers)->AddHeader(it.key() + " : " + value);
        }
      }
    }
  }
}

}  // namespace

AtomNetworkDelegate::AtomNetworkDelegate() {
}

AtomNetworkDelegate::~AtomNetworkDelegate() {
}

void AtomNetworkDelegate::SetSimpleListenerInIO(
    SimpleEvent type,
    const URLPatterns& patterns,
    const SimpleListener& callback) {
  if (callback.is_null())
    simple_listeners_.erase(type);
  else
    simple_listeners_[type] = { patterns, callback };
}

void AtomNetworkDelegate::SetResponseListenerInIO(
    ResponseEvent type,
    const URLPatterns& patterns,
    const ResponseListener& callback) {
  if (callback.is_null())
    response_listeners_.erase(type);
  else
    response_listeners_[type] = { patterns, callback };
}

void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
    const std::string& client_id) {
  base::AutoLock auto_lock(lock_);
  client_id_ = client_id;
}

int AtomNetworkDelegate::OnBeforeURLRequest(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    GURL* new_url) {
  if (!ContainsKey(response_listeners_, kOnBeforeRequest))
    return brightray::NetworkDelegate::OnBeforeURLRequest(
        request, callback, new_url);

  return HandleResponseEvent(kOnBeforeRequest, request, callback, new_url);
}

int AtomNetworkDelegate::OnBeforeSendHeaders(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    net::HttpRequestHeaders* headers) {
  std::string client_id;
  {
    base::AutoLock auto_lock(lock_);
    client_id = client_id_;
  }

  if (!client_id.empty())
    headers->SetHeader(
        DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId,
        client_id);
  if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders))
    return brightray::NetworkDelegate::OnBeforeSendHeaders(
        request, callback, headers);

  return HandleResponseEvent(
      kOnBeforeSendHeaders, request, callback, headers, *headers);
}

void AtomNetworkDelegate::OnSendHeaders(
    net::URLRequest* request,
    const net::HttpRequestHeaders& headers) {
  if (!ContainsKey(simple_listeners_, kOnSendHeaders)) {
    brightray::NetworkDelegate::OnSendHeaders(request, headers);
    return;
  }

  HandleSimpleEvent(kOnSendHeaders, request, headers);
}

int AtomNetworkDelegate::OnHeadersReceived(
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    const net::HttpResponseHeaders* original,
    scoped_refptr<net::HttpResponseHeaders>* override,
    GURL* allowed) {
  if (!ContainsKey(response_listeners_, kOnHeadersReceived))
    return brightray::NetworkDelegate::OnHeadersReceived(
        request, callback, original, override, allowed);

  return HandleResponseEvent(
      kOnHeadersReceived, request, callback,
      std::make_pair(override, original->GetStatusLine()), original);
}

void AtomNetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
                                           const GURL& new_location) {
  if (!ContainsKey(simple_listeners_, kOnBeforeRedirect)) {
    brightray::NetworkDelegate::OnBeforeRedirect(request, new_location);
    return;
  }

  HandleSimpleEvent(kOnBeforeRedirect, request, new_location,
                    request->response_headers(), request->GetSocketAddress(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
  if (!ContainsKey(simple_listeners_, kOnResponseStarted)) {
    brightray::NetworkDelegate::OnResponseStarted(request);
    return;
  }

  if (request->status().status() != net::URLRequestStatus::SUCCESS)
    return;

  HandleSimpleEvent(kOnResponseStarted, request, request->response_headers(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
  // OnCompleted may happen before other events.
  callbacks_.erase(request->identifier());

  if (request->status().status() == net::URLRequestStatus::FAILED ||
      request->status().status() == net::URLRequestStatus::CANCELED) {
    // Error event.
    OnErrorOccurred(request, started);
    return;
  } else if (request->response_headers() &&
             net::HttpResponseHeaders::IsRedirectResponseCode(
                 request->response_headers()->response_code())) {
    // Redirect event.
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  if (!ContainsKey(simple_listeners_, kOnCompleted)) {
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  HandleSimpleEvent(kOnCompleted, request, request->response_headers(),
                    request->was_cached());
}

void AtomNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
  callbacks_.erase(request->identifier());
}

void AtomNetworkDelegate::OnErrorOccurred(
    net::URLRequest* request, bool started) {
  if (!ContainsKey(simple_listeners_, kOnErrorOccurred)) {
    brightray::NetworkDelegate::OnCompleted(request, started);
    return;
  }

  HandleSimpleEvent(kOnErrorOccurred, request, request->was_cached(),
                    request->status());
}

template<typename Out, typename... Args>
int AtomNetworkDelegate::HandleResponseEvent(
    ResponseEvent type,
    net::URLRequest* request,
    const net::CompletionCallback& callback,
    Out out,
    Args... args) {
  const auto& info = response_listeners_[type];
  if (!MatchesFilterCondition(request, info.url_patterns))
    return net::OK;

  std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue);
  FillDetailsObject(details.get(), request, args...);

  // The |request| could be destroyed before the |callback| is called.
  callbacks_[request->identifier()] = callback;

  ResponseCallback response =
      base::Bind(&AtomNetworkDelegate::OnListenerResultInUI<Out>,
                 base::Unretained(this), request->identifier(), out);
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(RunResponseListener, info.listener, base::Passed(&details),
                 response));
  return net::ERR_IO_PENDING;
}

template<typename...Args>
void AtomNetworkDelegate::HandleSimpleEvent(
    SimpleEvent type, net::URLRequest* request, Args... args) {
  const auto& info = simple_listeners_[type];
  if (!MatchesFilterCondition(request, info.url_patterns))
    return;

  std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue);
  FillDetailsObject(details.get(), request, args...);

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(RunSimpleListener, info.listener, base::Passed(&details)));
}

template<typename T>
void AtomNetworkDelegate::OnListenerResultInIO(
    uint64_t id, T out, std::unique_ptr<base::DictionaryValue> response) {
  // The request has been destroyed.
  if (!ContainsKey(callbacks_, id))
    return;

  ReadFromResponseObject(*response.get(), out);

  bool cancel = false;
  response->GetBoolean("cancel", &cancel);
  callbacks_[id].Run(cancel ? net::ERR_BLOCKED_BY_CLIENT : net::OK);
}

template<typename T>
void AtomNetworkDelegate::OnListenerResultInUI(
    uint64_t id, T out, const base::DictionaryValue& response) {
  std::unique_ptr<base::DictionaryValue> copy = response.CreateDeepCopy();
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&AtomNetworkDelegate::OnListenerResultInIO<T>,
                 base::Unretained(this),  id, out, base::Passed(&copy)));
}

}  // namespace atom
<|endoftext|>