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

#include "chrome/browser/extensions/extension_apitest.h"

// TODO(rafaelw,erikkay) disabled due to flakiness
// BUG=22668 (probably the same bug)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_Toolstrip) {
  ASSERT_TRUE(RunExtensionTest("toolstrip")) << message_;
}
<commit_msg>Enable ExtensionApiTest.Toolstrip<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

// TODO(rafaelw,erikkay) disabled due to flakiness
// BUG=22668 (probably the same bug)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Toolstrip) {
  ASSERT_TRUE(RunExtensionTest("toolstrip")) << message_;
}
<|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 "chrome/browser/spellchecker/spellcheck_message_filter.h"

#include <algorithm>
#include <functional>

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/browser/spellchecker/spelling_service_client.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/spellcheck_marker.h"
#include "chrome/common/spellcheck_messages.h"
#include "content/public/browser/render_process_host.h"
#include "net/url_request/url_fetcher.h"

using content::BrowserThread;

SpellCheckMessageFilter::SpellCheckMessageFilter(int render_process_id)
    : render_process_id_(render_process_id),
      client_(new SpellingServiceClient) {
}

void SpellCheckMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  // IPC messages arrive on IO thread, but spellcheck data lives on UI thread.
  // The message filter overrides the thread for these messages because they
  // access spellcheck data.
  if (message.type() == SpellCheckHostMsg_RequestDictionary::ID ||
      message.type() == SpellCheckHostMsg_NotifyChecked::ID ||
      message.type() == SpellCheckHostMsg_RespondDocumentMarkers::ID)
    *thread = BrowserThread::UI;
#if !defined(OS_MACOSX)
  if (message.type() == SpellCheckHostMsg_CallSpellingService::ID)
    *thread = BrowserThread::UI;
#endif
}

bool SpellCheckMessageFilter::OnMessageReceived(const IPC::Message& message,
                                                bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(SpellCheckMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_RequestDictionary,
                        OnSpellCheckerRequestDictionary)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_NotifyChecked,
                        OnNotifyChecked)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_RespondDocumentMarkers,
                        OnRespondDocumentMarkers)
#if !defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_CallSpellingService,
                        OnCallSpellingService)
#endif
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

SpellCheckMessageFilter::~SpellCheckMessageFilter() {}

void SpellCheckMessageFilter::OnSpellCheckerRequestDictionary() {
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (!host)
    return;  // Teardown.
  Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
  // The renderer has requested that we initialize its spellchecker. This should
  // generally only be called once per session, as after the first call, all
  // future renderers will be passed the initialization information on startup
  // (or when the dictionary changes in some way).
  SpellcheckService* spellcheck_service =
      SpellcheckServiceFactory::GetForProfile(profile);

  DCHECK(spellcheck_service);
  // The spellchecker initialization already started and finished; just send
  // it to the renderer.
  spellcheck_service->InitForRenderer(host);

  // TODO(rlp): Ensure that we do not initialize the hunspell dictionary more
  // than once if we get requests from different renderers.
}

void SpellCheckMessageFilter::OnNotifyChecked(const string16& word,
                                              bool misspelled) {
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (!host)
    return;  // Teardown.
  // Delegates to SpellCheckHost which tracks the stats of our spellchecker.
  Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
  SpellcheckService* spellcheck_service =
      SpellcheckServiceFactory::GetForProfile(profile);
  DCHECK(spellcheck_service);
  if (spellcheck_service->GetMetrics())
    spellcheck_service->GetMetrics()->RecordCheckedWordStats(word, misspelled);
}

void SpellCheckMessageFilter::OnRespondDocumentMarkers(
    const std::vector<uint32>& markers) {
  SpellcheckService* spellcheck =
      SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
  // Spellcheck service may not be available for a renderer process that is
  // shutting down.
  if (!spellcheck)
    return;
  spellcheck->GetFeedbackSender()->OnReceiveDocumentMarkers(
      render_process_id_, markers);
}

#if !defined(OS_MACOSX)
void SpellCheckMessageFilter::OnCallSpellingService(
    int route_id,
    int identifier,
    const string16& text,
    std::vector<SpellCheckMarker> markers) {
  DCHECK(!text.empty());
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  // Erase invalid markers (with offsets out of boundaries of text length).
  markers.erase(
      std::remove_if(
          markers.begin(),
          markers.end(),
          std::not1(SpellCheckMarker::IsValidPredicate(text.length()))),
      markers.end());
  CallSpellingService(text, route_id, identifier, markers);
}

void SpellCheckMessageFilter::OnTextCheckComplete(
    int route_id,
    int identifier,
    const std::vector<SpellCheckMarker>& markers,
    bool success,
    const string16& text,
    const std::vector<SpellCheckResult>& results) {
  SpellcheckService* spellcheck =
      SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
  DCHECK(spellcheck);
  std::vector<SpellCheckResult> results_copy = results;
  spellcheck->GetFeedbackSender()->OnSpellcheckResults(
      &results_copy, render_process_id_, text, markers);
  Send(new SpellCheckMsg_RespondSpellingService(
      route_id, identifier, success, text, results_copy));
}

// CallSpellingService always executes the callback OnTextCheckComplete.
// (Which, in turn, sends a SpellCheckMsg_RespondSpellingService)
void SpellCheckMessageFilter::CallSpellingService(
    const string16& text,
    int route_id,
    int identifier,
    const std::vector<SpellCheckMarker>& markers) {
  Profile* profile = NULL;
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (host)
    profile = Profile::FromBrowserContext(host->GetBrowserContext());

  client_->RequestTextCheck(
    profile,
    SpellingServiceClient::SPELLCHECK,
    text,
    base::Bind(&SpellCheckMessageFilter::OnTextCheckComplete,
               base::Unretained(this),
               route_id,
               identifier,
               markers));
}
#endif
<commit_msg>Add null checks for handlers in spellcheck_message_filters to avoid crashes when the renderer is shutting down.<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 "chrome/browser/spellchecker/spellcheck_message_filter.h"

#include <algorithm>
#include <functional>

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/browser/spellchecker/spelling_service_client.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/spellcheck_marker.h"
#include "chrome/common/spellcheck_messages.h"
#include "content/public/browser/render_process_host.h"
#include "net/url_request/url_fetcher.h"

using content::BrowserThread;

SpellCheckMessageFilter::SpellCheckMessageFilter(int render_process_id)
    : render_process_id_(render_process_id),
      client_(new SpellingServiceClient) {
}

void SpellCheckMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  // IPC messages arrive on IO thread, but spellcheck data lives on UI thread.
  // The message filter overrides the thread for these messages because they
  // access spellcheck data.
  if (message.type() == SpellCheckHostMsg_RequestDictionary::ID ||
      message.type() == SpellCheckHostMsg_NotifyChecked::ID ||
      message.type() == SpellCheckHostMsg_RespondDocumentMarkers::ID)
    *thread = BrowserThread::UI;
#if !defined(OS_MACOSX)
  if (message.type() == SpellCheckHostMsg_CallSpellingService::ID)
    *thread = BrowserThread::UI;
#endif
}

bool SpellCheckMessageFilter::OnMessageReceived(const IPC::Message& message,
                                                bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(SpellCheckMessageFilter, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_RequestDictionary,
                        OnSpellCheckerRequestDictionary)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_NotifyChecked,
                        OnNotifyChecked)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_RespondDocumentMarkers,
                        OnRespondDocumentMarkers)
#if !defined(OS_MACOSX)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_CallSpellingService,
                        OnCallSpellingService)
#endif
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

SpellCheckMessageFilter::~SpellCheckMessageFilter() {}

void SpellCheckMessageFilter::OnSpellCheckerRequestDictionary() {
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (!host)
    return;  // Teardown.
  Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
  // The renderer has requested that we initialize its spellchecker. This should
  // generally only be called once per session, as after the first call, all
  // future renderers will be passed the initialization information on startup
  // (or when the dictionary changes in some way).
  SpellcheckService* spellcheck_service =
      SpellcheckServiceFactory::GetForProfile(profile);

  DCHECK(spellcheck_service);
  // The spellchecker initialization already started and finished; just send
  // it to the renderer.
  spellcheck_service->InitForRenderer(host);

  // TODO(rlp): Ensure that we do not initialize the hunspell dictionary more
  // than once if we get requests from different renderers.
}

void SpellCheckMessageFilter::OnNotifyChecked(const string16& word,
                                              bool misspelled) {
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (!host)
    return;  // Teardown.
  // Delegates to SpellCheckHost which tracks the stats of our spellchecker.
  Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
  SpellcheckService* spellcheck_service =
      SpellcheckServiceFactory::GetForProfile(profile);
  if (!spellcheck_service)
    return;
  if (spellcheck_service->GetMetrics())
    spellcheck_service->GetMetrics()->RecordCheckedWordStats(word, misspelled);
}

void SpellCheckMessageFilter::OnRespondDocumentMarkers(
    const std::vector<uint32>& markers) {
  SpellcheckService* spellcheck =
      SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
  // Spellcheck service may not be available for a renderer process that is
  // shutting down.
  if (!spellcheck)
    return;
  spellcheck->GetFeedbackSender()->OnReceiveDocumentMarkers(
      render_process_id_, markers);
}

#if !defined(OS_MACOSX)
void SpellCheckMessageFilter::OnCallSpellingService(
    int route_id,
    int identifier,
    const string16& text,
    std::vector<SpellCheckMarker> markers) {
  DCHECK(!text.empty());
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  // Erase invalid markers (with offsets out of boundaries of text length).
  markers.erase(
      std::remove_if(
          markers.begin(),
          markers.end(),
          std::not1(SpellCheckMarker::IsValidPredicate(text.length()))),
      markers.end());
  CallSpellingService(text, route_id, identifier, markers);
}

