<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/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"

using base::FieldTrial;
using base::FieldTrialList;

namespace prerender {

namespace {

const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
int g_omnibox_trial_default_group_number = kint32min;

const char kSpeculativePrefetchingLearningTrialName[] =
    "SpeculativePrefetchingLearning";
int g_speculative_prefetching_learning_default_group_number = kint32min;

void SetupPrefetchFieldTrial() {
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    return;
  }

  const FieldTrial::Probability divisor = 1000;
  const FieldTrial::Probability prefetch_probability = 500;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prefetch", divisor, "ContentPrefetchPrefetchOff",
          2013, 6, 30, NULL));
  const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn",
                                                  prefetch_probability);
  PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup);
}

void SetupPrerenderFieldTrial() {
  const FieldTrial::Probability divisor = 1000;

  FieldTrial::Probability control_probability;
  FieldTrial::Probability experiment_multi_prerender_probability;
  FieldTrial::Probability experiment_5min_ttl_probability;
  FieldTrial::Probability experiment_no_use_probability;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    // Use very conservatives and stable settings in beta and stable.
    const FieldTrial::Probability release_prerender_enabled_probability = 980;
    const FieldTrial::Probability release_control_probability = 10;
    const FieldTrial::Probability
        release_experiment_multi_prerender_probability = 0;
    const FieldTrial::Probability release_experiment_5min_ttl_probability = 10;
    const FieldTrial::Probability release_experiment_no_use_probability = 0;
    COMPILE_ASSERT(
        release_prerender_enabled_probability + release_control_probability +
        release_experiment_multi_prerender_probability +
        release_experiment_5min_ttl_probability +
        release_experiment_no_use_probability == divisor,
        release_experiment_probabilities_must_equal_divisor);

    control_probability = release_experiment_5min_ttl_probability;
    experiment_multi_prerender_probability =
        release_experiment_multi_prerender_probability;
    experiment_5min_ttl_probability = release_control_probability;
    experiment_no_use_probability = release_experiment_no_use_probability;
  } else {
    // In testing channels, use more experiments and a larger control group to
    // improve quality of data.
    const FieldTrial::Probability dev_prerender_enabled_probability = 250;
    const FieldTrial::Probability dev_control_probability = 250;
    const FieldTrial::Probability
        dev_experiment_multi_prerender_probability = 250;
    const FieldTrial::Probability dev_experiment_5min_ttl_probability = 125;
    const FieldTrial::Probability dev_experiment_no_use_probability = 125;
    COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
                   dev_experiment_multi_prerender_probability +
                   dev_experiment_5min_ttl_probability +
                   dev_experiment_no_use_probability == divisor,
                   dev_experiment_probabilities_must_equal_divisor);

    control_probability = dev_experiment_5min_ttl_probability;
    experiment_multi_prerender_probability =
        dev_experiment_multi_prerender_probability;
    experiment_5min_ttl_probability = dev_control_probability;
    experiment_no_use_probability = dev_experiment_no_use_probability;
  }

  int prerender_enabled_group = -1;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prerender", divisor, "PrerenderEnabled",
          2013, 6, 30, &prerender_enabled_group));
  const int control_group =
      trial->AppendGroup("PrerenderControl",
                         control_probability);
  const int experiment_multi_prerender_group =
      trial->AppendGroup("PrerenderMulti",
                         experiment_multi_prerender_probability);
  const int experiment_5_min_TTL_group =
      trial->AppendGroup("Prerender5minTTL",
                         experiment_5min_ttl_probability);
  const int experiment_no_use_group =
      trial->AppendGroup("PrerenderNoUse",
                         experiment_no_use_probability);

  const int trial_group = trial->group();
  if (trial_group == prerender_enabled_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
  } else if (trial_group == control_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
  } else if (trial_group == experiment_multi_prerender_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
  } else if (trial_group == experiment_5_min_TTL_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP);
  } else if (trial_group == experiment_no_use_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
  } else {
    NOTREACHED();
  }
}

}  // end namespace

void ConfigureOmniboxPrerender();
void ConfigureSpeculativePrefetching();

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerenderMode)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerenderMode);

    if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
      prerender_option = PRERENDER_OPTION_AUTO;
    } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderModeSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value ==
               switches::kPrerenderModeSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO:
      SetupPrefetchFieldTrial();
      SetupPrerenderFieldTrial();
      break;
    case PRERENDER_OPTION_DISABLED:
      PrerenderManager::SetIsPrefetchEnabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  UMA_HISTOGRAM_ENUMERATION("Prerender.Sessions",
                            PrerenderManager::GetMode(),
                            PrerenderManager::PRERENDER_MODE_MAX);

  ConfigureOmniboxPrerender();
  ConfigureSpeculativePrefetching();
}

void ConfigureOmniboxPrerender() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 10;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 1;
  }
  scoped_refptr<FieldTrial> omnibox_prerender_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
          2012, 12, 30, &g_omnibox_trial_default_group_number));
  omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
                                       kDisabledProbability);
}

bool IsOmniboxEnabled(Profile* profile) {
  if (!profile)
    return false;

  if (!PrerenderManager::IsPrerenderingPossible())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kPrerenderFromOmnibox)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kPrerenderFromOmnibox);

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
      return true;

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
      return false;

    DCHECK(switch_value == switches::kPrerenderFromOmniboxSwitchValueAuto);
  }

  const int group = FieldTrialList::FindValue(kOmniboxTrialName);
  return group == FieldTrial::kNotFinalized ||
         group == g_omnibox_trial_default_group_number;
}

void ConfigureSpeculativePrefetching() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 99;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 100;
  }
  scoped_refptr<FieldTrial> speculative_prefetching_learning_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kSpeculativePrefetchingLearningTrialName,
          kDivisor,
          "SpeculativePrefetchingLearningEnabled",
          2012, 12, 30,
          &g_speculative_prefetching_learning_default_group_number));
  speculative_prefetching_learning_trial->AppendGroup(
      "SpeculativePrefetchingDisabled",
      kDisabledProbability);
}

bool IsSpeculativeResourcePrefetchingLearningEnabled(Profile* profile) {
  if (!profile)
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);

    if (switch_value == switches::kSpeculativeResourcePrefetchingLearning)
      return true;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingLearningTrialName);
  return group == g_speculative_prefetching_learning_default_group_number;
}

}  // namespace prerender
<commit_msg>Enabling speculative resource prefetching for 90% users in canary/dev.<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/prerender/prerender_field_trial.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"

using base::FieldTrial;
using base::FieldTrialList;

namespace prerender {

namespace {

const char kOmniboxTrialName[] = "PrerenderFromOmnibox";
int g_omnibox_trial_default_group_number = kint32min;

const char kSpeculativePrefetchingLearningTrialName[] =
    "SpeculativePrefetchingLearning";
int g_speculative_prefetching_learning_default_group_number = kint32min;

void SetupPrefetchFieldTrial() {
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    return;
  }

  const FieldTrial::Probability divisor = 1000;
  const FieldTrial::Probability prefetch_probability = 500;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prefetch", divisor, "ContentPrefetchPrefetchOff",
          2013, 6, 30, NULL));
  const int kPrefetchOnGroup = trial->AppendGroup("ContentPrefetchPrefetchOn",
                                                  prefetch_probability);
  PrerenderManager::SetIsPrefetchEnabled(trial->group() == kPrefetchOnGroup);
}

void SetupPrerenderFieldTrial() {
  const FieldTrial::Probability divisor = 1000;

  FieldTrial::Probability control_probability;
  FieldTrial::Probability experiment_multi_prerender_probability;
  FieldTrial::Probability experiment_5min_ttl_probability;
  FieldTrial::Probability experiment_no_use_probability;

  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    // Use very conservatives and stable settings in beta and stable.
    const FieldTrial::Probability release_prerender_enabled_probability = 980;
    const FieldTrial::Probability release_control_probability = 10;
    const FieldTrial::Probability
        release_experiment_multi_prerender_probability = 0;
    const FieldTrial::Probability release_experiment_5min_ttl_probability = 10;
    const FieldTrial::Probability release_experiment_no_use_probability = 0;
    COMPILE_ASSERT(
        release_prerender_enabled_probability + release_control_probability +
        release_experiment_multi_prerender_probability +
        release_experiment_5min_ttl_probability +
        release_experiment_no_use_probability == divisor,
        release_experiment_probabilities_must_equal_divisor);

    control_probability = release_experiment_5min_ttl_probability;
    experiment_multi_prerender_probability =
        release_experiment_multi_prerender_probability;
    experiment_5min_ttl_probability = release_control_probability;
    experiment_no_use_probability = release_experiment_no_use_probability;
  } else {
    // In testing channels, use more experiments and a larger control group to
    // improve quality of data.
    const FieldTrial::Probability dev_prerender_enabled_probability = 250;
    const FieldTrial::Probability dev_control_probability = 250;
    const FieldTrial::Probability
        dev_experiment_multi_prerender_probability = 250;
    const FieldTrial::Probability dev_experiment_5min_ttl_probability = 125;
    const FieldTrial::Probability dev_experiment_no_use_probability = 125;
    COMPILE_ASSERT(dev_prerender_enabled_probability + dev_control_probability +
                   dev_experiment_multi_prerender_probability +
                   dev_experiment_5min_ttl_probability +
                   dev_experiment_no_use_probability == divisor,
                   dev_experiment_probabilities_must_equal_divisor);

    control_probability = dev_experiment_5min_ttl_probability;
    experiment_multi_prerender_probability =
        dev_experiment_multi_prerender_probability;
    experiment_5min_ttl_probability = dev_control_probability;
    experiment_no_use_probability = dev_experiment_no_use_probability;
  }

  int prerender_enabled_group = -1;
  scoped_refptr<FieldTrial> trial(
      FieldTrialList::FactoryGetFieldTrial(
          "Prerender", divisor, "PrerenderEnabled",
          2013, 6, 30, &prerender_enabled_group));
  const int control_group =
      trial->AppendGroup("PrerenderControl",
                         control_probability);
  const int experiment_multi_prerender_group =
      trial->AppendGroup("PrerenderMulti",
                         experiment_multi_prerender_probability);
  const int experiment_5_min_TTL_group =
      trial->AppendGroup("Prerender5minTTL",
                         experiment_5min_ttl_probability);
  const int experiment_no_use_group =
      trial->AppendGroup("PrerenderNoUse",
                         experiment_no_use_probability);

  const int trial_group = trial->group();
  if (trial_group == prerender_enabled_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP);
  } else if (trial_group == control_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
  } else if (trial_group == experiment_multi_prerender_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP);
  } else if (trial_group == experiment_5_min_TTL_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP);
  } else if (trial_group == experiment_no_use_group) {
    PrerenderManager::SetMode(
        PrerenderManager::PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP);
  } else {
    NOTREACHED();
  }
}

}  // end namespace