void SpellCheckMessageFilter::OnTextCheckComplete(
    int route_id,
    int identifier,
    const std::vector<SpellCheckMarker>& markers,
    bool success,
    const string16& text,
    const std::vector<SpellCheckResult>& results) {
  SpellcheckService* spellcheck =
      SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
  if (!spellcheck)
    return;
  std::vector<SpellCheckResult> results_copy = results;
  spellcheck->GetFeedbackSender()->OnSpellcheckResults(
      &results_copy, render_process_id_, text, markers);
  Send(new SpellCheckMsg_RespondSpellingService(
      route_id, identifier, success, text, results_copy));
}

// CallSpellingService always executes the callback OnTextCheckComplete.
// (Which, in turn, sends a SpellCheckMsg_RespondSpellingService)
void SpellCheckMessageFilter::CallSpellingService(
    const string16& text,
    int route_id,
    int identifier,
    const std::vector<SpellCheckMarker>& markers) {
  Profile* profile = NULL;
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (host)
    profile = Profile::FromBrowserContext(host->GetBrowserContext());

  client_->RequestTextCheck(
    profile,
    SpellingServiceClient::SPELLCHECK,
    text,
    base::Bind(&SpellCheckMessageFilter::OnTextCheckComplete,
               base::Unretained(this),
               route_id,
               identifier,
               markers));
}
#endif
<|endoftext|>


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

#include "chrome/browser/translate/translate_infobars_delegates.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

// TranslateInfoBarDelegate: InfoBarDelegate overrides: ------------------------

SkBitmap* TranslateInfoBarDelegate::GetIcon() const {
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_INFOBAR_TRANSLATE);
}

bool TranslateInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
  TranslateInfoBarDelegate* translate_delegate =
      delegate->AsTranslateInfoBarDelegate();
  // There can be only 1 translate infobar at any one time.
  return (!!translate_delegate);
}

void TranslateInfoBarDelegate::InfoBarClosed() {
  delete this;
}

// TranslateInfoBarDelegate: public: -------------------------------------------

void TranslateInfoBarDelegate::ModifyOriginalLanguage(
    const std::string& original_language) {
  original_language_ = original_language;
  // TODO(kuan): Send stats to Google Translate that original language has been
  // modified.
}

void TranslateInfoBarDelegate::ModifyTargetLanguage(
    const std::string& target_language) {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::GetAvailableOriginalLanguages(
    std::vector<std::string>* languages) {
  // TODO(kuan): Call backend when it's ready; hardcode a list for now.
  languages->push_back("Arabic");
  languages->push_back("Bengali");
  languages->push_back("Bulgarian");
  languages->push_back("Chinese (Simplified Han)");
  languages->push_back("Chinese (Traditional Han)");
  languages->push_back("Croatian");
  languages->push_back("Czech");
  languages->push_back("Danish");
  languages->push_back("Dutch");
  languages->push_back("English");
  languages->push_back("Estonian");
  languages->push_back("Filipino");
  languages->push_back("Finnish");
  languages->push_back("French");
  languages->push_back("German");
  languages->push_back("Greek");
  languages->push_back("Hebrew");
  languages->push_back("Hindi");
  languages->push_back("Hungarian");
  languages->push_back("Indonesian");
  languages->push_back("Italian");
  languages->push_back("Japanese");
  languages->push_back("Korean");
  languages->push_back("Latvian");
  languages->push_back("Lithuanian");
  languages->push_back("Norwegian");
  languages->push_back("Polish");
  languages->push_back("Portuguese");
  languages->push_back("Romanian");
  languages->push_back("Russian");
  languages->push_back("Serbian");
  languages->push_back("Slovak");
  languages->push_back("Slovenian");
  languages->push_back("Spanish");
  languages->push_back("Swedish");
  languages->push_back("Tamil");
  languages->push_back("Thai");
  languages->push_back("Turkish");
  languages->push_back("Ukrainian");
  languages->push_back("Vietnamese");
}

void TranslateInfoBarDelegate::GetAvailableTargetLanguages(
    std::vector<std::string>* languages) {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::Translate() {
  // TODO(kuan): Call actual Translate method.
/*
  Translate(WideToUTF8(original_language()), WideToUTF8(target_language()));
*/
}

bool TranslateInfoBarDelegate::IsLanguageBlacklisted() {
  NOTREACHED() << "Subclass should override";
  return false;
}

bool TranslateInfoBarDelegate::IsSiteBlacklisted() {
  NOTREACHED() << "Subclass should override";
  return false;
}

bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() {
  NOTREACHED() << "Subclass should override";
  return false;
}

void TranslateInfoBarDelegate::ToggleLanguageBlacklist() {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::ToggleSiteBlacklist() {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::ToggleAlwaysTranslate() {
  NOTREACHED() << "Subclass should override";
}

// TranslateInfoBarDelegate: protected: ----------------------------------------

TranslateInfoBarDelegate::TranslateInfoBarDelegate(TabContents* tab_contents,
    PrefService* user_prefs, const std::string& original_language,
    const std::string& target_language)
    : InfoBarDelegate(tab_contents),
      tab_contents_(tab_contents),
      original_language_(original_language),
      target_language_(target_language),
      prefs_(user_prefs) {
}

// BeforeTranslateInfoBarDelegate: public: -------------------------------------

BeforeTranslateInfoBarDelegate::BeforeTranslateInfoBarDelegate(
    TabContents* tab_contents, PrefService* user_prefs, const GURL& url,
    const std::string& original_language, const std::string& target_language)
    : TranslateInfoBarDelegate(tab_contents, user_prefs, original_language,
          target_language),
      site_(url.HostNoBrackets()),
      never_translate_language_(false),
      never_translate_site_(false) {
}

bool BeforeTranslateInfoBarDelegate::IsLanguageBlacklisted() {
  never_translate_language_ =
    prefs_.IsLanguageBlacklisted(original_language());
  return never_translate_language_;
}

void BeforeTranslateInfoBarDelegate::ToggleLanguageBlacklist() {
  never_translate_language_ = !never_translate_language_;
  if (never_translate_language_)
    prefs_.BlacklistLanguage(original_language());
  else
    prefs_.RemoveLanguageFromBlacklist(original_language());
}

bool BeforeTranslateInfoBarDelegate::IsSiteBlacklisted() {
  never_translate_site_ = prefs_.IsSiteBlacklisted(site_);
  return never_translate_site_;
}

void BeforeTranslateInfoBarDelegate::ToggleSiteBlacklist() {
  never_translate_site_ = !never_translate_site_;
  if (never_translate_site_)
    prefs_.BlacklistSite(site_);
  else
    prefs_.RemoveSiteFromBlacklist(site_);
}

// AfterTranslateInfoBarDelegate: public: --------------------------------------

AfterTranslateInfoBarDelegate::AfterTranslateInfoBarDelegate(
    TabContents* tab_contents, PrefService* user_prefs,
    const std::string& original_language, const std::string& target_language)
    : TranslateInfoBarDelegate(tab_contents, user_prefs, original_language,
          target_language),
      always_translate_(false) {
}

void AfterTranslateInfoBarDelegate::GetAvailableTargetLanguages(
    std::vector<std::string>* languages) {
  // TODO(kuan): Call backend when it's ready; hardcode a list for now.
  GetAvailableOriginalLanguages(languages);
}

void AfterTranslateInfoBarDelegate::ModifyTargetLanguage(
    const std::string& target_language) {
  target_language_ = target_language;
}

bool AfterTranslateInfoBarDelegate::ShouldAlwaysTranslate() {
  always_translate_ = prefs_.IsLanguagePairWhitelisted(original_language(),
      target_language());
  return always_translate_;
}

void AfterTranslateInfoBarDelegate::ToggleAlwaysTranslate() {
  always_translate_ = !always_translate_;
  if (always_translate_)
    prefs_.WhitelistLanguagePair(original_language(), target_language());
  else
    prefs_.RemoveLanguagePairFromWhitelist(original_language(),
        target_language());
}
<commit_msg>use stubs for yet-to-be-implemented non-windows translate infobars<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/translate/translate_infobars_delegates.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

// TranslateInfoBarDelegate: InfoBarDelegate overrides: ------------------------

SkBitmap* TranslateInfoBarDelegate::GetIcon() const {
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_INFOBAR_TRANSLATE);
}

bool TranslateInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
  TranslateInfoBarDelegate* translate_delegate =
      delegate->AsTranslateInfoBarDelegate();
  // There can be only 1 translate infobar at any one time.
  return (!!translate_delegate);
}

void TranslateInfoBarDelegate::InfoBarClosed() {
  delete this;
}

// TranslateInfoBarDelegate: public: -------------------------------------------

void TranslateInfoBarDelegate::ModifyOriginalLanguage(
    const std::string& original_language) {
  original_language_ = original_language;
  // TODO(kuan): Send stats to Google Translate that original language has been
  // modified.
}

void TranslateInfoBarDelegate::ModifyTargetLanguage(
    const std::string& target_language) {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::GetAvailableOriginalLanguages(
    std::vector<std::string>* languages) {
  // TODO(kuan): Call backend when it's ready; hardcode a list for now.
  languages->push_back("Arabic");
  languages->push_back("Bengali");
  languages->push_back("Bulgarian");
  languages->push_back("Chinese (Simplified Han)");
  languages->push_back("Chinese (Traditional Han)");
  languages->push_back("Croatian");
  languages->push_back("Czech");
  languages->push_back("Danish");
  languages->push_back("Dutch");
  languages->push_back("English");
  languages->push_back("Estonian");
  languages->push_back("Filipino");
  languages->push_back("Finnish");
  languages->push_back("French");
  languages->push_back("German");
  languages->push_back("Greek");
  languages->push_back("Hebrew");
  languages->push_back("Hindi");
  languages->push_back("Hungarian");
  languages->push_back("Indonesian");
  languages->push_back("Italian");
  languages->push_back("Japanese");
  languages->push_back("Korean");
  languages->push_back("Latvian");
  languages->push_back("Lithuanian");
  languages->push_back("Norwegian");
  languages->push_back("Polish");
  languages->push_back("Portuguese");
  languages->push_back("Romanian");
  languages->push_back("Russian");
  languages->push_back("Serbian");
  languages->push_back("Slovak");
  languages->push_back("Slovenian");
  languages->push_back("Spanish");
  languages->push_back("Swedish");
  languages->push_back("Tamil");
  languages->push_back("Thai");
  languages->push_back("Turkish");
  languages->push_back("Ukrainian");
  languages->push_back("Vietnamese");
}

void TranslateInfoBarDelegate::GetAvailableTargetLanguages(
    std::vector<std::string>* languages) {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::Translate() {
  // TODO(kuan): Call actual Translate method.
/*
  Translate(WideToUTF8(original_language()), WideToUTF8(target_language()));
*/
}

bool TranslateInfoBarDelegate::IsLanguageBlacklisted() {
  NOTREACHED() << "Subclass should override";
  return false;
}

bool TranslateInfoBarDelegate::IsSiteBlacklisted() {
  NOTREACHED() << "Subclass should override";
  return false;
}

bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() {
  NOTREACHED() << "Subclass should override";
  return false;
}

void TranslateInfoBarDelegate::ToggleLanguageBlacklist() {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::ToggleSiteBlacklist() {
  NOTREACHED() << "Subclass should override";
}

void TranslateInfoBarDelegate::ToggleAlwaysTranslate() {
  NOTREACHED() << "Subclass should override";
}

// TranslateInfoBarDelegate: protected: ----------------------------------------

TranslateInfoBarDelegate::TranslateInfoBarDelegate(TabContents* tab_contents,
    PrefService* user_prefs, const std::string& original_language,
    const std::string& target_language)
    : InfoBarDelegate(tab_contents),
      tab_contents_(tab_contents),
      original_language_(original_language),
      target_language_(target_language),
      prefs_(user_prefs) {
}

// BeforeTranslateInfoBarDelegate: public: -------------------------------------

BeforeTranslateInfoBarDelegate::BeforeTranslateInfoBarDelegate(
    TabContents* tab_contents, PrefService* user_prefs, const GURL& url,
    const std::string& original_language, const std::string& target_language)
    : TranslateInfoBarDelegate(tab_contents, user_prefs, original_language,
          target_language),
      site_(url.HostNoBrackets()),
      never_translate_language_(false),
      never_translate_site_(false) {
}

bool BeforeTranslateInfoBarDelegate::IsLanguageBlacklisted() {
  never_translate_language_ =
    prefs_.IsLanguageBlacklisted(original_language());
  return never_translate_language_;
}

void BeforeTranslateInfoBarDelegate::ToggleLanguageBlacklist() {
  never_translate_language_ = !never_translate_language_;
  if (never_translate_language_)
    prefs_.BlacklistLanguage(original_language());
  else
    prefs_.RemoveLanguageFromBlacklist(original_language());
}

bool BeforeTranslateInfoBarDelegate::IsSiteBlacklisted() {
  never_translate_site_ = prefs_.IsSiteBlacklisted(site_);
  return never_translate_site_;
}

void BeforeTranslateInfoBarDelegate::ToggleSiteBlacklist() {
  never_translate_site_ = !never_translate_site_;
  if (never_translate_site_)
    prefs_.BlacklistSite(site_);
  else
    prefs_.RemoveSiteFromBlacklist(site_);
}

#if !defined(TOOLKIT_VIEWS)
InfoBar* BeforeTranslateInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif  // !TOOLKIT_VIEWS

// AfterTranslateInfoBarDelegate: public: --------------------------------------

AfterTranslateInfoBarDelegate::AfterTranslateInfoBarDelegate(
    TabContents* tab_contents, PrefService* user_prefs,
    const std::string& original_language, const std::string& target_language)
    : TranslateInfoBarDelegate(tab_contents, user_prefs, original_language,
          target_language),
      always_translate_(false) {
}

void AfterTranslateInfoBarDelegate::GetAvailableTargetLanguages(
    std::vector<std::string>* languages) {
  // TODO(kuan): Call backend when it's ready; hardcode a list for now.
  GetAvailableOriginalLanguages(languages);
}

void AfterTranslateInfoBarDelegate::ModifyTargetLanguage(
    const std::string& target_language) {
  target_language_ = target_language;
}

bool AfterTranslateInfoBarDelegate::ShouldAlwaysTranslate() {
  always_translate_ = prefs_.IsLanguagePairWhitelisted(original_language(),
      target_language());
  return always_translate_;
}

void AfterTranslateInfoBarDelegate::ToggleAlwaysTranslate() {
  always_translate_ = !always_translate_;
  if (always_translate_)
    prefs_.WhitelistLanguagePair(original_language(), target_language());
  else
    prefs_.RemoveLanguagePairFromWhitelist(original_language(),
        target_language());
}

#if !defined(TOOLKIT_VIEWS)
InfoBar* AfterTranslateInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif  // !TOOLKIT_VIEWS
<|endoftext|>


<commit_before>#include "mocca/net/rpc/Dispatcher.h"

#include "mocca/base/ContainerTools.h"
#include "mocca/base/Error.h"
#include "mocca/base/Memory.h"
#include "mocca/log/LogManager.h"
#include "mocca/net/ConnectionFactorySelector.h"
#include "mocca/net/rpc/JsonKeys.h"

using namespace mocca::net;

Dispatcher::Dispatcher(const std::vector<mocca::net::Endpoint>& endpoints) {
    std::vector<std::unique_ptr<mocca::net::IMessageConnectionAcceptor>> acceptors;
    for (const auto& ep : endpoints) {
        acceptors.push_back(mocca::net::ConnectionFactorySelector::bind(ep));
    }
    aggregator_ = mocca::make_unique<mocca::net::ConnectionAggregator>(std::move(acceptors));
    registerReflection();
}

Dispatcher::~Dispatcher() {
    join();
}

void Dispatcher::sendReply(const JsonCpp::Value root, const std::vector<mocca::net::MessagePart>& binary,
                           std::shared_ptr<const mocca::net::ConnectionID> connectionID) {
    JsonCpp::FastWriter writer;
    std::string jsonStr = writer.write(root);
    mocca::net::Message message;
    message.push_back(mocca::net::createMessagePart(jsonStr));
    message.insert(end(message), begin(binary), end(binary));
    mocca::net::MessageEnvelope envelope(std::move(message), connectionID);
    aggregator_->send(std::move(envelope));
}

void Dispatcher::run() {
    const auto timeout(std::chrono::milliseconds(100));

    while (!isInterrupted()) {
        auto envelopeNullable = aggregator_->receive(timeout);
        if (!envelopeNullable.isNull()) {
            auto envelope = envelopeNullable.release();
            auto message = std::move(envelope.message);
            try {
                JsonCpp::Value root = parseMessage(message);

                // sanity checks on request
                if (!root.isMember(mocca::net::methodKey())) {
                    throw Error("Malformatted request: Required field 'method' or 'params' is missing", __FILE__, __LINE__);
                }

                // find matching method for request
                std::string methodName = root[mocca::net::methodKey()].asString();
                auto findIt = mocca::findMemberEqual(begin(methods_), end(methods_), &Method::name, methodName);
                if (findIt == end(methods_)) {
                    throw Error("Unknown method '" + methodName + "'", __FILE__, __LINE__);
                }

                // call method
                const auto& method = *findIt;
                auto result = method(root[mocca::net::paramsKey()]);
                const auto& json = result.first;
                const auto& binary = result.second;

                // send reply if method returned something
                if (!json.empty()) {
                    JsonCpp::Value reply;
                    reply[mocca::net::resultKey()] = json;
                    reply[mocca::net::statusKey()] = mocca::net::successStatus();
                    sendReply(reply, binary, envelope.connectionID);
                }
            } catch (const std::runtime_error& err) {
                LERROR(err.what());
                // in case of an error, send error message back to client
                JsonCpp::Value reply;
                reply[mocca::net::statusKey()] = mocca::net::errorStatus();
                reply[mocca::net::errorKey()] = err.what();
                sendReply(reply, {}, envelope.connectionID);
            }
        }
    }
}

JsonCpp::Value Dispatcher::parseMessage(const mocca::net::Message& message) {
    JsonCpp::Reader reader;
    JsonCpp::Value root;
    std::string json(reinterpret_cast<const char*>(message[0]->data()), message[0]->size());
    LDEBUG("Request: " << json);
    if (!reader.parse(json, root)) {
        throw Error("JSON parse error: " + reader.getFormattedErrorMessages(), __FILE__, __LINE__);
    }
    return root;
}

void Dispatcher::registerMethod(Method method) {
    methods_.push_back(std::move(method));
}

void Dispatcher::registerReflection() {
    MethodDescription description(mocca::net::describe(), {});
    Method method(description, [this](const JsonCpp::Value&) {
        JsonCpp::Value result;
        int count = 0;
        for (const auto& m : methods_) {
            result[count++] = MethodDescription::toJson(m.description());
        }
        return std::make_pair(result, std::vector<mocca::net::MessagePart>());
    });
    registerMethod(std::move(method));
}<commit_msg>return rpc reply even if it's empty<commit_after>#include "mocca/net/rpc/Dispatcher.h"

#include "mocca/base/ContainerTools.h"
#include "mocca/base/Error.h"
#include "mocca/base/Memory.h"
#include "mocca/log/LogManager.h"
#include "mocca/net/ConnectionFactorySelector.h"
#include "mocca/net/rpc/JsonKeys.h"

using namespace mocca::net;

Dispatcher::Dispatcher(const std::vector<mocca::net::Endpoint>& endpoints) {
    std::vector<std::unique_ptr<mocca::net::IMessageConnectionAcceptor>> acceptors;
    for (const auto& ep : endpoints) {
        acceptors.push_back(mocca::net::ConnectionFactorySelector::bind(ep));
    }
    aggregator_ = mocca::make_unique<mocca::net::ConnectionAggregator>(std::move(acceptors));
    registerReflection();
}

Dispatcher::~Dispatcher() {
    join();
}

void Dispatcher::sendReply(const JsonCpp::Value root, const std::vector<mocca::net::MessagePart>& binary,
                           std::shared_ptr<const mocca::net::ConnectionID> connectionID) {
    JsonCpp::FastWriter writer;
    std::string jsonStr = writer.write(root);
    mocca::net::Message message;
    message.push_back(mocca::net::createMessagePart(jsonStr));
    message.insert(end(message), begin(binary), end(binary));
    mocca::net::MessageEnvelope envelope(std::move(message), connectionID);
    aggregator_->send(std::move(envelope));
}

void Dispatcher::run() {
    const auto timeout(std::chrono::milliseconds(100));

    while (!isInterrupted()) {
        auto envelopeNullable = aggregator_->receive(timeout);
        if (!envelopeNullable.isNull()) {
            auto envelope = envelopeNullable.release();
            auto message = std::move(envelope.message);
            try {
                JsonCpp::Value root = parseMessage(message);

                // sanity checks on request
                if (!root.isMember(mocca::net::methodKey())) {
                    throw Error("Malformatted request: Required field 'method' or 'params' is missing", __FILE__, __LINE__);
                }

                // find matching method for request
                std::string methodName = root[mocca::net::methodKey()].asString();
                auto findIt = mocca::findMemberEqual(begin(methods_), end(methods_), &Method::name, methodName);
                if (findIt == end(methods_)) {
                    throw Error("Unknown method '" + methodName + "'", __FILE__, __LINE__);
                }

                // call method
                const auto& method = *findIt;
                auto result = method(root[mocca::net::paramsKey()]);
                const auto& json = result.first;
                const auto& binary = result.second;

                // send reply if method returned something
                JsonCpp::Value reply;
                reply[mocca::net::resultKey()] = json;
                reply[mocca::net::statusKey()] = mocca::net::successStatus();
                sendReply(reply, binary, envelope.connectionID);
            } catch (const std::runtime_error& err) {
                LERROR(err.what());
                // in case of an error, send error message back to client
                JsonCpp::Value reply;
                reply[mocca::net::statusKey()] = mocca::net::errorStatus();
                reply[mocca::net::errorKey()] = err.what();
                sendReply(reply, {}, envelope.connectionID);
            }
        }
    }
}

JsonCpp::Value Dispatcher::parseMessage(const mocca::net::Message& message) {
    JsonCpp::Reader reader;
    JsonCpp::Value root;
    std::string json(reinterpret_cast<const char*>(message[0]->data()), message[0]->size());
    LDEBUG("Request: " << json);
    if (!reader.parse(json, root)) {
        throw Error("JSON parse error: " + reader.getFormattedErrorMessages(), __FILE__, __LINE__);
    }
    return root;
}

void Dispatcher::registerMethod(Method method) {
    methods_.push_back(std::move(method));
}

void Dispatcher::registerReflection() {
    MethodDescription description(mocca::net::describe(), {});
    Method method(description, [this](const JsonCpp::Value&) {
        JsonCpp::Value result;
        int count = 0;
        for (const auto& m : methods_) {
            result[count++] = MethodDescription::toJson(m.description());
        }
        return std::make_pair(result, std::vector<mocca::net::MessagePart>());
    });
    registerMethod(std::move(method));
}<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2014                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENCE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_TYPED_ACTOR_HPP
#define CAF_TYPED_ACTOR_HPP

#include "caf/intrusive_ptr.hpp"

#include "caf/actor_addr.hpp"
#include "caf/actor_cast.hpp"
#include "caf/replies_to.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/typed_behavior.hpp"

namespace caf {

class actor_addr;
class local_actor;

struct invalid_actor_addr_t;

template <class... Rs>
class typed_event_based_actor;

/**
 * Identifies a strongly typed actor.
 * @tparam Rs Interface as `replies_to<`...>::with<...> parameter pack.
 */
template <class... Rs>
class typed_actor
  : detail::comparable<typed_actor<Rs...>>,
    detail::comparable<typed_actor<Rs...>, actor_addr>,
    detail::comparable<typed_actor<Rs...>, invalid_actor_addr_t> {

  friend class local_actor;

  // friend with all possible instantiations
  template <class...>
  friend class typed_actor;

  // allow conversion via actor_cast
  template <class T, typename U>
  friend T actor_cast(const U&);

 public:

  template <class... Es>
  struct extend {
    using type = typed_actor<Rs..., Es...>;
  };

  /**
   * Identifies the behavior type actors of this kind use
   * for their behavior stack.
   */
  using behavior_type = typed_behavior<Rs...>;

  /**
   * Identifies pointers to instances of this kind of actor.
   */
  using pointer = typed_event_based_actor<Rs...>*;

  /**
   * Identifies the base class for this kind of actor.
   */
  using base = typed_event_based_actor<Rs...>;

  typed_actor() = default;
  typed_actor(typed_actor&&) = default;
  typed_actor(const typed_actor&) = default;
  typed_actor& operator=(typed_actor&&) = default;
  typed_actor& operator=(const typed_actor&) = default;

  template <class... OtherRs>
  typed_actor(const typed_actor<OtherRs...>& other) {
    set(std::move(other));
  }

  template <class... OtherRs>
  typed_actor& operator=(const typed_actor<OtherRs...>& other) {
    set(std::move(other));
    return *this;
  }

  template <class Impl>
  typed_actor(intrusive_ptr<Impl> other) {
    set(other);
  }

  abstract_actor* operator->() const {
    return m_ptr.get();
  }

  abstract_actor& operator*() const {
    return *m_ptr.get();
  }

  /**
   * Queries the address of the stored actor.
   */
  actor_addr address() const {
    return m_ptr ? m_ptr->address() : actor_addr{};
  }

  inline intptr_t compare(const actor_addr& rhs) const {
    return address().compare(rhs);
  }

  inline intptr_t compare(const typed_actor& other) const {
    return compare(other.address());
  }

  inline intptr_t compare(const invalid_actor_addr_t&) const {
    return m_ptr ? 1 : 0;
  }

  static std::set<std::string> message_types() {
    return {detail::to_uniform_name<Rs>()...};
  }

  explicit operator bool() const { return static_cast<bool>(m_ptr); }

  inline bool operator!() const { return !m_ptr; }

 private:

  inline abstract_actor* get() const { return m_ptr.get(); }

  typed_actor(abstract_actor* ptr) : m_ptr(ptr) {}

  template <class ListA, class ListB>
  inline void check_signatures() {
    static_assert(detail::tl_is_strict_subset<ListA, ListB>::value,
            "'this' must be a strict subset of 'other'");
  }

  template <class... OtherRs>
  inline void set(const typed_actor<OtherRs...>& other) {
    check_signatures<detail::type_list<Rs...>, detail::type_list<OtherRs...>>();
    m_ptr = other.m_ptr;
  }

  template <class Impl>
  inline void set(intrusive_ptr<Impl>& other) {
    check_signatures<detail::type_list<Rs...>, typename Impl::signatures>();
    m_ptr = std::move(other);
  }

  abstract_actor_ptr m_ptr;

};

} // namespace caf

#endif // CAF_TYPED_ACTOR_HPP
<commit_msg>Fix doxygen documentation<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright (C) 2011 - 2014                                                  *
 * Dominik Charousset <dominik.charousset (at) haw-hamburg.de>                *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENCE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#ifndef CAF_TYPED_ACTOR_HPP
#define CAF_TYPED_ACTOR_HPP

#include "caf/intrusive_ptr.hpp"

#include "caf/actor_addr.hpp"
#include "caf/actor_cast.hpp"
#include "caf/replies_to.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/typed_behavior.hpp"

namespace caf {

class actor_addr;
class local_actor;

struct invalid_actor_addr_t;

template <class... Rs>
class typed_event_based_actor;

/**
 * Identifies a strongly typed actor.
 * @tparam Rs Interface as `replies_to<...>::with<...>` parameter pack.
 */
template <class... Rs>
class typed_actor
  : detail::comparable<typed_actor<Rs...>>,
    detail::comparable<typed_actor<Rs...>, actor_addr>,
    detail::comparable<typed_actor<Rs...>, invalid_actor_addr_t> {

  friend class local_actor;

  // friend with all possible instantiations
  template <class...>
  friend class typed_actor;

  // allow conversion via actor_cast
  template <class T, typename U>
  friend T actor_cast(const U&);

 public:

  template <class... Es>
  struct extend {
    using type = typed_actor<Rs..., Es...>;
  };

  /**
   * Identifies the behavior type actors of this kind use
   * for their behavior stack.
   */
  using behavior_type = typed_behavior<Rs...>;

  /**
   * Identifies pointers to instances of this kind of actor.
   */
  using pointer = typed_event_based_actor<Rs...>*;

  /**
   * Identifies the base class for this kind of actor.
   */
  using base = typed_event_based_actor<Rs...>;

  typed_actor() = default;
  typed_actor(typed_actor&&) = default;
  typed_actor(const typed_actor&) = default;
  typed_actor& operator=(typed_actor&&) = default;
  typed_actor& operator=(const typed_actor&) = default;

  template <class... OtherRs>
  typed_actor(const typed_actor<OtherRs...>& other) {
    set(std::move(other));
  }

  template <class... OtherRs>
  typed_actor& operator=(const typed_actor<OtherRs...>& other) {
    set(std::move(other));
    return *this;
  }

  template <class Impl>
  typed_actor(intrusive_ptr<Impl> other) {
    set(other);
  }

  abstract_actor* operator->() const {
    return m_ptr.get();
  }

  abstract_actor& operator*() const {
    return *m_ptr.get();
  }

  /**
   * Queries the address of the stored actor.
   */
  actor_addr address() const {
    return m_ptr ? m_ptr->address() : actor_addr{};
  }

  inline intptr_t compare(const actor_addr& rhs) const {
    return address().compare(rhs);
  }

  inline intptr_t compare(const typed_actor& other) const {
    return compare(other.address());
  }

  inline intptr_t compare(const invalid_actor_addr_t&) const {
    return m_ptr ? 1 : 0;
  }

  static std::set<std::string> message_types() {
    return {detail::to_uniform_name<Rs>()...};
  }

  explicit operator bool() const { return static_cast<bool>(m_ptr); }

  inline bool operator!() const { return !m_ptr; }

 private:

  inline abstract_actor* get() const { return m_ptr.get(); }

  typed_actor(abstract_actor* ptr) : m_ptr(ptr) {}

  template <class ListA, class ListB>
  inline void check_signatures() {
    static_assert(detail::tl_is_strict_subset<ListA, ListB>::value,
            "'this' must be a strict subset of 'other'");
  }

  template <class... OtherRs>
  inline void set(const typed_actor<OtherRs...>& other) {
    check_signatures<detail::type_list<Rs...>, detail::type_list<OtherRs...>>();
    m_ptr = other.m_ptr;
  }

  template <class Impl>
  inline void set(intrusive_ptr<Impl>& other) {
    check_signatures<detail::type_list<Rs...>, typename Impl::signatures>();
    m_ptr = std::move(other);
  }

  abstract_actor_ptr m_ptr;

};

} // namespace caf

#endif // CAF_TYPED_ACTOR_HPP
<|endoftext|>


<commit_before>/*
 * libcpu: translate_singlestep.cpp
 *
 * This translates a single instruction and hooks up all
 * basic blocks (branch target, taken, non-taken, ...)
 * so that execution will always exit after the instruction.
 */

#include "llvm/BasicBlock.h"

#include "libcpu.h"
#include "libcpu_llvm.h"
#include "disasm.h"
#include "tag.h"
#include "basicblock.h"
#include "translate.h"

//////////////////////////////////////////////////////////////////////
// single stepping
//////////////////////////////////////////////////////////////////////

BasicBlock *
create_singlestep_return_basicblock(cpu_t *cpu, addr_t new_pc, BasicBlock *bb_ret)
{
	BasicBlock *bb_branch = create_basicblock(cpu, new_pc, cpu->cur_func, BB_TYPE_NORMAL);
	emit_store_pc_return(cpu, bb_branch, new_pc, bb_ret);
	return bb_branch;
}

BasicBlock *
cpu_translate_singlestep(cpu_t *cpu, BasicBlock *bb_ret, BasicBlock *bb_trap)
{
	addr_t new_pc;
	tag_t tag;
	BasicBlock *cur_bb = NULL, *bb_target = NULL, *bb_next = NULL, *bb_cont = NULL;
	addr_t next_pc, pc = cpu->f.get_pc(cpu, cpu->rf.grf);

	cur_bb = BasicBlock::Create(_CTX(), "instruction", cpu->cur_func, 0);

	if (LOGGING)
		disasm_instr(cpu, pc);

	cpu->f.tag_instr(cpu, pc, &tag, &new_pc, &next_pc);

	/* get target basic block */
	if ((tag & TAG_RET) || (new_pc == NEW_PC_NONE)) /* translate_instr() will set PC */
		bb_target = bb_ret;
	else if (tag & (TAG_CALL|TAG_BRANCH))
		bb_target = create_singlestep_return_basicblock(cpu, new_pc, bb_ret);
	/* get not-taken & conditional basic block */
	if (tag & TAG_CONDITIONAL)
		bb_next = create_singlestep_return_basicblock(cpu, next_pc, bb_ret);

	bb_cont = translate_instr(cpu, pc, tag, bb_target, bb_trap, bb_next, cur_bb);

	/* If it's not a branch, append "store PC & return" to basic block */
	if (bb_cont)
		emit_store_pc_return(cpu, bb_cont, next_pc, bb_ret);

	return cur_bb;
}
<commit_msg>fix build<commit_after>/*
 * libcpu: translate_singlestep.cpp
 *
 * This translates a single instruction and hooks up all
 * basic blocks (branch target, taken, non-taken, ...)
 * so that execution will always exit after the instruction.
 */

#include "llvm/IR/BasicBlock.h"

#include "libcpu.h"
#include "libcpu_llvm.h"
#include "disasm.h"
#include "tag.h"
#include "basicblock.h"
#include "translate.h"

//////////////////////////////////////////////////////////////////////
// single stepping
//////////////////////////////////////////////////////////////////////

BasicBlock *
create_singlestep_return_basicblock(cpu_t *cpu, addr_t new_pc, BasicBlock *bb_ret)
{
	BasicBlock *bb_branch = create_basicblock(cpu, new_pc, cpu->cur_func, BB_TYPE_NORMAL);
	emit_store_pc_return(cpu, bb_branch, new_pc, bb_ret);
	return bb_branch;
}

BasicBlock *
cpu_translate_singlestep(cpu_t *cpu, BasicBlock *bb_ret, BasicBlock *bb_trap)
{
	addr_t new_pc;
	tag_t tag;
	BasicBlock *cur_bb = NULL, *bb_target = NULL, *bb_next = NULL, *bb_cont = NULL;
	addr_t next_pc, pc = cpu->f.get_pc(cpu, cpu->rf.grf);

	cur_bb = BasicBlock::Create(_CTX(), "instruction", cpu->cur_func, 0);

	if (LOGGING)
		disasm_instr(cpu, pc);

	cpu->f.tag_instr(cpu, pc, &tag, &new_pc, &next_pc);

	/* get target basic block */
	if ((tag & TAG_RET) || (new_pc == NEW_PC_NONE)) /* translate_instr() will set PC */
		bb_target = bb_ret;
	else if (tag & (TAG_CALL|TAG_BRANCH))
		bb_target = create_singlestep_return_basicblock(cpu, new_pc, bb_ret);
	/* get not-taken & conditional basic block */
	if (tag & TAG_CONDITIONAL)
		bb_next = create_singlestep_return_basicblock(cpu, next_pc, bb_ret);

	bb_cont = translate_instr(cpu, pc, tag, bb_target, bb_trap, bb_next, cur_bb);

	/* If it's not a branch, append "store PC & return" to basic block */
	if (bb_cont)
		emit_store_pc_return(cpu, bb_cont, next_pc, bb_ret);

	return cur_bb;
}
<|endoftext|>


<commit_before>/*
    kopetexsl.cpp - Kopete XSL Routines

    Copyright (c) 2003 by Jason Keirstead <jason@keirstead.org>

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

#include <libxslt/transform.h>
#include <libxml/parser.h>

#include <kdebug.h>
#include <kopetexsl.h>
#include <qregexp.h>
#include <qsignal.h>

//#define XSL_DEBUG 1

extern int xmlLoadExtDtdDefaultValue;

const QString KopeteXSL::xsltTransform( const QString &xmlString, const QString &xslString )
{
	KopeteXSLThread mThread( xmlString, xslString );
	mThread.start();
	mThread.wait();
	return mThread.result();
}

void KopeteXSL::xsltTransformAsync( const QString &xmlString, const QString &xslString,
			QObject *target, const char* slotCompleted )
{
	KopeteXSLThread *mThread = new KopeteXSLThread( xmlString, xslString, target, slotCompleted );
	mThread->start();
}

bool KopeteXSL::isValid( const QString &xslString )
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xslDoc = NULL;
	bool retVal = false;

	// Convert QString into a C string
	QCString xslCString = xslString.utf8();

	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xslDoc != NULL )
	{
		style_sheet = xsltParseStylesheetDoc( xslDoc );
		if( style_sheet != NULL )
		{
			retVal = true;
			xsltFreeStylesheet(style_sheet);
		}
		else
		{
			xmlFreeDoc(xslDoc);
		}
	}

	return retVal;
}

KopeteXSLThread::KopeteXSLThread( const QString &xmlString, const QString &xslString, QObject *target, const char* slotCompleted )
{
	m_xml = xmlString;
	m_xsl = xslString;

	m_target = target;
	m_slotCompleted = slotCompleted;
}

void KopeteXSLThread::run()
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xmlDoc, xslDoc, resultDoc;

	//Init Stuff
	xmlLoadExtDtdDefaultValue = 0;
	xmlSubstituteEntitiesDefault(1);

	// Convert QString into a C string
	QCString xmlCString = m_xml.utf8();
	QCString xslCString = m_xsl.utf8();

	// Read XML docs in from memory
	xmlDoc = xmlParseMemory( xmlCString, xmlCString.length() );
	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xmlDoc != NULL )
	{
		if( xslDoc != NULL )
		{
			style_sheet = xsltParseStylesheetDoc( xslDoc );
			if( style_sheet != NULL )
			{
				resultDoc = xsltApplyStylesheet(style_sheet, xmlDoc, NULL);
				if( resultDoc != NULL )
				{
					//Save the result into the QString
					xmlChar *mem;
					int size;
					xmlDocDumpMemory( resultDoc, &mem, &size );
					m_resultString = QString::fromUtf8( QCString( (char*)mem, size + 1 ) );
					delete mem;
					xmlFreeDoc(resultDoc);
				}
				else
				{
					kdDebug() << "Transformed document is null!!!" << endl;
				}
				xsltFreeStylesheet(style_sheet);
			}
			else
			{
				kdDebug() << "Document is not valid XSL!!!" << endl;
				xmlFreeDoc(xslDoc);
			}
		}
		else
		{
			kdDebug() << "XSL Document could not be parsed!!!" << endl;
		}
		xmlFreeDoc(xmlDoc);
	}
	else
	{
		kdDebug() << "XML Document could not be parsed!!!" << endl;
	}

	//Signal completion
	if( m_target && m_slotCompleted )
	{
		QSignal completeSignal( m_target );
		completeSignal.connect( m_target, m_slotCompleted );
		completeSignal.setValue( m_resultString );
		completeSignal.activate();

		delete this;
	}
}

QString KopeteXSL::unescape( const QString &xml )
{
	QString data = xml;

	data.replace( QRegExp( QString::fromLatin1( "\"\"" ) ), QString::fromLatin1( "\"" ) );
	data.replace( QRegExp( QString::fromLatin1( ">" ) ), QString::fromLatin1( ">" ) );
	data.replace( QRegExp( QString::fromLatin1( "<" ) ), QString::fromLatin1( "<" ) );
	data.replace( QRegExp( QString::fromLatin1( """ ) ), QString::fromLatin1( "\"" ) );
	data.replace( QRegExp( QString::fromLatin1( "&" ) ), QString::fromLatin1( "&" ) );

	return data;
}
<commit_msg>fix compile<commit_after>/*
    kopetexsl.cpp - Kopete XSL Routines

    Copyright (c) 2003 by Jason Keirstead <jason@keirstead.org>

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

#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
#include <libxml/parser.h>

#include <kdebug.h>
#include <kopetexsl.h>
#include <qregexp.h>
#include <qsignal.h>

//#define XSL_DEBUG 1

extern int xmlLoadExtDtdDefaultValue;

const QString KopeteXSL::xsltTransform( const QString &xmlString, const QString &xslString )
{
	KopeteXSLThread mThread( xmlString, xslString );
	mThread.start();
	mThread.wait();
	return mThread.result();
}

void KopeteXSL::xsltTransformAsync( const QString &xmlString, const QString &xslString,
			QObject *target, const char* slotCompleted )
{
	KopeteXSLThread *mThread = new KopeteXSLThread( xmlString, xslString, target, slotCompleted );
	mThread->start();
}

bool KopeteXSL::isValid( const QString &xslString )
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xslDoc = NULL;
	bool retVal = false;

	// Convert QString into a C string
	QCString xslCString = xslString.utf8();

	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xslDoc != NULL )
	{
		style_sheet = xsltParseStylesheetDoc( xslDoc );
		if( style_sheet != NULL )
		{
			retVal = true;
			xsltFreeStylesheet(style_sheet);
		}
		else
		{
			xmlFreeDoc(xslDoc);
		}
	}

	return retVal;
}

KopeteXSLThread::KopeteXSLThread( const QString &xmlString, const QString &xslString, QObject *target, const char* slotCompleted )
{
	m_xml = xmlString;
	m_xsl = xslString;

	m_target = target;
	m_slotCompleted = slotCompleted;
}

void KopeteXSLThread::run()
{
	xsltStylesheetPtr style_sheet = NULL;
	xmlDocPtr xmlDoc, xslDoc, resultDoc;

	//Init Stuff
	xmlLoadExtDtdDefaultValue = 0;
	xmlSubstituteEntitiesDefault(1);

	// Convert QString into a C string
	QCString xmlCString = m_xml.utf8();
	QCString xslCString = m_xsl.utf8();

	// Read XML docs in from memory
	xmlDoc = xmlParseMemory( xmlCString, xmlCString.length() );
	xslDoc = xmlParseMemory( xslCString, xslCString.length() );

	if( xmlDoc != NULL )
	{
		if( xslDoc != NULL )
		{
			style_sheet = xsltParseStylesheetDoc( xslDoc );
			if( style_sheet != NULL )
			{
				resultDoc = xsltApplyStylesheet(style_sheet, xmlDoc, NULL);
				if( resultDoc != NULL )
				{
					//Save the result into the QString
					xmlChar *mem;
					int size;
					xmlDocDumpMemory( resultDoc, &mem, &size );
					m_resultString = QString::fromUtf8( QCString( (char*)mem, size + 1 ) );
					delete mem;
					xmlFreeDoc(resultDoc);
				}
				else
				{
					kdDebug() << "Transformed document is null!!!" << endl;
				}
				xsltFreeStylesheet(style_sheet);
			}
			else
			{
				kdDebug() << "Document is not valid XSL!!!" << endl;
				xmlFreeDoc(xslDoc);
			}
		}
		else
		{
			kdDebug() << "XSL Document could not be parsed!!!" << endl;
		}
		xmlFreeDoc(xmlDoc);
	}
	else
	{
		kdDebug() << "XML Document could not be parsed!!!" << endl;
	}

	//Signal completion
	if( m_target && m_slotCompleted )
	{
		QSignal completeSignal( m_target );
		completeSignal.connect( m_target, m_slotCompleted );
		completeSignal.setValue( m_resultString );
		completeSignal.activate();

		delete this;
	}
}

QString KopeteXSL::unescape( const QString &xml )
{
	QString data = xml;

	data.replace( QRegExp( QString::fromLatin1( "\"\"" ) ), QString::fromLatin1( "\"" ) );
	data.replace( QRegExp( QString::fromLatin1( ">" ) ), QString::fromLatin1( ">" ) );
	data.replace( QRegExp( QString::fromLatin1( "<" ) ), QString::fromLatin1( "<" ) );
	data.replace( QRegExp( QString::fromLatin1( """ ) ), QString::fromLatin1( "\"" ) );
	data.replace( QRegExp( QString::fromLatin1( "&" ) ), QString::fromLatin1( "&" ) );

	return data;
}
<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include "proxy.h"

namespace ti
{
	Proxy::Proxy(const std::string& _hostname,
		const std::string& _port,
		const std::string& _username,
		const std::string& _password)
		: hostname(_hostname),
		  port(_port),
		  username(_username),
		  password(_password)
	{

		/**
		 * @tiapi(method=True,name=Titanium.Network.Proxy.getHostName,since=0.4) Returns the hostname of a Proxy object
		 * @tiresult(for=Titanium.Network.Proxy.getHostName, type=string) the hostname of the Proxy object
		 */
		this->SetMethod("getHostName",&Proxy::getHostName);

		/**
		 * @tiapi(method=True,name=Titanium.Network.Proxy.getPort,since=0.4) Returns the port of a Proxy object
		 * @tiresult(for=Titanium.Network.Proxy.getPort, type=string) the port of the Proxy object
		 */
		this->SetMethod("getPort",&Proxy::getPort);

		/**
		 * @tiapi(method=True,name=Titanium.Network.Proxy.getUserName,since=0.4) Returns the username of a Proxy object
		 * @tiresult(for=Titanium.Network.Proxy.getUserName, type=string) the username of the Proxy object
		 */
		this->SetMethod("getUserName",&Proxy::getUserName);

		/**
		 * @tiapi(method=True,name=Titanium.Network.Proxy.getPassword,since=0.4) Returns the password of a Proxy object
		 * @tiresult(for=Titanium.Network.Proxy.getPassword, type=string) the password of the Proxy object
		 */
		this->SetMethod("getPassword",&Proxy::getPassword);
	}

	Proxy::~Proxy()
	{
	}

	void Proxy::getHostName(const ValueList& args, SharedValue result)
	{
		result->SetString(this->hostname.c_str());
	}

	void Proxy::getPort(const ValueList& args, SharedValue result)
	{
		result->SetString(this->port.c_str());
	}

	void Proxy::getUserName(const ValueList& args, SharedValue result)
	{
		result->SetString(this->username.c_str());
	}

	void Proxy::getPassword(const ValueList& args, SharedValue result)
	{
		result->SetString(this->password.c_str());
	}
}
<commit_msg>Additional fixes for the API coverage documentation<commit_after>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include "proxy.h"

namespace ti
{
	Proxy::Proxy(const std::string& _hostname,
		const std::string& _port,
		const std::string& _username,
		const std::string& _password)
		: hostname(_hostname),
		  port(_port),
		  username(_username),
		  password(_password)
	{

		/**
		 * @tiapi(method=True,name=Network.Proxy.getHostName,since=0.4) Returns the hostname of a Proxy object
		 * @tiresult(for=Network.Proxy.getHostName, type=string) the hostname of the Proxy object
		 */
		this->SetMethod("getHostName",&Proxy::getHostName);

		/**
		 * @tiapi(method=True,name=Network.Proxy.getPort,since=0.4) Returns the port of a Proxy object
		 * @tiresult(for=Network.Proxy.getPort, type=string) the port of the Proxy object
		 */
		this->SetMethod("getPort",&Proxy::getPort);

		/**
		 * @tiapi(method=True,name=Network.Proxy.getUserName,since=0.4) Returns the username of a Proxy object
		 * @tiresult(for=Network.Proxy.getUserName, type=string) the username of the Proxy object
		 */
		this->SetMethod("getUserName",&Proxy::getUserName);

		/**
		 * @tiapi(method=True,name=Network.Proxy.getPassword,since=0.4) Returns the password of a Proxy object
		 * @tiresult(for=Network.Proxy.getPassword, type=string) the password of the Proxy object
		 */
		this->SetMethod("getPassword",&Proxy::getPassword);
	}

	Proxy::~Proxy()
	{
	}

	void Proxy::getHostName(const ValueList& args, SharedValue result)
	{
		result->SetString(this->hostname.c_str());
	}

	void Proxy::getPort(const ValueList& args, SharedValue result)
	{
		result->SetString(this->port.c_str());
	}

	void Proxy::getUserName(const ValueList& args, SharedValue result)
	{
		result->SetString(this->username.c_str());
	}

	void Proxy::getPassword(const ValueList& args, SharedValue result)
	{
		result->SetString(this->password.c_str());
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006  Justin Karneges
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 *
 */

// this code assumes the following ioctls work:
//   SIOCGIFCONF  - get list of devices
//   SIOCGIFFLAGS - get flags about a device

// gateway detection currently only works on linux

#include "irisnetplugin.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <errno.h>

// for solaris
#ifndef SIOCGIFCONF
# include<sys/sockio.h>
#endif

class UnixIface
{
public:
	QString name;
	bool loopback;
	QHostAddress address;
};

class UnixGateway
{
public:
	QString ifaceName;
	QHostAddress address;
};

static QList<UnixIface> get_sioc_ifaces()
{
	QList<UnixIface> out;

	int tmpsock = socket(AF_INET, SOCK_DGRAM, 0);
	if(tmpsock < 0)
		return out;

	struct ifconf ifc;
	int lastlen = 0;
	QByteArray buf(100 * sizeof(struct ifreq), 0); // guess
	while(1)
	{
		ifc.ifc_len = buf.size();
		ifc.ifc_buf = buf.data();
		if(ioctl(tmpsock, SIOCGIFCONF, &ifc) < 0)
		{
			if(errno != EINVAL || lastlen != 0)
				return out;
		}
		else
		{
			// if it didn't grow since last time, then
			//   there's no overflow
			if(ifc.ifc_len == lastlen)
				break;
			lastlen = ifc.ifc_len;
		}
		buf.resize(buf.size() + 10 * sizeof(struct ifreq));
	}
	buf.resize(lastlen);

	int itemsize;
	for(int at = 0; at < buf.size(); at += itemsize)
	{
		struct ifreq *ifr = (struct ifreq *)(buf.data() + at);

		int sockaddr_len;
		if(((struct sockaddr *)&ifr->ifr_addr)->sa_family == AF_INET)
			sockaddr_len = sizeof(struct sockaddr_in);
		else if(((struct sockaddr *)&ifr->ifr_addr)->sa_family == AF_INET6)
			sockaddr_len = sizeof(struct sockaddr_in6);
		else
			sockaddr_len = sizeof(struct sockaddr);

		// set this asap so the next iteration is possible
		itemsize = sizeof(ifr->ifr_name) + sockaddr_len;

		// skip if the family is 0 (sometimes you get empty entries)
		if(ifr->ifr_addr.sa_family == 0)
			continue;

		// make a copy of this item to do additional ioctls on
		struct ifreq ifrcopy = *ifr;

		// grab the flags
		if(ioctl(tmpsock, SIOCGIFFLAGS, &ifrcopy) < 0)
			continue;

		// device must be up and not loopback
		if(!(ifrcopy.ifr_flags & IFF_UP))
			continue;

		UnixIface i;
		i.name = QString::fromLatin1(ifr->ifr_name);
		i.loopback = (ifrcopy.ifr_flags & IFF_LOOPBACK) ? true : false;
		i.address.setAddress(&ifr->ifr_addr);
		out += i;
	}

	// don't need this anymore
	close(tmpsock);

	return out;
}

#ifdef Q_OS_LINUX
static QStringList read_proc_as_lines(const char *procfile)
{
	QStringList out;

	FILE *f = fopen(procfile, "r");
	if(!f)
		return out;

	QByteArray buf;
	while(!feof(f))
	{
		// max read on a proc is 4K
		QByteArray block(4096, 0);
		int ret = fread(block.data(), 1, block.size(), f);
		if(ret <= 0)
			break;
		block.resize(ret);
		buf += block;
	}
	fclose(f);

	QString str = QString::fromLocal8Bit(buf);
	out = str.split('\n', QString::SkipEmptyParts);
	return out;
}

static QHostAddress linux_ipv6_to_qaddr(const QString &in)
{
	QHostAddress out;
	if(in.length() != 32)
		return out;
	quint8 raw[16];
	for(int n = 0; n < 16; ++n)
	{
		bool ok;
		int x = in.mid(n * 2, 2).toInt(&ok, 16);
		if(!ok)
			return out;
		raw[n] = (quint8)x;
	}
	out.setAddress(raw);
	return out;
}

static QHostAddress linux_ipv4_to_qaddr(const QString &in)
{
	QHostAddress out;
	if(in.length() != 8)
		return out;
	quint32 raw;
	unsigned char *rawp = (unsigned char *)&raw;
	for(int n = 0; n < 4; ++n)
	{
		bool ok;
		int x = in.mid(n * 2, 2).toInt(&ok, 16);
		if(!ok)
			return out;
		rawp[n] = (unsigned char )x;
	}
	out.setAddress(raw);
	return out;
}

static QList<UnixIface> get_linux_ipv6_ifaces()
{
	QList<UnixIface> out;

	QStringList lines = read_proc_as_lines("/proc/net/if_inet6");
	for(int n = 0; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 6)
			continue;

		QString name = parts[5];
		if(name.isEmpty())
			continue;
		QHostAddress addr = linux_ipv6_to_qaddr(parts[0]);
		if(addr.isNull())
			continue;

		QString scopestr = parts[3];
		bool ok;
		unsigned int scope = parts[3].toInt(&ok, 16);
		if(!ok)
			continue;

		// IPV6_ADDR_LOOPBACK    0x0010U
		// IPV6_ADDR_SCOPE_MASK  0x00f0U
		bool loopback = false;
		if((scope & 0x00f0U) == 0x0010U)
			loopback = true;

		UnixIface i;
		i.name = name;
		i.loopback = loopback;
		i.address = addr;
		out += i;
	}

	return out;
}

static QList<UnixGateway> get_linux_gateways()
{
	QList<UnixGateway> out;

	QStringList lines = read_proc_as_lines("/proc/net/route");
	// skip the first line, so we start at 1
	for(int n = 1; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 10) // net-tools does 10, but why not 11?
			continue;

		QHostAddress addr = linux_ipv4_to_qaddr(parts[2]);
		if(addr.isNull())
			continue;

		int iflags = parts[3].toInt(0, 16);
		if(!(iflags & RTF_UP))
			continue;

		if(!(iflags & RTF_GATEWAY))
			continue;

		UnixGateway g;
		g.ifaceName = parts[0];
		g.address = addr;
		out += g;
	}

	lines = read_proc_as_lines("/proc/net/ipv6_route");
	for(int n = 0; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 10)
			continue;

		QHostAddress addr = linux_ipv6_to_qaddr(parts[4]);
		if(addr.isNull())
			continue;

		int iflags = parts[8].toInt(0, 16);
		if(!(iflags & RTF_UP))
			continue;

		if(!(iflags & RTF_GATEWAY))
			continue;

		UnixGateway g;
		g.ifaceName = parts[9];
		g.address = addr;
		out += g;
	}

	return out;
}
#endif

static QList<UnixIface> get_unix_ifaces()
{
	QList<UnixIface> out = get_sioc_ifaces();
#ifdef Q_OS_LINUX
	out += get_linux_ipv6_ifaces();
#endif
	return out;
}

static QList<UnixGateway> get_unix_gateways()
{
	// support other platforms here
	QList<UnixGateway> out;
#ifdef Q_OS_LINUX
	out = get_linux_gateways();
#endif
	return out;
}

namespace XMPP {

class UnixNet : public NetInterfaceProvider
{
	Q_OBJECT
	Q_INTERFACES(XMPP::NetInterfaceProvider)
public:
	QList<Info> info;
	QTimer t;

	UnixNet() : t(this)
	{
		connect(&t, SIGNAL(timeout()), SLOT(check()));
	}

	void start()
	{
		t.start(5000);
		poll();
	}

	QList<Info> interfaces() const
	{
		return info;
	}

	void poll()
	{
		QList<Info> ifaces;

		QList<UnixIface> list = get_unix_ifaces();
		for(int n = 0; n < list.count(); ++n)
		{
			// see if we have it already
			int lookup = -1;
			for(int k = 0; k < ifaces.count(); ++k)
			{
				if(ifaces[k].id == list[n].name)
				{
					lookup = k;
					break;
				}
			}

			// don't have it?  make it
			if(lookup == -1)
			{
				Info i;
				i.id = list[n].name;
				i.name = list[n].name;
				i.isLoopback = list[n].loopback;
				i.addresses += list[n].address;
				ifaces += i;
			}
			// otherwise, tack on the address
			else
				ifaces[lookup].addresses += list[n].address;
		}

		QList<UnixGateway> glist = get_unix_gateways();
		for(int n = 0; n < glist.count(); ++n)
		{
			// look up the interface
			int lookup = -1;
			for(int k = 0; k < ifaces.count(); ++k)
			{
				if(ifaces[k].id == glist[n].ifaceName)
				{
					lookup = k;
					break;
				}
			}

			if(lookup == -1)
				break;

			ifaces[lookup].gateway = glist[n].address;
		}

		info = ifaces;
	}

public slots:
	void check()
	{
		poll();
		emit updated();
	}
};

class UnixNetProvider : public IrisNetProvider
{
	Q_OBJECT
	Q_INTERFACES(XMPP::IrisNetProvider)
public:
	virtual NetInterfaceProvider *createNetInterfaceProvider()
	{
		return new UnixNet;
	}
};

IrisNetProvider *irisnet_createUnixNetProvider()
{
	return new UnixNetProvider;
}

}

#include "netinterface_unix.moc"
<commit_msg>SVN_SILENT compile<commit_after>/*
 * Copyright (C) 2006  Justin Karneges
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 *
 */

// this code assumes the following ioctls work:
//   SIOCGIFCONF  - get list of devices
//   SIOCGIFFLAGS - get flags about a device

// gateway detection currently only works on linux

#include "irisnetplugin.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>

// for solaris
#ifndef SIOCGIFCONF
# include<sys/sockio.h>
#endif

class UnixIface
{
public:
	QString name;
	bool loopback;
	QHostAddress address;
};

class UnixGateway
{
public:
	QString ifaceName;
	QHostAddress address;
};

static QList<UnixIface> get_sioc_ifaces()
{
	QList<UnixIface> out;

	int tmpsock = socket(AF_INET, SOCK_DGRAM, 0);
	if(tmpsock < 0)
		return out;

	struct ifconf ifc;
	int lastlen = 0;
	QByteArray buf(100 * sizeof(struct ifreq), 0); // guess
	while(1)
	{
		ifc.ifc_len = buf.size();
		ifc.ifc_buf = buf.data();
		if(ioctl(tmpsock, SIOCGIFCONF, &ifc) < 0)
		{
			if(errno != EINVAL || lastlen != 0)
				return out;
		}
		else
		{
			// if it didn't grow since last time, then
			//   there's no overflow
			if(ifc.ifc_len == lastlen)
				break;
			lastlen = ifc.ifc_len;
		}
		buf.resize(buf.size() + 10 * sizeof(struct ifreq));
	}
	buf.resize(lastlen);

	int itemsize;
	for(int at = 0; at < buf.size(); at += itemsize)
	{
		struct ifreq *ifr = (struct ifreq *)(buf.data() + at);

		int sockaddr_len;
		if(((struct sockaddr *)&ifr->ifr_addr)->sa_family == AF_INET)
			sockaddr_len = sizeof(struct sockaddr_in);
		else if(((struct sockaddr *)&ifr->ifr_addr)->sa_family == AF_INET6)
			sockaddr_len = sizeof(struct sockaddr_in6);
		else
			sockaddr_len = sizeof(struct sockaddr);

		// set this asap so the next iteration is possible
		itemsize = sizeof(ifr->ifr_name) + sockaddr_len;

		// skip if the family is 0 (sometimes you get empty entries)
		if(ifr->ifr_addr.sa_family == 0)
			continue;

		// make a copy of this item to do additional ioctls on
		struct ifreq ifrcopy = *ifr;

		// grab the flags
		if(ioctl(tmpsock, SIOCGIFFLAGS, &ifrcopy) < 0)
			continue;

		// device must be up and not loopback
		if(!(ifrcopy.ifr_flags & IFF_UP))
			continue;

		UnixIface i;
		i.name = QString::fromLatin1(ifr->ifr_name);
		i.loopback = (ifrcopy.ifr_flags & IFF_LOOPBACK) ? true : false;
		i.address.setAddress(&ifr->ifr_addr);
		out += i;
	}

	// don't need this anymore
	close(tmpsock);

	return out;
}

#ifdef Q_OS_LINUX
static QStringList read_proc_as_lines(const char *procfile)
{
	QStringList out;

	FILE *f = fopen(procfile, "r");
	if(!f)
		return out;

	QByteArray buf;
	while(!feof(f))
	{
		// max read on a proc is 4K
		QByteArray block(4096, 0);
		int ret = fread(block.data(), 1, block.size(), f);
		if(ret <= 0)
			break;
		block.resize(ret);
		buf += block;
	}
	fclose(f);

	QString str = QString::fromLocal8Bit(buf);
	out = str.split('\n', QString::SkipEmptyParts);
	return out;
}

static QHostAddress linux_ipv6_to_qaddr(const QString &in)
{
	QHostAddress out;
	if(in.length() != 32)
		return out;
	quint8 raw[16];
	for(int n = 0; n < 16; ++n)
	{
		bool ok;
		int x = in.mid(n * 2, 2).toInt(&ok, 16);
		if(!ok)
			return out;
		raw[n] = (quint8)x;
	}
	out.setAddress(raw);
	return out;
}

static QHostAddress linux_ipv4_to_qaddr(const QString &in)
{
	QHostAddress out;
	if(in.length() != 8)
		return out;
	quint32 raw;
	unsigned char *rawp = (unsigned char *)&raw;
	for(int n = 0; n < 4; ++n)
	{
		bool ok;
		int x = in.mid(n * 2, 2).toInt(&ok, 16);
		if(!ok)
			return out;
		rawp[n] = (unsigned char )x;
	}
	out.setAddress(raw);
	return out;
}

static QList<UnixIface> get_linux_ipv6_ifaces()
{
	QList<UnixIface> out;

	QStringList lines = read_proc_as_lines("/proc/net/if_inet6");
	for(int n = 0; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 6)
			continue;

		QString name = parts[5];
		if(name.isEmpty())
			continue;
		QHostAddress addr = linux_ipv6_to_qaddr(parts[0]);
		if(addr.isNull())
			continue;

		QString scopestr = parts[3];
		bool ok;
		unsigned int scope = parts[3].toInt(&ok, 16);
		if(!ok)
			continue;

		// IPV6_ADDR_LOOPBACK    0x0010U
		// IPV6_ADDR_SCOPE_MASK  0x00f0U
		bool loopback = false;
		if((scope & 0x00f0U) == 0x0010U)
			loopback = true;

		UnixIface i;
		i.name = name;
		i.loopback = loopback;
		i.address = addr;
		out += i;
	}

	return out;
}

static QList<UnixGateway> get_linux_gateways()
{
	QList<UnixGateway> out;

	QStringList lines = read_proc_as_lines("/proc/net/route");
	// skip the first line, so we start at 1
	for(int n = 1; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 10) // net-tools does 10, but why not 11?
			continue;

		QHostAddress addr = linux_ipv4_to_qaddr(parts[2]);
		if(addr.isNull())
			continue;

		int iflags = parts[3].toInt(0, 16);
		if(!(iflags & RTF_UP))
			continue;

		if(!(iflags & RTF_GATEWAY))
			continue;

		UnixGateway g;
		g.ifaceName = parts[0];
		g.address = addr;
		out += g;
	}

	lines = read_proc_as_lines("/proc/net/ipv6_route");
	for(int n = 0; n < lines.count(); ++n)
	{
		const QString &line = lines[n];
		QStringList parts = line.simplified().split(' ', QString::SkipEmptyParts);
		if(parts.count() < 10)
			continue;

		QHostAddress addr = linux_ipv6_to_qaddr(parts[4]);
		if(addr.isNull())
			continue;

		int iflags = parts[8].toInt(0, 16);
		if(!(iflags & RTF_UP))
			continue;

		if(!(iflags & RTF_GATEWAY))
			continue;

		UnixGateway g;
		g.ifaceName = parts[9];
		g.address = addr;
		out += g;
	}

	return out;
}
#endif