void ConfigureOmniboxPrerender();
void ConfigureSpeculativePrefetching();

void ConfigurePrefetchAndPrerender(const CommandLine& command_line) {
  enum PrerenderOption {
    PRERENDER_OPTION_AUTO,
    PRERENDER_OPTION_DISABLED,
    PRERENDER_OPTION_ENABLED,
    PRERENDER_OPTION_PREFETCH_ONLY,
  };

  PrerenderOption prerender_option = PRERENDER_OPTION_AUTO;
  if (command_line.HasSwitch(switches::kPrerenderMode)) {
    const std::string switch_value =
        command_line.GetSwitchValueASCII(switches::kPrerenderMode);

    if (switch_value == switches::kPrerenderModeSwitchValueAuto) {
      prerender_option = PRERENDER_OPTION_AUTO;
    } else if (switch_value == switches::kPrerenderModeSwitchValueDisabled) {
      prerender_option = PRERENDER_OPTION_DISABLED;
    } else if (switch_value.empty() ||
               switch_value == switches::kPrerenderModeSwitchValueEnabled) {
      // The empty string means the option was provided with no value, and that
      // means enable.
      prerender_option = PRERENDER_OPTION_ENABLED;
    } else if (switch_value ==
               switches::kPrerenderModeSwitchValuePrefetchOnly) {
      prerender_option = PRERENDER_OPTION_PREFETCH_ONLY;
    } else {
      prerender_option = PRERENDER_OPTION_DISABLED;
      LOG(ERROR) << "Invalid --prerender option received on command line: "
                 << switch_value;
      LOG(ERROR) << "Disabling prerendering!";
    }
  }

  switch (prerender_option) {
    case PRERENDER_OPTION_AUTO:
      SetupPrefetchFieldTrial();
      SetupPrerenderFieldTrial();
      break;
    case PRERENDER_OPTION_DISABLED:
      PrerenderManager::SetIsPrefetchEnabled(false);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    case PRERENDER_OPTION_ENABLED:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_ENABLED);
      break;
    case PRERENDER_OPTION_PREFETCH_ONLY:
      PrerenderManager::SetIsPrefetchEnabled(true);
      PrerenderManager::SetMode(PrerenderManager::PRERENDER_MODE_DISABLED);
      break;
    default:
      NOTREACHED();
  }

  UMA_HISTOGRAM_ENUMERATION("Prerender.Sessions",
                            PrerenderManager::GetMode(),
                            PrerenderManager::PRERENDER_MODE_MAX);

  ConfigureOmniboxPrerender();
  ConfigureSpeculativePrefetching();
}

void ConfigureOmniboxPrerender() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 10;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 1;
  }
  scoped_refptr<FieldTrial> omnibox_prerender_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kOmniboxTrialName, kDivisor, "OmniboxPrerenderEnabled",
          2012, 12, 30, &g_omnibox_trial_default_group_number));
  omnibox_prerender_trial->AppendGroup("OmniboxPrerenderDisabled",
                                       kDisabledProbability);
}

bool IsOmniboxEnabled(Profile* profile) {
  if (!profile)
    return false;

  if (!PrerenderManager::IsPrerenderingPossible())
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kPrerenderFromOmnibox)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kPrerenderFromOmnibox);

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueEnabled)
      return true;

    if (switch_value == switches::kPrerenderFromOmniboxSwitchValueDisabled)
      return false;

    DCHECK(switch_value == switches::kPrerenderFromOmniboxSwitchValueAuto);
  }

  const int group = FieldTrialList::FindValue(kOmniboxTrialName);
  return group == FieldTrial::kNotFinalized ||
         group == g_omnibox_trial_default_group_number;
}

void ConfigureSpeculativePrefetching() {
  // Field trial to see if we're enabled.
  const FieldTrial::Probability kDivisor = 100;

  FieldTrial::Probability kDisabledProbability = 10;
  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
  if (channel == chrome::VersionInfo::CHANNEL_STABLE ||
      channel == chrome::VersionInfo::CHANNEL_BETA) {
    kDisabledProbability = 100;
  }
  scoped_refptr<FieldTrial> speculative_prefetching_learning_trial(
      FieldTrialList::FactoryGetFieldTrial(
          kSpeculativePrefetchingLearningTrialName,
          kDivisor,
          "SpeculativePrefetchingLearningEnabled",
          2012, 12, 30,
          &g_speculative_prefetching_learning_default_group_number));
  speculative_prefetching_learning_trial->AppendGroup(
      "SpeculativePrefetchingDisabled",
      kDisabledProbability);
}

bool IsSpeculativeResourcePrefetchingLearningEnabled(Profile* profile) {
  if (!profile)
    return false;

  // Override any field trial groups if the user has set a command line flag.
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSpeculativeResourcePrefetching)) {
    const std::string switch_value =
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kSpeculativeResourcePrefetching);

    if (switch_value == switches::kSpeculativeResourcePrefetchingLearning)
      return true;
  }

  const int group = FieldTrialList::FindValue(
      kSpeculativePrefetchingLearningTrialName);
  return group == g_speculative_prefetching_learning_default_group_number;
}

}  // namespace prerender
<|endoftext|>


<commit_before><commit_msg>PWGPP-584,ATO-465: adding MC true event information vertex+event times<commit_after><|endoftext|>