static QList<UnixIface> get_unix_ifaces()
{
	QList<UnixIface> out = get_sioc_ifaces();
#ifdef Q_OS_LINUX
	out += get_linux_ipv6_ifaces();
#endif
	return out;
}

static QList<UnixGateway> get_unix_gateways()
{
	// support other platforms here
	QList<UnixGateway> out;
#ifdef Q_OS_LINUX
	out = get_linux_gateways();
#endif
	return out;
}

namespace XMPP {

class UnixNet : public NetInterfaceProvider
{
	Q_OBJECT
	Q_INTERFACES(XMPP::NetInterfaceProvider)
public:
	QList<Info> info;
	QTimer t;

	UnixNet() : t(this)
	{
		connect(&t, SIGNAL(timeout()), SLOT(check()));
	}

	void start()
	{
		t.start(5000);
		poll();
	}

	QList<Info> interfaces() const
	{
		return info;
	}

	void poll()
	{
		QList<Info> ifaces;

		QList<UnixIface> list = get_unix_ifaces();
		for(int n = 0; n < list.count(); ++n)
		{
			// see if we have it already
			int lookup = -1;
			for(int k = 0; k < ifaces.count(); ++k)
			{
				if(ifaces[k].id == list[n].name)
				{
					lookup = k;
					break;
				}
			}

			// don't have it?  make it
			if(lookup == -1)
			{
				Info i;
				i.id = list[n].name;
				i.name = list[n].name;
				i.isLoopback = list[n].loopback;
				i.addresses += list[n].address;
				ifaces += i;
			}
			// otherwise, tack on the address
			else
				ifaces[lookup].addresses += list[n].address;
		}

		QList<UnixGateway> glist = get_unix_gateways();
		for(int n = 0; n < glist.count(); ++n)
		{
			// look up the interface
			int lookup = -1;
			for(int k = 0; k < ifaces.count(); ++k)
			{
				if(ifaces[k].id == glist[n].ifaceName)
				{
					lookup = k;
					break;
				}
			}

			if(lookup == -1)
				break;

			ifaces[lookup].gateway = glist[n].address;
		}

		info = ifaces;
	}

public slots:
	void check()
	{
		poll();
		emit updated();
	}
};

class UnixNetProvider : public IrisNetProvider
{
	Q_OBJECT
	Q_INTERFACES(XMPP::IrisNetProvider)
public:
	virtual NetInterfaceProvider *createNetInterfaceProvider()
	{
		return new UnixNet;
	}
};

IrisNetProvider *irisnet_createUnixNetProvider()
{
	return new UnixNetProvider;
}

}

#include "netinterface_unix.moc"
<|endoftext|>