<commit_before>/*
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>
    Copyright (C) 2009 Martin Sandsmark <sandsmark@samfundet.no>
    Copyright (C) 2011 Harald Sitter <sitter@kde.org>
    Copyright (C) 2011 Alessandro Siniscalchi <asiniscalchi@gmail.com>

    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) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "audiodataoutput.h"
#include "gsthelper.h"
#include "medianode.h"
#include <QtCore/QVector>
#include <QtCore/QMap>
#include <phonon/audiooutput.h>

#include <gst/gstghostpad.h>
#include <gst/gstutils.h>

QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace Gstreamer
{

AudioDataOutput::AudioDataOutput(Backend *backend, QObject *parent)
    : QObject(parent)
    , MediaNode(backend, AudioSink)
{
    static int count = 0;
    m_name = "AudioDataOutput" + QString::number(count++);

    m_queue = gst_bin_new(NULL);
    gst_object_ref(GST_OBJECT(m_queue));
    gst_object_sink(GST_OBJECT(m_queue));
    GstElement* sink = gst_element_factory_make("fakesink", NULL);
    GstElement* queue = gst_element_factory_make("queue", NULL);
    GstElement* convert = gst_element_factory_make("audioconvert", NULL);

    g_signal_connect(sink, "handoff", G_CALLBACK(processBuffer), this);
    g_object_set(G_OBJECT(sink), "signal-handoffs", true, NULL);

    //G_BYTE_ORDER is the host machine's endianess
    GstCaps *caps = gst_caps_new_simple("audio/x-raw-int",
                                        "endianess", G_TYPE_INT, G_BYTE_ORDER,
                                        "width", G_TYPE_INT, 16,
                                        "depth", G_TYPE_INT, 16,
                                        NULL);

    gst_bin_add_many(GST_BIN(m_queue), sink, convert, queue, NULL);
    gst_element_link(queue, convert);
    gst_element_link_filtered(convert, sink, caps);
    gst_caps_unref(caps);

    GstPad *inputpad = gst_element_get_static_pad(queue, "sink");
    gst_element_add_pad(m_queue, gst_ghost_pad_new("sink", inputpad));
    gst_object_unref(inputpad);

    g_object_set(G_OBJECT(sink), "sync", true, NULL);

    m_isValid = true;
}

AudioDataOutput::~AudioDataOutput()
{
    gst_element_set_state(m_queue, GST_STATE_NULL);
    gst_object_unref(m_queue);
}

void AudioDataOutput::setDataSize(int size)
{
    m_dataSize = size;
}

int AudioDataOutput::dataSize() const
{
    return m_dataSize;
}

int AudioDataOutput::sampleRate() const
{
    return 44100;
}

inline void AudioDataOutput::convertAndEmit()
{
    QMap<Phonon::AudioDataOutput::Channel, QVector<qint16> > map;

    for (int i = 0 ; i < m_channels ; ++i) {
        map.insert(static_cast<Phonon::AudioDataOutput::Channel>(i), m_channelBuffers[i]);
        Q_ASSERT(i == 0 || m_channelBuffers[i - 1].size() == m_channelBuffers[i].size());
    }

    emit dataReady(map);
}

void AudioDataOutput::processBuffer(GstElement*, GstBuffer* buffer, GstPad*, gpointer gThat)
{
    // TODO emit endOfMedia
    AudioDataOutput *that = static_cast<AudioDataOutput *>(gThat);

    // Copiend locally to avoid multithead problems
    qint32 dataSize = that->m_dataSize;
    if (dataSize == 0)
        return;

    // determine the number of channels
    GstStructure *structure = gst_caps_get_structure(GST_BUFFER_CAPS(buffer), 0);
    gst_structure_get_int(structure, "channels", &that->m_channels);

    // Let's get the buffers
    gint16 *gstBufferData = reinterpret_cast<gint16 *>(GST_BUFFER_DATA(buffer));
    guint gstBufferSize = GST_BUFFER_SIZE(buffer) / sizeof(gint16);

    if (gstBufferSize == 0) {
        qWarning() << Q_FUNC_INFO << ": received a buffer of 0 size ... doing nothing";
        return;
    }

    if ((gstBufferSize % that->m_channels) != 0) {
        qWarning() << Q_FUNC_INFO << ": corrupted data";
        return;
    }

    // I set the number of channels
    if (that->m_channelBuffers.size() != that->m_channels)
        that->m_channelBuffers.resize(that->m_channels);

    // check how many emits I will perform
    int nBlockToSend = (that->m_pendingData.size() + gstBufferSize) / (dataSize * that->m_channels);

    if (nBlockToSend == 0) { // add data to pending buffer
        for (quint32 i = 0; i < gstBufferSize ; ++i) {
#warning should be QBA, so we can work with append(buffer, size)
            that->m_pendingData.append(gstBufferData[i]);
        }
        return;
    }

    // SENDING DATA

    // 1) I empty the stored data
    if (that->m_pendingData.size() != 0) {
        for (int i = 0; i < that->m_pendingData.size(); i += that->m_channels) {
            for (int j = 0; j < that->m_channels; ++j) {
                that->m_channelBuffers[j].append(that->m_pendingData[i+j]);
            }
        }

        if (that->m_pendingData.capacity() != dataSize)
            that->m_pendingData.reserve(dataSize);

        that->m_pendingData.resize(0);
    }

    // 2) I fill with fresh data and send
    for (int i = 0 ; i < that->m_channels ; ++i)
    {
        if (that->m_channelBuffers[i].capacity() != dataSize)
            that->m_channelBuffers.reserve(dataSize);
    }

    quint32 bufferPosition = 0;
    for (int i = 0 ; i < nBlockToSend ; ++i) {
        for ( ; (that->m_channelBuffers[0].size() < dataSize) && (bufferPosition < gstBufferSize) ; bufferPosition += that->m_channels ) {
            for (int j = 0 ; j < that->m_channels ; ++j) {
                that->m_channelBuffers[j].append(gstBufferData[bufferPosition+j]);
            }
        }

        that->convertAndEmit();

        for (int j = 0 ; j < that->m_channels ; ++j) {
            // QVector::resize doesn't reallocate the buffer
            that->m_channelBuffers[j].resize(0);
        }
    }

    // 3) I store the rest of data
    while (bufferPosition < gstBufferSize) {
        that->m_pendingData.append(gstBufferData[bufferPosition]);
        ++bufferPosition;
    }
}

}} //namespace Phonon::Gstreamer

QT_END_NAMESPACE
QT_END_HEADER

#include "moc_audiodataoutput.cpp"
<commit_msg>asserts++<commit_after>/*
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>
    Copyright (C) 2009 Martin Sandsmark <sandsmark@samfundet.no>
    Copyright (C) 2011 Harald Sitter <sitter@kde.org>
    Copyright (C) 2011 Alessandro Siniscalchi <asiniscalchi@gmail.com>

    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) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    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, see <http://www.gnu.org/licenses/>.
*/

#include "audiodataoutput.h"
#include "gsthelper.h"
#include "medianode.h"
#include <QtCore/QVector>
#include <QtCore/QMap>
#include <phonon/audiooutput.h>

#include <gst/gstghostpad.h>
#include <gst/gstutils.h>

QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace Gstreamer
{

AudioDataOutput::AudioDataOutput(Backend *backend, QObject *parent)
    : QObject(parent)
    , MediaNode(backend, AudioSink)
{
    static int count = 0;
    m_name = "AudioDataOutput" + QString::number(count++);

    m_queue = gst_bin_new(NULL);
    gst_object_ref(GST_OBJECT(m_queue));
    gst_object_sink(GST_OBJECT(m_queue));
    GstElement* sink = gst_element_factory_make("fakesink", NULL);
    GstElement* queue = gst_element_factory_make("queue", NULL);
    GstElement* convert = gst_element_factory_make("audioconvert", NULL);

    g_signal_connect(sink, "handoff", G_CALLBACK(processBuffer), this);
    g_object_set(G_OBJECT(sink), "signal-handoffs", true, NULL);

    //G_BYTE_ORDER is the host machine's endianess
    GstCaps *caps = gst_caps_new_simple("audio/x-raw-int",
                                        "endianess", G_TYPE_INT, G_BYTE_ORDER,
                                        "width", G_TYPE_INT, 16,
                                        "depth", G_TYPE_INT, 16,
                                        NULL);

    gst_bin_add_many(GST_BIN(m_queue), sink, convert, queue, NULL);
    gst_element_link(queue, convert);
    gst_element_link_filtered(convert, sink, caps);
    gst_caps_unref(caps);

    GstPad *inputpad = gst_element_get_static_pad(queue, "sink");
    gst_element_add_pad(m_queue, gst_ghost_pad_new("sink", inputpad));
    gst_object_unref(inputpad);

    g_object_set(G_OBJECT(sink), "sync", true, NULL);

    m_isValid = true;
}

AudioDataOutput::~AudioDataOutput()
{
    gst_element_set_state(m_queue, GST_STATE_NULL);
    gst_object_unref(m_queue);
}

void AudioDataOutput::setDataSize(int size)
{
    m_dataSize = size;
}

int AudioDataOutput::dataSize() const
{
    return m_dataSize;
}

int AudioDataOutput::sampleRate() const
{
    return 44100;
}

inline void AudioDataOutput::convertAndEmit()
{
    QMap<Phonon::AudioDataOutput::Channel, QVector<qint16> > map;

    for (int i = 0 ; i < m_channels ; ++i) {
        map.insert(static_cast<Phonon::AudioDataOutput::Channel>(i), m_channelBuffers[i]);
        Q_ASSERT(i == 0 || m_channelBuffers[i - 1].size() == m_channelBuffers[i].size());
    }

    emit dataReady(map);
}

void AudioDataOutput::processBuffer(GstElement*, GstBuffer* buffer, GstPad*, gpointer gThat)
{
    // TODO emit endOfMedia
    AudioDataOutput *that = static_cast<AudioDataOutput *>(gThat);

    // Copiend locally to avoid multithead problems
    qint32 dataSize = that->m_dataSize;
    if (dataSize == 0)
        return;

    // determine the number of channels
    GstStructure *structure = gst_caps_get_structure(GST_BUFFER_CAPS(buffer), 0);
    gst_structure_get_int(structure, "channels", &that->m_channels);

    // Let's get the buffers
    gint16 *gstBufferData = reinterpret_cast<gint16 *>(GST_BUFFER_DATA(buffer));
    guint gstBufferSize = GST_BUFFER_SIZE(buffer) / sizeof(gint16);

    if (gstBufferSize == 0) {
        qWarning() << Q_FUNC_INFO << ": received a buffer of 0 size ... doing nothing";
        return;
    }

    if ((gstBufferSize % that->m_channels) != 0) {
        qWarning() << Q_FUNC_INFO << ": corrupted data";
        return;
    }

    // I set the number of channels
    if (that->m_channelBuffers.size() != that->m_channels)
        that->m_channelBuffers.resize(that->m_channels);

    // check how many emits I will perform
    int nBlockToSend = (that->m_pendingData.size() + gstBufferSize) / (dataSize * that->m_channels);

    if (nBlockToSend == 0) { // add data to pending buffer
        const int prevPendingSize = that->m_pendingData.size();
        for (quint32 i = 0; i < gstBufferSize ; ++i) {
#warning should be QBA, so we can work with append(buffer, size)
            that->m_pendingData.append(gstBufferData[i]);
        }
        Q_ASSERT(prevPendingSize + gstBufferSize == that->m_pendingData.size());
        return;
    }

    // SENDING DATA

    // 1) I empty the stored data
    if (that->m_pendingData.size() != 0) {
        // Since pendingData is a concatenation of buffers it must share its
        // attribute of being a multiple of channelCount
        Q_ASSERT((that->m_pendingData.size() % that->m_channels) == 0);
        for (int i = 0; i < that->m_pendingData.size(); i += that->m_channels) {
            for (int j = 0; j < that->m_channels; ++j) {
                that->m_channelBuffers[j].append(that->m_pendingData[i+j]);
            }
        }

        if (that->m_pendingData.capacity() != dataSize)
            that->m_pendingData.reserve(dataSize);

        that->m_pendingData.resize(0);
    }

    // 2) I fill with fresh data and send
    for (int i = 0 ; i < that->m_channels ; ++i)
    {
        if (that->m_channelBuffers[i].capacity() != dataSize)
            that->m_channelBuffers.reserve(dataSize);
    }

    quint32 bufferPosition = 0;
    for (int i = 0 ; i < nBlockToSend ; ++i) {
        for ( ; (that->m_channelBuffers[0].size() < dataSize) && (bufferPosition < gstBufferSize) ; bufferPosition += that->m_channels ) {
            for (int j = 0 ; j < that->m_channels ; ++j) {
                that->m_channelBuffers[j].append(gstBufferData[bufferPosition+j]);
            }
        }

        that->convertAndEmit();

        for (int j = 0 ; j < that->m_channels ; ++j) {
            // QVector::resize doesn't reallocate the buffer
            that->m_channelBuffers[j].resize(0);
        }
    }

    // 3) I store the rest of data
    while (bufferPosition < gstBufferSize) {
        that->m_pendingData.append(gstBufferData[bufferPosition]);
        ++bufferPosition;
    }
}

}} //namespace Phonon::Gstreamer

QT_END_NAMESPACE
QT_END_HEADER

#include "moc_audiodataoutput.cpp"
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XMLIndexTOCContext.cxx,v $
 * $Revision: 1.18 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include "XMLIndexTOCContext.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/text/XTextContent.hpp>
#include <com/sun/star/text/XTextSection.hpp>
#include <com/sun/star/text/XRelativeTextContentInsert.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include "XMLIndexTOCSourceContext.hxx"
#include "XMLIndexObjectSourceContext.hxx"
#include "XMLIndexAlphabeticalSourceContext.hxx"
#include "XMLIndexUserSourceContext.hxx"
#include "XMLIndexBibliographySourceContext.hxx"
#include "XMLIndexTableSourceContext.hxx"
#include "XMLIndexIllustrationSourceContext.hxx"
#include "XMLIndexBodyContext.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmlnmspe.hxx"
#include "xmlkywd.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/prstylei.hxx>
#include "xmlerror.hxx"
#include <xmloff/xmluconv.hxx>
#include <tools/debug.hxx>
#include <rtl/ustring.hxx>
#include <tools/debug.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::lang::IllegalArgumentException;

TYPEINIT1(XMLIndexTOCContext, SvXMLImportContext);

static const sal_Char* aIndexServiceMap[] =
{
    "com.sun.star.text.ContentIndex",
    "com.sun.star.text.DocumentIndex",
    "com.sun.star.text.TableIndex",
    "com.sun.star.text.ObjectIndex",
    "com.sun.star.text.Bibliography",
    "com.sun.star.text.UserIndex",
    "com.sun.star.text.IllustrationsIndex"
};

static const sal_Char* aIndexSourceElementMap[] =
{
    sXML_table_of_content_source,
    sXML_alphabetical_index_source,
    sXML_table_index_source,
    sXML_object_index_source,
    sXML_bibliography_source,
    sXML_user_index_source,
    sXML_illustration_index_source
};

SvXMLEnumMapEntry __READONLY_DATA aIndexTypeMap[] =
{
    { XML_TABLE_OF_CONTENT,     TEXT_INDEX_TOC },
    { XML_ALPHABETICAL_INDEX,   TEXT_INDEX_ALPHABETICAL },
    { XML_TABLE_INDEX,          TEXT_INDEX_TABLE },
    { XML_OBJECT_INDEX,         TEXT_INDEX_OBJECT },
    { XML_BIBLIOGRAPHY,         TEXT_INDEX_BIBLIOGRAPHY },
    { XML_USER_INDEX,           TEXT_INDEX_USER },
    { XML_ILLUSTRATION_INDEX,   TEXT_INDEX_ILLUSTRATION },
    { XML_TOKEN_INVALID,        0 }
};

XMLIndexTOCContext::XMLIndexTOCContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrfx,
    const OUString& rLocalName )
:   SvXMLImportContext(rImport, nPrfx, rLocalName)
,   sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
,   sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
,   sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
,   pSourceElementName(NULL)
,   bValid(sal_False)
{
    if (XML_NAMESPACE_TEXT == nPrfx)
    {
        sal_uInt16 nTmp;
        if (SvXMLUnitConverter::convertEnum(nTmp, rLocalName, aIndexTypeMap))
        {
            // check for array index:
            DBG_ASSERT(nTmp < (sizeof(aIndexServiceMap)/sizeof(sal_Char*)), "index out of range");
            DBG_ASSERT(sizeof(aIndexServiceMap) ==
                       sizeof(aIndexSourceElementMap),
                       "service and source element maps must be same size");

            eIndexType = (enum IndexTypeEnum)nTmp;
            pSourceElementName = aIndexSourceElementMap[eIndexType];
            bValid = sal_True;
        }
    }
}

XMLIndexTOCContext::~XMLIndexTOCContext()
{
}

void XMLIndexTOCContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    if (bValid)
    {
        // create table of content (via MultiServiceFactory)
        Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
                                                 UNO_QUERY);
        if( xFactory.is() )
        {
            Reference<XInterface> xIfc =
                xFactory->createInstance(
                    OUString::createFromAscii(aIndexServiceMap[eIndexType]));
            if( xIfc.is() )
            {
                // get Property set
                Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
                xTOCPropertySet = xPropSet;

                // insert section
                // a) insert section
                //    The inserted index consists of an empty paragraph
                //    only, as well as an empty paragraph *after* the index
                // b) insert marker after index, and put Cursor inside of the
                //    index

                // preliminaries
#ifdef PRODUCT
                OUString sMarker(RTL_CONSTASCII_USTRINGPARAM(" "));
#else
                OUString sMarker(RTL_CONSTASCII_USTRINGPARAM("Y"));
#endif
                UniReference<XMLTextImportHelper> rImport =
                    GetImport().GetTextImport();

                // a) insert index
                Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
                try
                {
                    GetImport().GetTextImport()->InsertTextContent(
                        xTextContent);
                }
                catch( IllegalArgumentException e )
                {
                    // illegal argument? Then we can't accept indices here!
                    Sequence<OUString> aSeq(1);
                    aSeq[0] = GetLocalName();
                    GetImport().SetError(
                        XMLERROR_FLAG_ERROR | XMLERROR_NO_INDEX_ALLOWED_HERE,
                        aSeq, e.Message, NULL );

                    // set bValid to false, and return prematurely
                    bValid = false;
                    return;
                }

                // b) insert marker and move cursor
                rImport->InsertString(sMarker);
                rImport->GetCursor()->goLeft(2, sal_False);
            }
        }

        // finally, check for redlines that should start at
        // the section start node
        if( bValid )
            GetImport().GetTextImport()->
                RedlineAdjustStartNodeCursor(sal_True);

        // find text:style-name attribute and set section style
        // find text:protected and set value
        // find text:name and set value (if not empty)
        sal_Int16 nCount = xAttrList->getLength();
        sal_Bool bProtected = sal_False;
        OUString sIndexName;
        for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
        {
            OUString sLocalName;
            sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
                GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
                                  &sLocalName );
            if ( XML_NAMESPACE_TEXT == nPrefix)
            {
                if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
                {
                    XMLPropStyleContext* pStyle =
                        GetImport().GetTextImport()->FindSectionStyle(
                                xAttrList->getValueByIndex(nAttr));
                    if (pStyle != NULL)
                    {
                        pStyle->FillPropertySet( xTOCPropertySet );
                    }
                }
                else if ( IsXMLToken( sLocalName, XML_PROTECTED ) )
                {
                    sal_Bool bTmp;
                    if ( SvXMLUnitConverter::convertBool(
                         bTmp, xAttrList->getValueByIndex(nAttr) ) )
                    {
                        bProtected = bTmp;
                    }
                }
                else if ( IsXMLToken( sLocalName, XML_NAME ) )
                {
                    sIndexName = xAttrList->getValueByIndex(nAttr);
                }
            }
        }
        Any aAny;
        aAny.setValue( &bProtected, ::getBooleanCppuType() );
        xTOCPropertySet->setPropertyValue( sIsProtected, aAny );

        if (sIndexName.getLength() > 0)
        {
            aAny <<= sIndexName;
            xTOCPropertySet->setPropertyValue( sName, aAny );
        }
    }
}

void XMLIndexTOCContext::EndElement()
{
    // complete import of index by removing the markers (if the index
    // was actually inserted, that is)
    if( bValid )
    {
        // preliminaries
        OUString sEmpty;
        UniReference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();

        // get rid of last paragraph (unless it's the only paragraph)
        rHelper->GetCursor()->goRight(1, sal_False);
        if( xBodyContextRef.Is() &&
            ((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
        {
            rHelper->GetCursor()->goLeft(1, sal_True);
            rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
                                             sEmpty, sal_True);
        }

        // and delete second marker
        rHelper->GetCursor()->goRight(1, sal_True);
        rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
                                         sEmpty, sal_True);

        // check for Redlines on our end node
        GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False);
    }
}

SvXMLImportContext* XMLIndexTOCContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList )
{
    SvXMLImportContext* pContext = NULL;

    if (bValid)
    {
        if (XML_NAMESPACE_TEXT == nPrefix)
        {
            if ( IsXMLToken( rLocalName, XML_INDEX_BODY ) )
            {
                pContext = new XMLIndexBodyContext(GetImport(), nPrefix,
                                                   rLocalName);
                if ( !xBodyContextRef.Is() ||
                     !((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
                {
                    xBodyContextRef = pContext;
                }
            }
            else if (0 == rLocalName.compareToAscii(pSourceElementName))
            {
                // instantiate source context for the appropriate index type
                switch (eIndexType)
                {
                    case TEXT_INDEX_TOC:
                        pContext = new XMLIndexTOCSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_OBJECT:
                        pContext = new XMLIndexObjectSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_ALPHABETICAL:
                        pContext = new XMLIndexAlphabeticalSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_USER:
                        pContext = new XMLIndexUserSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_BIBLIOGRAPHY:
                        pContext = new XMLIndexBibliographySourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_TABLE:
                        pContext = new XMLIndexTableSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_ILLUSTRATION:
                        pContext = new XMLIndexIllustrationSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    default:
                        DBG_ERROR("index type not implemented");
                        break;
                }
            }
            // else: ignore
        }
        // else: no text: namespace -> ignore
    }
    // else: not valid -> ignore

    // default: ignore
    if (pContext == NULL)
    {
        pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
                                                          xAttrList);
    }

    return pContext;
}
<commit_msg>INTEGRATION: CWS odfmetadata (1.18.50); FILE MERGED 2008/06/19 17:06:56 mst 1.18.50.1: #i90620#: import xml:id in text elements - xmloff/source/text/XMLIndexTOCContext.cxx:   + XMLIndexTOCContext::StartElement():  attribute xml:id - xmloff/source/text/XMLSectionImportContext{.hxx,.cxx}:   + XMLSectionToken: new token: XML_TOK_SECTION_XMLID   + XMLSectionImportContext::ProcessAttributes():  attribute xml:id - xmloff/source/text/XMLTextListBlockContext{.hxx,.cxx}:   + XMLTextListBlockContext::XMLTextListBlockContext():  attribute xml:id - xmloff/source/text/XMLTextListItemContext.cxx:   + XMLTextListItemContext::XMLTextListItemContext():  attribute xml:id - xmloff/source/text/XMLTextMarkImportContext{.hxx,.cxx}:   + refactor methods to pass XmlId around   + XMLTextMarkImportContext::FindName():  attribute xml:id - xmloff/source/text/txtparai{.hxx,.cxx}:   + new class XMLMetaImportContext   + XMLImpSpanContext_Impl::CreateChildContext():     handle TEXT_META and (provisionally) TEXT_META_FIELD   + XMLParaContext::XMLParaContext():  attribute xml:id<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XMLIndexTOCContext.cxx,v $
 * $Revision: 1.19 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include "XMLIndexTOCContext.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/text/XTextContent.hpp>
#include <com/sun/star/text/XTextSection.hpp>
#include <com/sun/star/text/XRelativeTextContentInsert.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include "XMLIndexTOCSourceContext.hxx"
#include "XMLIndexObjectSourceContext.hxx"
#include "XMLIndexAlphabeticalSourceContext.hxx"
#include "XMLIndexUserSourceContext.hxx"
#include "XMLIndexBibliographySourceContext.hxx"
#include "XMLIndexTableSourceContext.hxx"
#include "XMLIndexIllustrationSourceContext.hxx"
#include "XMLIndexBodyContext.hxx"
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmlnmspe.hxx"
#include "xmlkywd.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/prstylei.hxx>
#include "xmlerror.hxx"
#include <xmloff/xmluconv.hxx>
#include <tools/debug.hxx>
#include <rtl/ustring.hxx>
#include <tools/debug.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

using ::rtl::OUString;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::lang::IllegalArgumentException;

TYPEINIT1(XMLIndexTOCContext, SvXMLImportContext);

static const sal_Char* aIndexServiceMap[] =
{
    "com.sun.star.text.ContentIndex",
    "com.sun.star.text.DocumentIndex",
    "com.sun.star.text.TableIndex",
    "com.sun.star.text.ObjectIndex",
    "com.sun.star.text.Bibliography",
    "com.sun.star.text.UserIndex",
    "com.sun.star.text.IllustrationsIndex"
};

static const sal_Char* aIndexSourceElementMap[] =
{
    sXML_table_of_content_source,
    sXML_alphabetical_index_source,
    sXML_table_index_source,
    sXML_object_index_source,
    sXML_bibliography_source,
    sXML_user_index_source,
    sXML_illustration_index_source
};

SvXMLEnumMapEntry __READONLY_DATA aIndexTypeMap[] =
{
    { XML_TABLE_OF_CONTENT,     TEXT_INDEX_TOC },
    { XML_ALPHABETICAL_INDEX,   TEXT_INDEX_ALPHABETICAL },
    { XML_TABLE_INDEX,          TEXT_INDEX_TABLE },
    { XML_OBJECT_INDEX,         TEXT_INDEX_OBJECT },
    { XML_BIBLIOGRAPHY,         TEXT_INDEX_BIBLIOGRAPHY },
    { XML_USER_INDEX,           TEXT_INDEX_USER },
    { XML_ILLUSTRATION_INDEX,   TEXT_INDEX_ILLUSTRATION },
    { XML_TOKEN_INVALID,        0 }
};

XMLIndexTOCContext::XMLIndexTOCContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrfx,
    const OUString& rLocalName )
:   SvXMLImportContext(rImport, nPrfx, rLocalName)
,   sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
,   sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
,   sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
,   pSourceElementName(NULL)
,   bValid(sal_False)
{
    if (XML_NAMESPACE_TEXT == nPrfx)
    {
        sal_uInt16 nTmp;
        if (SvXMLUnitConverter::convertEnum(nTmp, rLocalName, aIndexTypeMap))
        {
            // check for array index:
            DBG_ASSERT(nTmp < (sizeof(aIndexServiceMap)/sizeof(sal_Char*)), "index out of range");
            DBG_ASSERT(sizeof(aIndexServiceMap) ==
                       sizeof(aIndexSourceElementMap),
                       "service and source element maps must be same size");

            eIndexType = (enum IndexTypeEnum)nTmp;
            pSourceElementName = aIndexSourceElementMap[eIndexType];
            bValid = sal_True;
        }
    }
}

XMLIndexTOCContext::~XMLIndexTOCContext()
{
}

void XMLIndexTOCContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    if (bValid)
    {
        // find text:style-name attribute and set section style
        // find text:protected and set value
        // find text:name and set value (if not empty)
        sal_Int16 nCount = xAttrList->getLength();
        sal_Bool bProtected = sal_False;
        OUString sIndexName;
        OUString sXmlId;
        XMLPropStyleContext* pStyle(NULL);
        for(sal_Int16 nAttr = 0; nAttr < nCount; nAttr++)
        {
            OUString sLocalName;
            sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
                GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
                                  &sLocalName );
            if ( XML_NAMESPACE_TEXT == nPrefix)
            {
                if ( IsXMLToken( sLocalName, XML_STYLE_NAME ) )
                {
                    pStyle = GetImport().GetTextImport()->FindSectionStyle(
                                xAttrList->getValueByIndex(nAttr));
                }
                else if ( IsXMLToken( sLocalName, XML_PROTECTED ) )
                {
                    sal_Bool bTmp;
                    if ( SvXMLUnitConverter::convertBool(
                         bTmp, xAttrList->getValueByIndex(nAttr) ) )
                    {
                        bProtected = bTmp;
                    }
                }
                else if ( IsXMLToken( sLocalName, XML_NAME ) )
                {
                    sIndexName = xAttrList->getValueByIndex(nAttr);
                }
            }
            else if ( XML_NAMESPACE_XML == nPrefix)
            {
                if ( IsXMLToken( sLocalName, XML_ID ) )
                {
                    sXmlId = xAttrList->getValueByIndex(nAttr);
                }
            }
        }

        // create table of content (via MultiServiceFactory)
        Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),
                                                 UNO_QUERY);
        if( xFactory.is() )
        {
            Reference<XInterface> xIfc =
                xFactory->createInstance(
                    OUString::createFromAscii(aIndexServiceMap[eIndexType]));
            if( xIfc.is() )
            {

                // xml:id for RDF metadata
                GetImport().SetXmlId(xIfc, sXmlId);

                // get Property set
                Reference<XPropertySet> xPropSet(xIfc, UNO_QUERY);
                xTOCPropertySet = xPropSet;

                // insert section
                // a) insert section
                //    The inserted index consists of an empty paragraph
                //    only, as well as an empty paragraph *after* the index
                // b) insert marker after index, and put Cursor inside of the
                //    index

                // preliminaries
#ifdef PRODUCT
                OUString sMarker(RTL_CONSTASCII_USTRINGPARAM(" "));
#else
                OUString sMarker(RTL_CONSTASCII_USTRINGPARAM("Y"));
#endif
                UniReference<XMLTextImportHelper> rImport =
                    GetImport().GetTextImport();

                // a) insert index
                Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
                try
                {
                    GetImport().GetTextImport()->InsertTextContent(
                        xTextContent);
                }
                catch( IllegalArgumentException e )
                {
                    // illegal argument? Then we can't accept indices here!
                    Sequence<OUString> aSeq(1);
                    aSeq[0] = GetLocalName();
                    GetImport().SetError(
                        XMLERROR_FLAG_ERROR | XMLERROR_NO_INDEX_ALLOWED_HERE,
                        aSeq, e.Message, NULL );

                    // set bValid to false, and return prematurely
                    bValid = false;
                    return;
                }

                // b) insert marker and move cursor
                rImport->InsertString(sMarker);
                rImport->GetCursor()->goLeft(2, sal_False);
            }
        }

        // finally, check for redlines that should start at
        // the section start node
        if( bValid )
            GetImport().GetTextImport()->
                RedlineAdjustStartNodeCursor(sal_True);

        if (pStyle != NULL)
        {
            pStyle->FillPropertySet( xTOCPropertySet );
        }

        Any aAny;
        aAny.setValue( &bProtected, ::getBooleanCppuType() );
        xTOCPropertySet->setPropertyValue( sIsProtected, aAny );

        if (sIndexName.getLength() > 0)
        {
            aAny <<= sIndexName;
            xTOCPropertySet->setPropertyValue( sName, aAny );
        }
    }
}

void XMLIndexTOCContext::EndElement()
{
    // complete import of index by removing the markers (if the index
    // was actually inserted, that is)
    if( bValid )
    {
        // preliminaries
        OUString sEmpty;
        UniReference<XMLTextImportHelper> rHelper= GetImport().GetTextImport();

        // get rid of last paragraph (unless it's the only paragraph)
        rHelper->GetCursor()->goRight(1, sal_False);
        if( xBodyContextRef.Is() &&
            ((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
        {
            rHelper->GetCursor()->goLeft(1, sal_True);
            rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
                                             sEmpty, sal_True);
        }

        // and delete second marker
        rHelper->GetCursor()->goRight(1, sal_True);
        rHelper->GetText()->insertString(rHelper->GetCursorAsRange(),
                                         sEmpty, sal_True);

        // check for Redlines on our end node
        GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False);
    }
}

SvXMLImportContext* XMLIndexTOCContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList )
{
    SvXMLImportContext* pContext = NULL;

    if (bValid)
    {
        if (XML_NAMESPACE_TEXT == nPrefix)
        {
            if ( IsXMLToken( rLocalName, XML_INDEX_BODY ) )
            {
                pContext = new XMLIndexBodyContext(GetImport(), nPrefix,
                                                   rLocalName);
                if ( !xBodyContextRef.Is() ||
                     !((XMLIndexBodyContext*)&xBodyContextRef)->HasContent() )
                {
                    xBodyContextRef = pContext;
                }
            }
            else if (0 == rLocalName.compareToAscii(pSourceElementName))
            {
                // instantiate source context for the appropriate index type
                switch (eIndexType)
                {
                    case TEXT_INDEX_TOC:
                        pContext = new XMLIndexTOCSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_OBJECT:
                        pContext = new XMLIndexObjectSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_ALPHABETICAL:
                        pContext = new XMLIndexAlphabeticalSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_USER:
                        pContext = new XMLIndexUserSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_BIBLIOGRAPHY:
                        pContext = new XMLIndexBibliographySourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_TABLE:
                        pContext = new XMLIndexTableSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    case TEXT_INDEX_ILLUSTRATION:
                        pContext = new XMLIndexIllustrationSourceContext(
                            GetImport(), nPrefix, rLocalName, xTOCPropertySet);
                        break;

                    default:
                        DBG_ERROR("index type not implemented");
                        break;
                }
            }
            // else: ignore
        }
        // else: no text: namespace -> ignore
    }
    // else: not valid -> ignore

    // default: ignore
    if (pContext == NULL)
    {
        pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
                                                          xAttrList);
    }

    return pContext;
}
<|endoftext|>


<commit_before>/// \file rootqt5.cpp
/// \ingroup CanvasPainter ROOT7
/// \author Sergey Linev <S.Linev@gsi.de>
/// \date 2017-06-29
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <QApplication>
#include <QWebEngineView>
#include <qtwebengineglobal.h>
#include <QThread>
#include <QWebEngineSettings>
#include <QWebEngineProfile>

#include "TROOT.h"
#include "TApplication.h"
#include "TRint.h"
#include "TTimer.h"
#include "TThread.h"
#include "THttpServer.h"

#include "rootwebview.h"
#include "rootwebpage.h"
#include "rooturlschemehandler.h"

#include <memory>

#include <ROOT/RWebDisplayHandle.hxx>
#include <ROOT/RMakeUnique.hxx>
#include <ROOT/TLogger.hxx>

#include <stdio.h>

class TQt5Timer : public TTimer {
public:
   TQt5Timer(Long_t milliSec, Bool_t mode) : TTimer(milliSec, mode) {}
   virtual void Timeout()
   {
      // timeout handler
      // used to process all qt5 events in main ROOT thread
      QApplication::sendPostedEvents();
      QApplication::processEvents();
   }
};

namespace ROOT {
namespace Experimental {

class RQt5WebDisplayHandle : public RWebDisplayHandle {
protected:
   class Qt5Creator : public Creator {
      int fCounter{0}; ///< counter used to number handlers
      QApplication *qapp{nullptr};  ///< created QApplication
      int qargc{1};                 ///< arg counter
      char *qargv[10];              ///< arg values
      bool fInitEngine{false};      ///< does engine was initialized
      TQt5Timer *fTimer{nullptr};   ///< timer to process ROOT events
   public:

      Qt5Creator() = default;

      std::unique_ptr<RWebDisplayHandle> Display(const RWebDisplayArgs &args) override
      {
         if (args.IsHeadless())
            return nullptr;

         if (!qapp && !QApplication::instance()) {

            if (!gApplication) {
               R__ERROR_HERE("Qt5") << "NOT FOUND gApplication to create QApplication";
               return nullptr;
            }

            qargv[0] = gApplication->Argv(0);
            qargv[1] = nullptr;
            qapp = new QApplication(qargc, qargv);
         }

         if (!fInitEngine) {
            QtWebEngine::initialize();
            fInitEngine = true;
         }

         if (!fTimer) {
            fTimer = new TQt5Timer(10, kTRUE);
            fTimer->TurnOn();
         }

         std::unique_ptr<RootUrlSchemeHandler> handler;
         QString fullurl = QString(args.GetUrl().c_str());

         // if no server provided - normal HTTP will be allowed to use
         if (args.GetHttpServer()) {
            handler = std::make_unique<RootUrlSchemeHandler>(args.GetHttpServer(), fCounter++);
            fullurl = handler->MakeFullUrl(fullurl);
         }

         QWidget *qparent = (QWidget *) args.GetDriverData();

         if (!args.GetUrlOpt().empty()) {
            fullurl.append(QString("&"));
            fullurl.append(QString(args.GetUrlOpt().c_str()));
         }

         auto handle = std::make_unique<RQt5WebDisplayHandle>(fullurl.toLatin1().constData(), handler);

         if (args.IsHeadless()) {
            RootWebPage *page = new RootWebPage();
            page->settings()->resetAttribute(QWebEngineSettings::WebGLEnabled);
            page->settings()->resetAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled);
            page->settings()->resetAttribute(QWebEngineSettings::PluginsEnabled);
            page->load(QUrl(fullurl));
         } else {
            RootWebView *view = new RootWebView(qparent, args.GetWidth(), args.GetHeight());
            view->load(QUrl(fullurl));
            view->show();
         }

         return handle;
      }

      virtual ~Qt5Creator()
      {
         if (fTimer) {
            fTimer->TurnOff();
            delete fTimer;
         }

      }
   };

   std::unique_ptr<RootUrlSchemeHandler> fHandler;

public:
   RQt5WebDisplayHandle(const std::string &url, std::unique_ptr<RootUrlSchemeHandler> &handler)
      : RWebDisplayHandle(url)
   {
      std::swap(fHandler, handler);
      if (fHandler)
         QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(QByteArray(fHandler->GetProtocol()), fHandler.get());
   }

   static void AddCreator()
   {
      auto &entry = FindCreator("qt5");
      if (!entry)
         GetMap().emplace("qt5", std::make_unique<Qt5Creator>());
   }

   virtual ~RQt5WebDisplayHandle()
   {
      if (fHandler)
         QWebEngineProfile::defaultProfile()->removeUrlSchemeHandler(fHandler.get());
   }
};

struct RQt5CreatorReg {
   RQt5CreatorReg() { RQt5WebDisplayHandle::AddCreator(); }
} newRQt5CreatorReg;

}
}
<commit_msg>webgui: increase frequency of timer for running qt5 events<commit_after>/// \file rootqt5.cpp
/// \ingroup CanvasPainter ROOT7
/// \author Sergey Linev <S.Linev@gsi.de>
/// \date 2017-06-29
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <QApplication>
#include <QWebEngineView>
#include <qtwebengineglobal.h>
#include <QThread>
#include <QWebEngineSettings>
#include <QWebEngineProfile>

#include "TROOT.h"
#include "TApplication.h"
#include "TTimer.h"
#include "TEnv.h"
#include "TThread.h"
#include "THttpServer.h"

#include "rootwebview.h"
#include "rootwebpage.h"
#include "rooturlschemehandler.h"

#include <memory>

#include <ROOT/RWebDisplayHandle.hxx>
#include <ROOT/RMakeUnique.hxx>
#include <ROOT/TLogger.hxx>

class TQt5Timer : public TTimer {
public:
   TQt5Timer(Long_t milliSec, Bool_t mode) : TTimer(milliSec, mode) {}
   virtual void Timeout()
   {
      // timeout handler
      // used to process all qt5 events in main ROOT thread
      QApplication::sendPostedEvents();
      QApplication::processEvents();
   }
};

namespace ROOT {
namespace Experimental {

class RQt5WebDisplayHandle : public RWebDisplayHandle {
protected:
   class Qt5Creator : public Creator {
      int fCounter{0}; ///< counter used to number handlers
      QApplication *qapp{nullptr};  ///< created QApplication
      int qargc{1};                 ///< arg counter
      char *qargv[10];              ///< arg values
      bool fInitEngine{false};      ///< does engine was initialized
      TQt5Timer *fTimer{nullptr};   ///< timer to process ROOT events
   public:

      Qt5Creator() = default;

      std::unique_ptr<RWebDisplayHandle> Display(const RWebDisplayArgs &args) override
      {
         if (args.IsHeadless())
            return nullptr;

         if (!qapp && !QApplication::instance()) {

            if (!gApplication) {
               R__ERROR_HERE("Qt5") << "NOT FOUND gApplication to create QApplication";
               return nullptr;
            }

            qargv[0] = gApplication->Argv(0);
            qargv[1] = nullptr;
            qapp = new QApplication(qargc, qargv);
         }

         if (!fInitEngine) {
            QtWebEngine::initialize();
            fInitEngine = true;
         }

         if (!fTimer) {
            Int_t interval = gEnv->GetValue("WebGui.Qt5Timer", 1);
            if (interval > 0) {
               fTimer = new TQt5Timer(interval, kTRUE);
               fTimer->TurnOn();
            }
         }

         std::unique_ptr<RootUrlSchemeHandler> handler;
         QString fullurl = QString(args.GetUrl().c_str());

         // if no server provided - normal HTTP will be allowed to use
         if (args.GetHttpServer()) {
            handler = std::make_unique<RootUrlSchemeHandler>(args.GetHttpServer(), fCounter++);
            fullurl = handler->MakeFullUrl(fullurl);
         }

         QWidget *qparent = (QWidget *) args.GetDriverData();

         if (!args.GetUrlOpt().empty()) {
            fullurl.append(QString("&"));
            fullurl.append(QString(args.GetUrlOpt().c_str()));
         }

         auto handle = std::make_unique<RQt5WebDisplayHandle>(fullurl.toLatin1().constData(), handler);

         if (args.IsHeadless()) {
            RootWebPage *page = new RootWebPage();
            page->settings()->resetAttribute(QWebEngineSettings::WebGLEnabled);
            page->settings()->resetAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled);
            page->settings()->resetAttribute(QWebEngineSettings::PluginsEnabled);
            page->load(QUrl(fullurl));
         } else {
            RootWebView *view = new RootWebView(qparent, args.GetWidth(), args.GetHeight());
            view->load(QUrl(fullurl));
            view->show();
         }

         return handle;
      }

      virtual ~Qt5Creator()
      {
         if (fTimer) {
            fTimer->TurnOff();
            delete fTimer;
         }

      }
   };

   std::unique_ptr<RootUrlSchemeHandler> fHandler;

public:
   RQt5WebDisplayHandle(const std::string &url, std::unique_ptr<RootUrlSchemeHandler> &handler)
      : RWebDisplayHandle(url)
   {
      std::swap(fHandler, handler);
      if (fHandler)
         QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(QByteArray(fHandler->GetProtocol()), fHandler.get());
   }

   static void AddCreator()
   {
      auto &entry = FindCreator("qt5");
      if (!entry)
         GetMap().emplace("qt5", std::make_unique<Qt5Creator>());
   }

   virtual ~RQt5WebDisplayHandle()
   {
      if (fHandler)
         QWebEngineProfile::defaultProfile()->removeUrlSchemeHandler(fHandler.get());
   }
};

struct RQt5CreatorReg {
   RQt5CreatorReg() { RQt5WebDisplayHandle::AddCreator(); }
} newRQt5CreatorReg;

}
}
<|endoftext|>


<commit_before>/* ****************************************************************************
 *
 * FILE                     main_samson_comscore_directory_create.cpp
 *
 * AUTHOR                   Andreu Urrueka
 *
 * CREATION DATE            2012
 *
 */

#include "parseArgs/parseArgs.h"
#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include <signal.h>
#include <algorithm>
#include <iostream>

#include "au/LockDebugger.h"            // au::LockDebugger
#include "au/ThreadManager.h"

#include "comscore/common.h"
#include "comscore/SamsonComscoreDictionary.h"

#define DEFAULT_COMSCORE_PATH "/var/comscore"
#define LINE_BUFF_SIZE 10000
/* ****************************************************************************
 *
 * Option variables
 */

static char paDictPath[128];

/* ****************************************************************************
 *
 * parse arguments
 */
PaArgument paArgs[] ={
    { "", paDictPath, "", PaStr, PaHid, 0, PaNL, PaNL,
            "Path to cs_mmxi.bcp, pattern_category_mapping.txt and cat_subcat_lookup.txt"},
    PA_END_OF_ARGS
};

/* ****************************************************************************
 *
 * global variables
 */

int logFd = -1;

/* ****************************************************************************
 *
 * main -
 */

// Vector of entries from original dictionary
std::vector<samson::comscore::OriginalDictionaryEntry> original_dictionary_entries;

// Vector of relations pattern to category
std::vector<samson::comscore::Id2Id> original_pattern_to_category;

typedef samson::comscore::uint uint;

// Map of category names
std::map< uint, std::string > categories;

void read_original_categories_file(const char* file_name) {
    LM_M(("Reading original categories file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original categories file", file_name));

    char line[10000];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, 10000, file)) {
        fields[0] = line;
        for (int f = 1; f < 3; f++) {
            char * pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        uint id = atoll(fields[0]);
        std::string description = fields[1];

        categories.insert(std::pair< uint, std::string > (id, description));

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));
    }

}

void read_original_pattern_to_category_file(const char * file_name) {
    LM_M(("Reading original pattern to category file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original pattern to category file", file_name));

    char line[LINE_BUFF_SIZE];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, LINE_BUFF_SIZE, file)) {
        fields[0] = line;
        for (int f = 1; f < 3; f++) {
            char *pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        // Fill element
        samson::comscore::Id2Id entry;

        entry.first = atoll(fields[0]);
        entry.second = atoll(fields[1]);

        // Push back this entry
        original_pattern_to_category.push_back(entry);

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));
    }

    // Sorting original records
    LM_M(("Sorting entries..."));

    std::sort(original_pattern_to_category.begin(), original_pattern_to_category.end(), samson::comscore::compareId2Id);

}

void read_original_dictionary_file(const char * file_name) {
    LM_M(("Reading original dictionary file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original dictionary file", file_name));

    char line[10000];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, 10000, file)) {
        fields[0] = line;
        for (int f = 1; f < 10; f++) {
            char * pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        // Fill element
        samson::comscore::OriginalDictionaryEntry dictionary_entry;

        dictionary_entry.id = atoll(fields[0]);
        dictionary_entry.pre_domain_pattern = fields[1];
        dictionary_entry.domain = fields[2];
        dictionary_entry.path_pattern = fields[5];
        dictionary_entry.order_1 = atoll(fields[6]);
        dictionary_entry.order_2 = atoll(fields[7]);

        if (
                (strstr(dictionary_entry.domain.c_str(), "/") != NULL) ||
                (strstr(dictionary_entry.domain.c_str(), "%") != NULL) ||
                (strcmp(dictionary_entry.domain.c_str(), "") == 0)
                ) {
            LM_W(("Discarting domain '%s' [%s][%s]"
                    , dictionary_entry.domain.c_str()
                    , dictionary_entry.pre_domain_pattern.c_str()
                    , dictionary_entry.path_pattern.c_str()
                    ));
            continue;
        }

        // Replace % by * in pre_domain_pattern and path_pattern
        replace(dictionary_entry.pre_domain_pattern.begin(), dictionary_entry.pre_domain_pattern.end(), '%', '*');
        replace(dictionary_entry.path_pattern.begin(), dictionary_entry.path_pattern.end(), '%', '*');

        // Remove first "/" and last "/" in path if exist
        size_t l = dictionary_entry.path_pattern.length();

        if (l > 0) {
            if (dictionary_entry.path_pattern.substr(0, 1) == "/")
                dictionary_entry.path_pattern.erase(0, 1);

            if (dictionary_entry.path_pattern.substr(l - 1, 1) == "/")
                dictionary_entry.path_pattern.erase(l - 1, 1);
        }

        // Push back this entry
        original_dictionary_entries.push_back(dictionary_entry);

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));

    }

    // Sorting original records
    LM_M(("Sorting entries"));
    std::sort(original_dictionary_entries.begin(), original_dictionary_entries.end(), samson::comscore::compareOriginalDictionaryEntry);

}

int main(int argC, const char *argV[]) {
    paConfig("builtin prefix", (void*) "SS_WORKER_");
    paConfig("usage and exit on any warning", (void*) true);

    paConfig("log to screen", (void*) true);

    paConfig("log file line format", (void*) "TYPE:DATE:EXEC-AUX/FILE[LINE](p.PID)(t.TID) FUNC: TEXT");
    paConfig("screen line format", (void*) "TYPE@TIME  EXEC: TEXT");
    paConfig("log to file", (void*) false);

    paParse(paArgs, argC, (char**) argV, 1, false);

    std::cout << "Comscore path " << paDictPath << std::endl;

    const char *comscore_path = (strlen(paDictPath))
                ? paDictPath : DEFAULT_COMSCORE_PATH;
    std::string comscore_dictionary_file_name = comscore_path;
    comscore_dictionary_file_name += "/cs_mmxi.bcp";
    std::string pattern_to_category_file_name = comscore_path;
    pattern_to_category_file_name += "/pattern_category_mapping.txt";
    std::string comscore_categories_files = comscore_path;
    comscore_categories_files += "/cat_subcat_lookup.txt";

    const char* samson_comsore_dictionary_file_name = "samson_comscore_dictionary.bin"; // Current directories

    // Reading original files
    read_original_dictionary_file(comscore_dictionary_file_name.c_str());
    read_original_pattern_to_category_file(pattern_to_category_file_name.c_str());
    read_original_categories_file(comscore_categories_files.c_str());

    // ------------------------------------
    // Creating the file
    // ------------------------------------
    LM_M(("Creating samson comscore dictionary"));
    samson::comscore::SamsonComscoreDictionary samson_comscore_dictionary;

    LM_M(("Adding main dictionary entries"));
    for (size_t i = 0; i < original_dictionary_entries.size(); i++) {
        if ((i % 100000) == 0)
            LM_M(("Progress %lu records", i));

        samson_comscore_dictionary.push(original_dictionary_entries[i]);
    }

    LM_M(("Adding pattern to dictionary mapping entries"));
    for (size_t i = 0; i < original_pattern_to_category.size(); i++) {
        if ((i % 100000) == 0)
                LM_M(("Progress %lu records", i));
        samson_comscore_dictionary.push_pattern_to_category(original_pattern_to_category[i]);
    }

    LM_M(("Adding category description"));
    std::map< uint, std::string >::iterator it_categories;
    for (it_categories = categories.begin(); it_categories != categories.end(); it_categories++)
        samson_comscore_dictionary.push_category(it_categories->first, it_categories->second);

    LM_M(("Writing comscore dictionary to file %s", samson_comsore_dictionary_file_name));
    samson_comscore_dictionary.write(samson_comsore_dictionary_file_name);
}
<commit_msg>cat_subcat_lookup.txt renamed to cat_subcat_map.txt<commit_after>/* ****************************************************************************
 *
 * FILE                     main_samson_comscore_directory_create.cpp
 *
 * AUTHOR                   Andreu Urrueka
 *
 * CREATION DATE            2012
 *
 */

#include "parseArgs/parseArgs.h"
#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include <signal.h>
#include <algorithm>
#include <iostream>

#include "au/LockDebugger.h"            // au::LockDebugger
#include "au/ThreadManager.h"

#include "comscore/common.h"
#include "comscore/SamsonComscoreDictionary.h"

#define DEFAULT_COMSCORE_PATH "/var/comscore"
#define LINE_BUFF_SIZE 10000
/* ****************************************************************************
 *
 * Option variables
 */

static char paDictPath[128];

/* ****************************************************************************
 *
 * parse arguments
 */
PaArgument paArgs[] ={
    { "", paDictPath, "", PaStr, PaHid, 0, PaNL, PaNL,
            "Path to cs_mmxi.bcp, pattern_category_mapping.txt and cat_subcat_map.txt"},
    PA_END_OF_ARGS
};

/* ****************************************************************************
 *
 * global variables
 */

int logFd = -1;

/* ****************************************************************************
 *
 * main -
 */

// Vector of entries from original dictionary
std::vector<samson::comscore::OriginalDictionaryEntry> original_dictionary_entries;

// Vector of relations pattern to category
std::vector<samson::comscore::Id2Id> original_pattern_to_category;

typedef samson::comscore::uint uint;

// Map of category names
std::map< uint, std::string > categories;

void read_original_categories_file(const char* file_name) {
    LM_M(("Reading original categories file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original categories file", file_name));

    char line[10000];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, 10000, file)) {
        fields[0] = line;
        for (int f = 1; f < 3; f++) {
            char * pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        uint id = atoll(fields[0]);
        std::string description = fields[1];

        categories.insert(std::pair< uint, std::string > (id, description));

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));
    }

}

void read_original_pattern_to_category_file(const char * file_name) {
    LM_M(("Reading original pattern to category file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original pattern to category file", file_name));

    char line[LINE_BUFF_SIZE];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, LINE_BUFF_SIZE, file)) {
        fields[0] = line;
        for (int f = 1; f < 3; f++) {
            char *pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        // Fill element
        samson::comscore::Id2Id entry;

        entry.first = atoll(fields[0]);
        entry.second = atoll(fields[1]);

        // Push back this entry
        original_pattern_to_category.push_back(entry);

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));
    }

    // Sorting original records
    LM_M(("Sorting entries..."));

    std::sort(original_pattern_to_category.begin(), original_pattern_to_category.end(), samson::comscore::compareId2Id);

}

void read_original_dictionary_file(const char * file_name) {
    LM_M(("Reading original dictionary file"));

    FILE *file = fopen(file_name, "r");

    if (!file)
        LM_X(1, ("Error reading file %s to load original dictionary file", file_name));

    char line[10000];
    char* fields[10];
    size_t num = 0;

    while (fgets(line, 10000, file)) {
        fields[0] = line;
        for (int f = 1; f < 10; f++) {
            char * pos = strstr(fields[f - 1], "\t");
            *pos = '\0';

            fields[f] = pos + 1;
        }

        // Fill element
        samson::comscore::OriginalDictionaryEntry dictionary_entry;

        dictionary_entry.id = atoll(fields[0]);
        dictionary_entry.pre_domain_pattern = fields[1];
        dictionary_entry.domain = fields[2];
        dictionary_entry.path_pattern = fields[5];
        dictionary_entry.order_1 = atoll(fields[6]);
        dictionary_entry.order_2 = atoll(fields[7]);

        if (
                (strstr(dictionary_entry.domain.c_str(), "/") != NULL) ||
                (strstr(dictionary_entry.domain.c_str(), "%") != NULL) ||
                (strcmp(dictionary_entry.domain.c_str(), "") == 0)
                ) {
            LM_W(("Discarting domain '%s' [%s][%s]"
                    , dictionary_entry.domain.c_str()
                    , dictionary_entry.pre_domain_pattern.c_str()
                    , dictionary_entry.path_pattern.c_str()
                    ));
            continue;
        }

        // Replace % by * in pre_domain_pattern and path_pattern
        replace(dictionary_entry.pre_domain_pattern.begin(), dictionary_entry.pre_domain_pattern.end(), '%', '*');
        replace(dictionary_entry.path_pattern.begin(), dictionary_entry.path_pattern.end(), '%', '*');

        // Remove first "/" and last "/" in path if exist
        size_t l = dictionary_entry.path_pattern.length();

        if (l > 0) {
            if (dictionary_entry.path_pattern.substr(0, 1) == "/")
                dictionary_entry.path_pattern.erase(0, 1);

            if (dictionary_entry.path_pattern.substr(l - 1, 1) == "/")
                dictionary_entry.path_pattern.erase(l - 1, 1);
        }

        // Push back this entry
        original_dictionary_entries.push_back(dictionary_entry);

        if ((++num % 100000) == 0)
            LM_M(("Readed %lu records", num));

    }

    // Sorting original records
    LM_M(("Sorting entries"));
    std::sort(original_dictionary_entries.begin(), original_dictionary_entries.end(), samson::comscore::compareOriginalDictionaryEntry);

}

int main(int argC, const char *argV[]) {
    paConfig("builtin prefix", (void*) "SS_WORKER_");
    paConfig("usage and exit on any warning", (void*) true);

    paConfig("log to screen", (void*) true);

    paConfig("log file line format", (void*) "TYPE:DATE:EXEC-AUX/FILE[LINE](p.PID)(t.TID) FUNC: TEXT");
    paConfig("screen line format", (void*) "TYPE@TIME  EXEC: TEXT");
    paConfig("log to file", (void*) false);

    paParse(paArgs, argC, (char**) argV, 1, false);

    std::cout << "Comscore path " << paDictPath << std::endl;

    const char *comscore_path = (strlen(paDictPath))
                ? paDictPath : DEFAULT_COMSCORE_PATH;
    std::string comscore_dictionary_file_name = comscore_path;
    comscore_dictionary_file_name += "/cs_mmxi.bcp";
    std::string pattern_to_category_file_name = comscore_path;
    pattern_to_category_file_name += "/pattern_category_mapping.txt";
    std::string comscore_categories_files = comscore_path;
    comscore_categories_files += "/cat_subcat_map.txt";

    const char* samson_comsore_dictionary_file_name = "samson_comscore_dictionary.bin"; // Current directories

    // Reading original files
    read_original_dictionary_file(comscore_dictionary_file_name.c_str());
    read_original_pattern_to_category_file(pattern_to_category_file_name.c_str());
    read_original_categories_file(comscore_categories_files.c_str());

    // ------------------------------------
    // Creating the file
    // ------------------------------------
    LM_M(("Creating samson comscore dictionary"));
    samson::comscore::SamsonComscoreDictionary samson_comscore_dictionary;

    LM_M(("Adding main dictionary entries"));
    for (size_t i = 0; i < original_dictionary_entries.size(); i++) {
        if ((i % 100000) == 0)
            LM_M(("Progress %lu records", i));

        samson_comscore_dictionary.push(original_dictionary_entries[i]);
    }

    LM_M(("Adding pattern to dictionary mapping entries"));
    for (size_t i = 0; i < original_pattern_to_category.size(); i++) {
        if ((i % 100000) == 0)
                LM_M(("Progress %lu records", i));
        samson_comscore_dictionary.push_pattern_to_category(original_pattern_to_category[i]);
    }

    LM_M(("Adding category description"));
    std::map< uint, std::string >::iterator it_categories;
    for (it_categories = categories.begin(); it_categories != categories.end(); it_categories++)
        samson_comscore_dictionary.push_category(it_categories->first, it_categories->second);

    LM_M(("Writing comscore dictionary to file %s", samson_comsore_dictionary_file_name));
    samson_comscore_dictionary.write(samson_comsore_dictionary_file_name);
}
<|endoftext|>