<commit_before>/*
  Copyright 2011 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include "OpenImageIO/fmath.h"
#include "OpenImageIO/unittest.h"

OIIO_NAMESPACE_USING;

void
test_int_helpers ()
{
    std::cout << "\ntest_int_helpers\n";

    // ispow2
    for (int i = 1; i < (1<<30); i *= 2) {
        OIIO_CHECK_ASSERT (ispow2(i));
        if (i > 1)
            OIIO_CHECK_ASSERT (! ispow2(i+1));
    }
    OIIO_CHECK_ASSERT (ispow2(int(0)));
    OIIO_CHECK_ASSERT (! ispow2(-1));
    OIIO_CHECK_ASSERT (! ispow2(-2));

    // ispow2, try size_t, which is unsigned
    for (size_t i = 1; i < (1<<30); i *= 2) {
        OIIO_CHECK_ASSERT (ispow2(i));
        if (i > 1)
            OIIO_CHECK_ASSERT (! ispow2(i+1));
    }
    OIIO_CHECK_ASSERT (ispow2((unsigned int)0));

    // pow2roundup
    OIIO_CHECK_EQUAL (pow2roundup(4), 4);
    OIIO_CHECK_EQUAL (pow2roundup(5), 8);
    OIIO_CHECK_EQUAL (pow2roundup(6), 8);
    OIIO_CHECK_EQUAL (pow2roundup(7), 8);
    OIIO_CHECK_EQUAL (pow2roundup(8), 8);

    // pow2rounddown
    OIIO_CHECK_EQUAL (pow2rounddown(4), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(5), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(6), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(7), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(8), 8);

    // round_to_multiple
    OIIO_CHECK_EQUAL (round_to_multiple(1, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(2, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(3, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(4, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(5, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(6, 5), 10);

    // round_to_multiple_of_pow2
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(1), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(2), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(3), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(4), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(5), 4), 8);

    // round_to_multiple_of_pow2
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(1), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(2), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(3), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(4), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(5), size_t(4)), 8);
}

// Convert T to F to T, make sure value are preserved round trip
template<typename T, typename F>
void test_convert_type (double tolerance = 1e-6)
{
    if (std::numeric_limits<T>::is_integer) {
        for (long long i = std::numeric_limits<T>::min();
                 i <= std::numeric_limits<T>::max();  ++i) {
            T in = (T)i;
            F f = convert_type<T,F> (in);
            T out = convert_type<F,T> (f);
            if (out != in) {
                std::cout << "  convert " << (long long)in << " -> " << f << " -> " << (long long)out << "\n";
                ++unit_test_failures;
            }
        }
    } else {
        for (float i = 0.0f; i <= 1.0f;  i += 0.001) {
            T in = (T)i;
            F f = convert_type<T,F> (in);
            T out = convert_type<F,T> (f);
            if (fabs(double(out-in)) > tolerance) {
                std::cout << "  convert " << in << " -> " << f << " -> " << out << " (diff = " << (out-in) << ")\n";
                ++unit_test_failures;
            }
        }
    }
}

void test_bit_range_convert ()
{
    OIIO_CHECK_EQUAL ((bit_range_convert<10,16>(1023)), 65535);
    OIIO_CHECK_EQUAL ((bit_range_convert<2,8>(3)), 255);
    OIIO_CHECK_EQUAL ((bit_range_convert<8,8>(255)), 255);
    OIIO_CHECK_EQUAL ((bit_range_convert<16,10>(65535)), 1023);
    OIIO_CHECK_EQUAL ((bit_range_convert<2,20>(3)), 1048575);
    OIIO_CHECK_EQUAL ((bit_range_convert<20,2>(1048575)), 3);
    OIIO_CHECK_EQUAL ((bit_range_convert<20,21>(1048575)), 2097151);
    OIIO_CHECK_EQUAL ((bit_range_convert<32,32>(4294967295U)), 4294967295U);
    OIIO_CHECK_EQUAL ((bit_range_convert<32,16>(4294967295U)), 65535);
// These are not expected to work, since bit_range_convert only takes a
// regular 'unsigned int' as parameter.  If we need >32 bit conversion,
// we need to add a uint64_t version of bit_range_convert.
//    OIIO_CHECK_EQUAL ((bit_range_convert<33,16>(8589934591)), 65535);
//    OIIO_CHECK_EQUAL ((bit_range_convert<33,33>(8589934591)), 8589934591);
//    OIIO_CHECK_EQUAL ((bit_range_convert<64,32>(18446744073709551615)), 4294967295);
}

int main (int argc, char *argv[])
{
    test_int_helpers ();

    std::cout << "\nround trip convert char/float/char\n";
    test_convert_type<char,float> ();
    std::cout << "round trip convert unsigned char/float/unsigned char\n";
    test_convert_type<unsigned char,float> ();
    std::cout << "round trip convert unsigned char/unsigned short/unsigned char\n";
    test_convert_type<unsigned char,unsigned short> ();
    std::cout << "round trip convert short/float/short\n";
    test_convert_type<short,float> ();
    std::cout << "round trip convert unsigned short/float/unsigned short\n";
    test_convert_type<unsigned short,float> ();
    std::cout << "round trip convert float/int/float \n";
    test_convert_type<float,int> ();
    std::cout << "round trip convert double/float/double\n";
    test_convert_type<double,float> ();
    std::cout << "round trip convert double/long/double\n";
    test_convert_type<double,long> ();
    std::cout << "round trip convert float/unsigned int/float\n";
    test_convert_type<float, unsigned int> ();

// convertion to a type smaller in bytes causes error
//    std::cout << "round trip convert float/short/float\n";
//    test_convert_type<float,short> ();
//    std::cout << "round trip convert unsigned float/char/float\n";
//    test_convert_type<float,char> ();
//    std::cout << "round trip convert unsigned float/unsigned char/float\n";
//    test_convert_type<float,unsigned char> ();
//    std::cout << "round trip convert unsigned short/unsigned char/unsigned short\n";
//    test_convert_type<unsigned short,unsigned char> ();
//    std::cout << "round trip convert float/unsigned short/float\n";
//    test_convert_type<float,unsigned short> ();

    test_bit_range_convert();

    return unit_test_failures != 0;
}
<commit_msg>fmath_test -- add benchmarks for various data conversions<commit_after>/*
  Copyright 2011 Larry Gritz and the other authors and contributors.
  All Rights Reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the software's owners nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  (This is the Modified BSD License)
*/

#include <vector>

#include <OpenEXR/half.h>

#include <OpenImageIO/fmath.h>
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/typedesc.h>
#include <OpenImageIO/timer.h>
#include <OpenImageIO/unittest.h>
#include <OpenImageIO/imagebufalgo_util.h>

OIIO_NAMESPACE_USING;

void
test_int_helpers ()
{
    std::cout << "\ntest_int_helpers\n";

    // ispow2
    for (int i = 1; i < (1<<30); i *= 2) {
        OIIO_CHECK_ASSERT (ispow2(i));
        if (i > 1)
            OIIO_CHECK_ASSERT (! ispow2(i+1));
    }
    OIIO_CHECK_ASSERT (ispow2(int(0)));
    OIIO_CHECK_ASSERT (! ispow2(-1));
    OIIO_CHECK_ASSERT (! ispow2(-2));

    // ispow2, try size_t, which is unsigned
    for (size_t i = 1; i < (1<<30); i *= 2) {
        OIIO_CHECK_ASSERT (ispow2(i));
        if (i > 1)
            OIIO_CHECK_ASSERT (! ispow2(i+1));
    }
    OIIO_CHECK_ASSERT (ispow2((unsigned int)0));

    // pow2roundup
    OIIO_CHECK_EQUAL (pow2roundup(4), 4);
    OIIO_CHECK_EQUAL (pow2roundup(5), 8);
    OIIO_CHECK_EQUAL (pow2roundup(6), 8);
    OIIO_CHECK_EQUAL (pow2roundup(7), 8);
    OIIO_CHECK_EQUAL (pow2roundup(8), 8);

    // pow2rounddown
    OIIO_CHECK_EQUAL (pow2rounddown(4), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(5), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(6), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(7), 4);
    OIIO_CHECK_EQUAL (pow2rounddown(8), 8);

    // round_to_multiple
    OIIO_CHECK_EQUAL (round_to_multiple(1, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(2, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(3, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(4, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(5, 5), 5);
    OIIO_CHECK_EQUAL (round_to_multiple(6, 5), 10);

    // round_to_multiple_of_pow2
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(1), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(2), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(3), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(4), 4), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(int(5), 4), 8);

    // round_to_multiple_of_pow2
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(1), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(2), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(3), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(4), size_t(4)), 4);
    OIIO_CHECK_EQUAL (round_to_multiple_of_pow2(size_t(5), size_t(4)), 8);
}

// Convert T to F to T, make sure value are preserved round trip
template<typename T, typename F>
void test_convert_type (double tolerance = 1e-6)
{
    if (std::numeric_limits<T>::is_integer) {
        for (long long i = std::numeric_limits<T>::min();
                 i <= std::numeric_limits<T>::max();  ++i) {
            T in = (T)i;
            F f = convert_type<T,F> (in);
            T out = convert_type<F,T> (f);
            if (out != in) {
                std::cout << "  convert " << (long long)in << " -> " << f << " -> " << (long long)out << "\n";
                ++unit_test_failures;
            }
        }
    } else {
        for (float i = 0.0f; i <= 1.0f;  i += 0.001) {
            T in = (T)i;
            F f = convert_type<T,F> (in);
            T out = convert_type<F,T> (f);
            if (fabs(double(out-in)) > tolerance) {
                std::cout << "  convert " << in << " -> " << f << " -> " << out << " (diff = " << (out-in) << ")\n";
                ++unit_test_failures;
            }
        }
    }
}

template<typename S, typename D>
void do_convert_type (const std::vector<S> &svec, std::vector<D> &dvec)
{
    convert_type (&svec[0], &dvec[0], svec.size());
    DoNotOptimize (dvec[0]);  // Be sure nothing is optimized away
}

template<typename S, typename D>
void benchmark_convert_type ()
{
    const int ntrials = 5;
    const int iterations = 10;
    const size_t size = 10000000;
    const S testval(1.0);
    std::vector<S> svec (size, testval);
    std::vector<D> dvec (size);
    std::cout << Strutil::format("Benchmark conversion of %6s -> %6s : ",
                                 TypeDesc(BaseTypeFromC<S>::value),
                                 TypeDesc(BaseTypeFromC<D>::value));
    float time = time_trial (bind (do_convert_type<S,D>, OIIO::cref(svec), OIIO::ref(dvec)),
                             ntrials, iterations) / iterations;
    std::cout << Strutil::format ("%7.1f Mvals/sec", (size/1.0e6)/time) << std::endl;
    D r = convert_type<S,D>(testval);
    OIIO_CHECK_EQUAL (dvec[size-1], r);
}

void test_bit_range_convert ()
{
    OIIO_CHECK_EQUAL ((bit_range_convert<10,16>(1023)), 65535);
    OIIO_CHECK_EQUAL ((bit_range_convert<2,8>(3)), 255);
    OIIO_CHECK_EQUAL ((bit_range_convert<8,8>(255)), 255);
    OIIO_CHECK_EQUAL ((bit_range_convert<16,10>(65535)), 1023);
    OIIO_CHECK_EQUAL ((bit_range_convert<2,20>(3)), 1048575);
    OIIO_CHECK_EQUAL ((bit_range_convert<20,2>(1048575)), 3);
    OIIO_CHECK_EQUAL ((bit_range_convert<20,21>(1048575)), 2097151);
    OIIO_CHECK_EQUAL ((bit_range_convert<32,32>(4294967295U)), 4294967295U);
    OIIO_CHECK_EQUAL ((bit_range_convert<32,16>(4294967295U)), 65535);
// These are not expected to work, since bit_range_convert only takes a
// regular 'unsigned int' as parameter.  If we need >32 bit conversion,
// we need to add a uint64_t version of bit_range_convert.
//    OIIO_CHECK_EQUAL ((bit_range_convert<33,16>(8589934591)), 65535);
//    OIIO_CHECK_EQUAL ((bit_range_convert<33,33>(8589934591)), 8589934591);
//    OIIO_CHECK_EQUAL ((bit_range_convert<64,32>(18446744073709551615)), 4294967295);
}

int main (int argc, char *argv[])
{
    test_int_helpers ();

    std::cout << "\nround trip convert char/float/char\n";
    test_convert_type<char,float> ();
    std::cout << "round trip convert unsigned char/float/unsigned char\n";
    test_convert_type<unsigned char,float> ();
    std::cout << "round trip convert unsigned char/unsigned short/unsigned char\n";
    test_convert_type<unsigned char,unsigned short> ();
    std::cout << "round trip convert short/float/short\n";
    test_convert_type<short,float> ();
    std::cout << "round trip convert unsigned short/float/unsigned short\n";
    test_convert_type<unsigned short,float> ();
    std::cout << "round trip convert float/int/float \n";
    test_convert_type<float,int> ();
    std::cout << "round trip convert double/float/double\n";
    test_convert_type<double,float> ();
    std::cout << "round trip convert double/long/double\n";
    test_convert_type<double,long> ();
    std::cout << "round trip convert float/unsigned int/float\n";
    test_convert_type<float, unsigned int> ();

    benchmark_convert_type<unsigned char, float> ();
    benchmark_convert_type<float, unsigned char> ();
    benchmark_convert_type<unsigned short, float> ();
    benchmark_convert_type<float, unsigned short> ();
    benchmark_convert_type<half, float> ();
    benchmark_convert_type<float, half> ();
    benchmark_convert_type<float, float> ();
// convertion to a type smaller in bytes causes error
//    std::cout << "round trip convert float/short/float\n";
//    test_convert_type<float,short> ();
//    std::cout << "round trip convert unsigned float/char/float\n";
//    test_convert_type<float,char> ();
//    std::cout << "round trip convert unsigned float/unsigned char/float\n";
//    test_convert_type<float,unsigned char> ();
//    std::cout << "round trip convert unsigned short/unsigned char/unsigned short\n";
//    test_convert_type<unsigned short,unsigned char> ();
//    std::cout << "round trip convert float/unsigned short/float\n";
//    test_convert_type<float,unsigned short> ();

    test_bit_range_convert();

    return unit_test_failures != 0;
}
<|endoftext|>


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

#include "chrome/renderer/speech_input_dispatcher.h"

#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSpeechInputListener.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"

using WebKit::WebFrame;

SpeechInputDispatcher::SpeechInputDispatcher(
    RenderView* render_view, WebKit::WebSpeechInputListener* listener)
    : render_view_(render_view),
      listener_(listener) {
}

bool SpeechInputDispatcher::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(SpeechInputDispatcher, message)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_SetRecognitionResult,
                        OnSpeechRecognitionResult)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_RecordingComplete,
                        OnSpeechRecordingComplete)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_RecognitionComplete,
                        OnSpeechRecognitionComplete)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool SpeechInputDispatcher::startRecognition(
    int request_id, const WebKit::WebString& language,
    const WebKit::WebRect& element_rect) {
  return startRecognition(request_id, element_rect);
}

bool SpeechInputDispatcher::startRecognition(
    int request_id, const WebKit::WebRect& element_rect) {
  VLOG(1) << "SpeechInputDispatcher::startRecognition enter";
  gfx::Size scroll = render_view_->webview()->mainFrame()->scrollOffset();
  gfx::Rect rect = element_rect;
  rect.Offset(-scroll.width(), -scroll.height());
  render_view_->Send(new ViewHostMsg_SpeechInput_StartRecognition(
      render_view_->routing_id(), request_id, rect));
  VLOG(1) << "SpeechInputDispatcher::startRecognition exit";
  return true;
}

void SpeechInputDispatcher::cancelRecognition(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::cancelRecognition enter";
  render_view_->Send(new ViewHostMsg_SpeechInput_CancelRecognition(
      render_view_->routing_id(), request_id));
  VLOG(1) << "SpeechInputDispatcher::cancelRecognition exit";
}

void SpeechInputDispatcher::stopRecording(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::stopRecording enter";
  render_view_->Send(new ViewHostMsg_SpeechInput_StopRecording(
      render_view_->routing_id(), request_id));
  VLOG(1) << "SpeechInputDispatcher::stopRecording exit";
}

void SpeechInputDispatcher::OnSpeechRecognitionResult(
    int request_id, const string16& result) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult enter";
  listener_->setRecognitionResult(request_id, result);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult exit";
}

void SpeechInputDispatcher::OnSpeechRecordingComplete(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete enter";
  listener_->didCompleteRecording(request_id);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete exit";
}

void SpeechInputDispatcher::OnSpeechRecognitionComplete(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete enter";
  listener_->didCompleteRecognition(request_id);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete exit";
}
<commit_msg>Construct a WebString explicitly and pass to a WebKit method. This is to prevent build errors when https://bugs.webkit.org/show_bug.cgi?id=48068 lands.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/speech_input_dispatcher.h"

#include "chrome/renderer/render_view.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSpeechInputListener.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"

using WebKit::WebFrame;

SpeechInputDispatcher::SpeechInputDispatcher(
    RenderView* render_view, WebKit::WebSpeechInputListener* listener)
    : render_view_(render_view),
      listener_(listener) {
}

bool SpeechInputDispatcher::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(SpeechInputDispatcher, message)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_SetRecognitionResult,
                        OnSpeechRecognitionResult)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_RecordingComplete,
                        OnSpeechRecordingComplete)
    IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_RecognitionComplete,
                        OnSpeechRecognitionComplete)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool SpeechInputDispatcher::startRecognition(
    int request_id, const WebKit::WebString& language,
    const WebKit::WebRect& element_rect) {
  return startRecognition(request_id, element_rect);
}

bool SpeechInputDispatcher::startRecognition(
    int request_id, const WebKit::WebRect& element_rect) {
  VLOG(1) << "SpeechInputDispatcher::startRecognition enter";
  gfx::Size scroll = render_view_->webview()->mainFrame()->scrollOffset();
  gfx::Rect rect = element_rect;
  rect.Offset(-scroll.width(), -scroll.height());
  render_view_->Send(new ViewHostMsg_SpeechInput_StartRecognition(
      render_view_->routing_id(), request_id, rect));
  VLOG(1) << "SpeechInputDispatcher::startRecognition exit";
  return true;
}

void SpeechInputDispatcher::cancelRecognition(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::cancelRecognition enter";
  render_view_->Send(new ViewHostMsg_SpeechInput_CancelRecognition(
      render_view_->routing_id(), request_id));
  VLOG(1) << "SpeechInputDispatcher::cancelRecognition exit";
}

void SpeechInputDispatcher::stopRecording(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::stopRecording enter";
  render_view_->Send(new ViewHostMsg_SpeechInput_StopRecording(
      render_view_->routing_id(), request_id));
  VLOG(1) << "SpeechInputDispatcher::stopRecording exit";
}

void SpeechInputDispatcher::OnSpeechRecognitionResult(
    int request_id, const string16& result) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult enter";
  WebKit::WebString webkit_result(result);
  listener_->setRecognitionResult(request_id, webkit_result);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionResult exit";
}

void SpeechInputDispatcher::OnSpeechRecordingComplete(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete enter";
  listener_->didCompleteRecording(request_id);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecordingComplete exit";
}

void SpeechInputDispatcher::OnSpeechRecognitionComplete(int request_id) {
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete enter";
  listener_->didCompleteRecognition(request_id);
  VLOG(1) << "SpeechInputDispatcher::OnSpeechRecognitionComplete exit";
}
<|endoftext|>


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

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

const wchar_t kRunDromaeo[] = L"run-dromaeo-benchmark";

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest(const FilePath::CharType* suite) {
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(
        FilePath::StringType(FILE_PATH_LITERAL("index.html?")) +
        FilePath::StringType(suite) +
        FilePath::StringType(FILE_PATH_LITERAL("&automated")));
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    PrintResult("score", "", trace_name, score, unit_name, true);

    ResultsMap::const_iterator it = results.begin();
    for (; it != results.end(); ++it) {
      std::string test_name = it->first;
      for (size_t i = 0; i < test_name.length(); i++)
        if (!isalnum(test_name[i]))
          test_name[i] = '_';
      PrintResult(test_name, "", trace_name, it->second, unit_name, false);
    }
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, DOMCorePerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoTest, JSLibPerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("jslib"));
}

TEST_F(DromaeoReferenceTest, DOMCorePerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoReferenceTest, JSLibPerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("jslib"));
}

}  // namespace
<commit_msg>Drop leading score: score line.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

const wchar_t kRunDromaeo[] = L"run-dromaeo-benchmark";

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest(const FilePath::CharType* suite) {
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(
        FilePath::StringType(FILE_PATH_LITERAL("index.html?")) +
        FilePath::StringType(suite) +
        FilePath::StringType(FILE_PATH_LITERAL("&automated")));
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    ResultsMap::const_iterator it = results.begin();
    // First result is overall score and thus "important".
    bool important = true;
    for (; it != results.end(); ++it) {
      std::string test_name = it->first;
      for (size_t i = 0; i < test_name.length(); i++)
        if (!isalnum(test_name[i]))
          test_name[i] = '_';
      PrintResult(test_name, "", trace_name, it->second, unit_name, important);
      important = false;  // All others are not overall scores.
    }
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, DOMCorePerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoTest, JSLibPerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("jslib"));
}

TEST_F(DromaeoReferenceTest, DOMCorePerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoReferenceTest, JSLibPerf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest(FILE_PATH_LITERAL("jslib"));
}

}  // namespace
<|endoftext|>


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

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest(const FilePath::CharType* suite) {
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(
        FilePath::StringType(FILE_PATH_LITERAL("index.html?")) +
        FilePath::StringType(suite) +
        FilePath::StringType(FILE_PATH_LITERAL("&automated")));
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    PrintResult("score", "", trace_name, score, unit_name, true);

    ResultsMap::const_iterator it = results.begin();
    for (; it != results.end(); ++it) {
      std::string test_name = it->first;
      for (size_t i = 0; i < test_name.length(); i++)
        if (!isalnum(test_name[i]))
          test_name[i] = '_';
      PrintResult(test_name, "", trace_name, it->second, unit_name, false);
    }
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, DOMCorePerf) {
  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoTest, JSLibPerf) {
  RunTest(FILE_PATH_LITERAL("jslib"));
}

TEST_F(DromaeoReferenceTest, DOMCorePerf) {
  RunTest(FILE_PATH_LITERAL("dom"));
}

TEST_F(DromaeoReferenceTest, JSLibPerf) {
  RunTest(FILE_PATH_LITERAL("jslib"));
}

}  // namespace
<commit_msg>Revert -r 40634 to wait until masters' configs get updated.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

static const FilePath::CharType kStartFile[] =
    FILE_PATH_LITERAL("index.html?dom|jslib&automated");

const wchar_t kRunDromaeo[] = L"run-dromaeo-benchmark";

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest() {
    FilePath::StringType start_file(kStartFile);
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(start_file);
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    PrintResult("score", "", trace_name, score, unit_name, true);

    ResultsMap::const_iterator it = results.begin();
    for (; it != results.end(); ++it) {
      std::string test_name = it->first;
      for (size_t i = 0; i < test_name.length(); i++)
        if (!isalnum(test_name[i]))
          test_name[i] = '_';
      PrintResult(test_name, "", trace_name, it->second, unit_name, false);
    }
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, Perf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest();
}

TEST_F(DromaeoReferenceTest, Perf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest();
}

}  // namespace
<|endoftext|>


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

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

static const FilePath::CharType kStartFile[] =
    FILE_PATH_LITERAL("index.html?dom|jslib&automated");

const wchar_t kRunDromaeo[] = L"run-dromaeo-benchmark";

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest() {
    FilePath::StringType start_file(kStartFile);
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(start_file);
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    PrintResult("score", "", trace_name, score, unit_name, true);

    ResultsMap::const_iterator it = results.begin();
    for (; it != results.end(); ++it)
      PrintResult(it->first, "", trace_name, it->second, unit_name, false);
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, Perf) {
  //if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
  //  return;

  //RunTest();
}

TEST_F(DromaeoReferenceTest, Perf) {
  //if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
  //  return;

  //RunTest();
}

}  // namespace
<commit_msg>Patch by antomn@chromium.org<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_test.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"

namespace {

static const FilePath::CharType kStartFile[] =
    FILE_PATH_LITERAL("index.html?dom|jslib&automated");

const wchar_t kRunDromaeo[] = L"run-dromaeo-benchmark";

class DromaeoTest : public UITest {
 public:
  typedef std::map<std::string, std::string> ResultsMap;

  DromaeoTest() : reference_(false) {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  void RunTest() {
    FilePath::StringType start_file(kStartFile);
    FilePath test_path = GetDromaeoDir();
    test_path = test_path.Append(start_file);
    GURL test_url(net::FilePathToFileURL(test_path));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    tab->NavigateToURL(test_url);

    // Wait for the test to finish.
    ASSERT_TRUE(WaitUntilTestCompletes(tab.get(), test_url));

    PrintResults(tab.get());
  }

 protected:
  bool reference_;  // True if this is a reference build.

 private:
  // Return the path to the dromaeo benchmark directory on the local filesystem.
  FilePath GetDromaeoDir() {
    FilePath test_dir;
    PathService::Get(chrome::DIR_TEST_DATA, &test_dir);
    return test_dir.AppendASCII("dromaeo");
  }

  bool WaitUntilTestCompletes(TabProxy* tab, const GURL& test_url) {
    return WaitUntilCookieValue(tab, test_url, "__done", 1000,
                                UITest::test_timeout_ms(), "1");
  }

  bool GetScore(TabProxy* tab, std::string* score) {
    std::wstring score_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send(automation.GetScore());",
        &score_wide);

    // Note that we don't use ASSERT_TRUE here (and in some other places) as it
    // doesn't work inside a function with a return type other than void.
    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    score->assign(WideToUTF8(score_wide));
    return true;
  }

  bool GetResults(TabProxy* tab, ResultsMap* results) {
    std::wstring json_wide;
    bool succeeded = tab->ExecuteAndExtractString(L"",
        L"window.domAutomationController.send("
        L"    JSON.stringify(automation.GetResults()));",
        &json_wide);

    EXPECT_TRUE(succeeded);
    if (!succeeded)
      return false;

    std::string json = WideToUTF8(json_wide);
    return JsonDictionaryToMap(json, results);
  }

  void PrintResults(TabProxy* tab) {
    std::string score;
    ASSERT_TRUE(GetScore(tab, &score));

    ResultsMap results;
    ASSERT_TRUE(GetResults(tab, &results));

    std::string trace_name = reference_ ? "score_ref" : "score";
    std::string unit_name = "runs/s";

    PrintResult("score", "", trace_name, score, unit_name, true);

    ResultsMap::const_iterator it = results.begin();
    for (; it != results.end(); ++it) {
      std::string test_name = it->first;
      for (size_t i = 0; i < test_name.length(); i++)
        if (!isalnum(test_name[i]))
          test_name[i] = '_';
      PrintResult(test_name, "", trace_name, it->second, unit_name, false);
    }
  }

  DISALLOW_COPY_AND_ASSIGN(DromaeoTest);
};

class DromaeoReferenceTest : public DromaeoTest {
 public:
  DromaeoReferenceTest() : DromaeoTest() {
    reference_ = true;
  }

  // Override the browser directory that is used by UITest::SetUp to cause it
  // to use the reference build instead.
  void SetUp() {
    FilePath dir;
    PathService::Get(chrome::DIR_TEST_TOOLS, &dir);
    dir = dir.AppendASCII("reference_build");
#if defined(OS_WIN)
    dir = dir.AppendASCII("chrome");
#elif defined(OS_LINUX)
    dir = dir.AppendASCII("chrome_linux");
#elif defined(OS_MACOSX)
    dir = dir.AppendASCII("chrome_mac");
#endif
    browser_directory_ = dir;
    UITest::SetUp();
  }
};

TEST_F(DromaeoTest, Perf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest();
}

TEST_F(DromaeoReferenceTest, Perf) {
  if (!CommandLine::ForCurrentProcess()->HasSwitch(kRunDromaeo))
    return;

  RunTest();
}

}  // namespace
<|endoftext|>


<commit_before>//===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/PathV2.h"
#include "llvm/Support/ErrorHandling.h"

#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::sys;

#define ASSERT_NO_ERROR(x) \
  if (error_code ec = x) { \
    SmallString<128> Message; \
    GTEST_FATAL_FAILURE_((Twine(#x ": did not return errc::success.\n") + \
                         "error number: " + Twine(ec.value()) + "\n" + \
                         "error message: " + \
                     ec.message()).toNullTerminatedStringRef(Message).data()); \
  } else {}

namespace {

TEST(Support, Path) {
  SmallVector<StringRef, 40> paths;
  paths.push_back("");
  paths.push_back(".");
  paths.push_back("..");
  paths.push_back("foo");
  paths.push_back("/");
  paths.push_back("/foo");
  paths.push_back("foo/");
  paths.push_back("/foo/");
  paths.push_back("foo/bar");
  paths.push_back("/foo/bar");
  paths.push_back("//net");
  paths.push_back("//net/foo");
  paths.push_back("///foo///");
  paths.push_back("///foo///bar");
  paths.push_back("/.");
  paths.push_back("./");
  paths.push_back("/..");
  paths.push_back("../");
  paths.push_back("foo/.");
  paths.push_back("foo/..");
  paths.push_back("foo/./");
  paths.push_back("foo/./bar");
  paths.push_back("foo/..");
  paths.push_back("foo/../");
  paths.push_back("foo/../bar");
  paths.push_back("c:");
  paths.push_back("c:/");
  paths.push_back("c:foo");
  paths.push_back("c:/foo");
  paths.push_back("c:foo/");
  paths.push_back("c:/foo/");
  paths.push_back("c:/foo/bar");
  paths.push_back("prn:");
  paths.push_back("c:\\");
  paths.push_back("c:foo");
  paths.push_back("c:\\foo");
  paths.push_back("c:foo\\");
  paths.push_back("c:\\foo\\");
  paths.push_back("c:\\foo/");
  paths.push_back("c:/foo\\bar");

  for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
                                                  e = paths.end();
                                                  i != e;
                                                  ++i) {
    for (sys::path::const_iterator ci = sys::path::begin(*i),
                                   ce = sys::path::end(*i);
                                   ci != ce;
                                   ++ci) {
      ASSERT_FALSE(ci->empty());
    }

#if 0 // Valgrind is whining about this.
    outs() << "    Reverse Iteration: [";
    for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
                                     ce = sys::path::rend(*i);
                                     ci != ce;
                                     ++ci) {
      outs() << *ci << ',';
    }
    outs() << "]\n";
#endif

    path::has_root_path(*i);
    path::root_path(*i);
    path::has_root_name(*i);
    path::root_name(*i);
    path::has_root_directory(*i);
    path::root_directory(*i);
    path::has_parent_path(*i);
    path::parent_path(*i);
    path::has_filename(*i);
    path::filename(*i);
    path::has_stem(*i);
    path::stem(*i);
    path::has_extension(*i);
    path::extension(*i);
    path::is_absolute(*i);
    path::is_relative(*i);

    SmallString<128> temp_store;
    temp_store = *i;
    ASSERT_NO_ERROR(fs::make_absolute(temp_store));
    temp_store = *i;
    path::remove_filename(temp_store);

    temp_store = *i;
    path::replace_extension(temp_store, "ext");
    StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
    stem = path::stem(filename);
    ext  = path::extension(filename);
    EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());

    path::native(*i, temp_store);
  }
}

class FileSystemTest : public testing::Test {
protected:
  /// Unique temporary directory in which all created filesystem entities must
  /// be placed. It is recursively removed at the end of each test.
  SmallString<128> TestDirectory;

  virtual void SetUp() {
    int fd;
    ASSERT_NO_ERROR(
      fs::unique_file("file-system-test-%%-%%-%%-%%/test-directory.anchor", fd,
                      TestDirectory));
    // We don't care about this specific file.
    ::close(fd);
    TestDirectory = path::parent_path(TestDirectory);
    errs() << "Test Directory: " << TestDirectory << '\n';
    errs().flush();
  }

  virtual void TearDown() {
    uint32_t removed;
    ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));
  }
};

TEST_F(FileSystemTest, TempFiles) {
  // Create a temp file.
  int FileDescriptor;
  SmallString<64> TempPath;
  ASSERT_NO_ERROR(
    fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));

  // Make sure it exists.
  bool TempFileExists;
  ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Create another temp tile.
  int FD2;
  SmallString<64> TempPath2;
  ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2));
  ASSERT_NE(TempPath.str(), TempPath2.str());

  // Try to copy the first to the second.
  EXPECT_EQ(
    fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists);

  ::close(FD2);
  // Try again with the proper options.
  ASSERT_NO_ERROR(fs::copy_file(Twine(TempPath), Twine(TempPath2),
                                fs::copy_option::overwrite_if_exists));
  // Remove Temp2.
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Make sure Temp2 doesn't exist.
  ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
  EXPECT_FALSE(TempFileExists);

  // Create a hard link to Temp1.
  ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2)));
  bool equal;
  ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
  EXPECT_TRUE(equal);

  // Remove Temp1.
  ::close(FileDescriptor);
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Remove the hard link.
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Make sure Temp1 doesn't exist.
  ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
  EXPECT_FALSE(TempFileExists);
}

TEST_F(FileSystemTest, DirectoryIteration) {
  error_code ec;
  for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) {
    if (ec) {
      errs() << ec.message() << '\n';
      errs().flush();
      report_fatal_error("Directory iteration failed!");
    }
  }
}

} // anonymous namespace
<commit_msg>UnitTests/Path: More ASSERT_NO_ERROR cleanup.<commit_after>//===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/PathV2.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::sys;

#define ASSERT_NO_ERROR(x) \
  if (error_code ASSERT_NO_ERROR_ec = x) { \
    SmallString<128> MessageStorage; \
    raw_svector_ostream Message(MessageStorage); \
    Message << #x ": did not return errc::success.\n" \
            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
    GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
  } else {}

namespace {

TEST(Support, Path) {
  SmallVector<StringRef, 40> paths;
  paths.push_back("");
  paths.push_back(".");
  paths.push_back("..");
  paths.push_back("foo");
  paths.push_back("/");
  paths.push_back("/foo");
  paths.push_back("foo/");
  paths.push_back("/foo/");
  paths.push_back("foo/bar");
  paths.push_back("/foo/bar");
  paths.push_back("//net");
  paths.push_back("//net/foo");
  paths.push_back("///foo///");
  paths.push_back("///foo///bar");
  paths.push_back("/.");
  paths.push_back("./");
  paths.push_back("/..");
  paths.push_back("../");
  paths.push_back("foo/.");
  paths.push_back("foo/..");
  paths.push_back("foo/./");
  paths.push_back("foo/./bar");
  paths.push_back("foo/..");
  paths.push_back("foo/../");
  paths.push_back("foo/../bar");
  paths.push_back("c:");
  paths.push_back("c:/");
  paths.push_back("c:foo");
  paths.push_back("c:/foo");
  paths.push_back("c:foo/");
  paths.push_back("c:/foo/");
  paths.push_back("c:/foo/bar");
  paths.push_back("prn:");
  paths.push_back("c:\\");
  paths.push_back("c:foo");
  paths.push_back("c:\\foo");
  paths.push_back("c:foo\\");
  paths.push_back("c:\\foo\\");
  paths.push_back("c:\\foo/");
  paths.push_back("c:/foo\\bar");

  for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
                                                  e = paths.end();
                                                  i != e;
                                                  ++i) {
    for (sys::path::const_iterator ci = sys::path::begin(*i),
                                   ce = sys::path::end(*i);
                                   ci != ce;
                                   ++ci) {
      ASSERT_FALSE(ci->empty());
    }

#if 0 // Valgrind is whining about this.
    outs() << "    Reverse Iteration: [";
    for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
                                     ce = sys::path::rend(*i);
                                     ci != ce;
                                     ++ci) {
      outs() << *ci << ',';
    }
    outs() << "]\n";
#endif

    path::has_root_path(*i);
    path::root_path(*i);
    path::has_root_name(*i);
    path::root_name(*i);
    path::has_root_directory(*i);
    path::root_directory(*i);
    path::has_parent_path(*i);
    path::parent_path(*i);
    path::has_filename(*i);
    path::filename(*i);
    path::has_stem(*i);
    path::stem(*i);
    path::has_extension(*i);
    path::extension(*i);
    path::is_absolute(*i);
    path::is_relative(*i);

    SmallString<128> temp_store;
    temp_store = *i;
    ASSERT_NO_ERROR(fs::make_absolute(temp_store));
    temp_store = *i;
    path::remove_filename(temp_store);

    temp_store = *i;
    path::replace_extension(temp_store, "ext");
    StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
    stem = path::stem(filename);
    ext  = path::extension(filename);
    EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());

    path::native(*i, temp_store);
  }
}

class FileSystemTest : public testing::Test {
protected:
  /// Unique temporary directory in which all created filesystem entities must
  /// be placed. It is recursively removed at the end of each test.
  SmallString<128> TestDirectory;

  virtual void SetUp() {
    int fd;
    ASSERT_NO_ERROR(
      fs::unique_file("file-system-test-%%-%%-%%-%%/test-directory.anchor", fd,
                      TestDirectory));
    // We don't care about this specific file.
    ::close(fd);
    TestDirectory = path::parent_path(TestDirectory);
    errs() << "Test Directory: " << TestDirectory << '\n';
    errs().flush();
  }

  virtual void TearDown() {
    uint32_t removed;
    ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));
  }
};

TEST_F(FileSystemTest, TempFiles) {
  // Create a temp file.
  int FileDescriptor;
  SmallString<64> TempPath;
  ASSERT_NO_ERROR(
    fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));

  // Make sure it exists.
  bool TempFileExists;
  ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Create another temp tile.
  int FD2;
  SmallString<64> TempPath2;
  ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2));
  ASSERT_NE(TempPath.str(), TempPath2.str());

  // Try to copy the first to the second.
  EXPECT_EQ(
    fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists);

  ::close(FD2);
  // Try again with the proper options.
  ASSERT_NO_ERROR(fs::copy_file(Twine(TempPath), Twine(TempPath2),
                                fs::copy_option::overwrite_if_exists));
  // Remove Temp2.
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Make sure Temp2 doesn't exist.
  ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
  EXPECT_FALSE(TempFileExists);

  // Create a hard link to Temp1.
  ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2)));
  bool equal;
  ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
  EXPECT_TRUE(equal);

  // Remove Temp1.
  ::close(FileDescriptor);
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Remove the hard link.
  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
  EXPECT_TRUE(TempFileExists);

  // Make sure Temp1 doesn't exist.
  ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
  EXPECT_FALSE(TempFileExists);
}

TEST_F(FileSystemTest, DirectoryIteration) {
  error_code ec;
  for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
    ASSERT_NO_ERROR(ec);
}
  }
}

} // anonymous namespace
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display";
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL";
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<commit_msg>Unset EGL context<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display";
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL";
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/framework/partial_tensor_shape.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/dataset.h"
#include "tensorflow/core/lib/random/philox_random.h"
#include "tensorflow/core/lib/random/simple_philox.h"
#include "tensorflow/core/lib/random/random.h"
#include "tensorflow/core/lib/random/random_distributions.h"

namespace tensorflow {
namespace data {
namespace {

// See documentation in ../../ops/dataset_ops.cc for a high-level
// description of the following op.

class SamplingDatasetOp : public UnaryDatasetOpKernel {
 public:
  explicit SamplingDatasetOp(OpKernelConstruction* ctx)
      : UnaryDatasetOpKernel(ctx) {}

 protected:
  // Create a new SamplingDatasetOp::Dataset, and return it as the output.
  void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
                   DatasetBase** output) override {
    float rate;
    int64 seed;
    int64 seed2;
    OP_REQUIRES_OK(ctx, ParseScalarArgument<float>(ctx, "rate", &rate));
    OP_REQUIRES_OK(ctx, ParseScalarArgument<int64>(ctx, "seed", &seed));
    OP_REQUIRES_OK(ctx, ParseScalarArgument<int64>(ctx, "seed2", &seed2));

    if (seed == 0 && seed2 == 0) {
      seed = random::New64();
      seed2 = random::New64();
    }
    *output = new Dataset(ctx, rate, seed, seed2, input);
  }

 private:
  class Dataset : public DatasetBase {
   public:
    Dataset(OpKernelContext* ctx, float rate, int64 seed, int64 seed2,
            const DatasetBase* input)
        : DatasetBase(DatasetContext(ctx)), rate_(rate), seed_(seed),
          seed2_(seed2), input_(input) {
      input_->Ref();
    }

    ~Dataset() override { input_->Unref(); }

    std::unique_ptr<IteratorBase> MakeIteratorInternal(
        const string& prefix) const override {
      return std::unique_ptr<IteratorBase>(
        new Iterator({this, strings::StrCat(prefix, "::Sampling")}, seed_, seed2_));
    }

    const DataTypeVector& output_dtypes() const override {
      return input_->output_dtypes();
    }

    const std::vector<PartialTensorShape>& output_shapes() const override {
      return input_->output_shapes();
    }

    string DebugString() const override { return "SamplingDatasetOp::Dataset"; }

   protected:
    Status AsGraphDefInternal(SerializationContext* ctx,
                              DatasetGraphDefBuilder* b,
                              Node** output) const override {
      Node* input_graph_node = nullptr;
      TF_RETURN_IF_ERROR(b->AddInputDataset(ctx, input_, &input_graph_node));
      Node* rate = nullptr;
      Node* seed = nullptr;
      Node* seed2 = nullptr;
      TF_RETURN_IF_ERROR(b->AddScalar(rate_, &rate));
      TF_RETURN_IF_ERROR(b->AddScalar(seed_, &seed));
      TF_RETURN_IF_ERROR(b->AddScalar(seed2_, &seed2));
      TF_RETURN_IF_ERROR(b->AddDataset(this, {input_graph_node, rate, seed,
                                              seed2}, output));
      return Status::OK();
    }

   private:
    class Iterator : public DatasetIterator<Dataset> {
     public:
      explicit Iterator(const Params& params, int64 seed, int64 seed2)
          : DatasetIterator<Dataset>(params),
            seed_(seed),
            seed2_(seed2),
            parent_generator_(seed, seed2),
            generator_(&parent_generator_) {
      }

      Status Initialize(IteratorContext* ctx) override {
        return dataset()->input_->MakeIterator(ctx, prefix(), &input_impl_);
      }

      Status GetNextInternal(IteratorContext* ctx,
                             std::vector<Tensor>* out_tensors,
                             bool* end_of_sequence) override {
        bool rand_val_hit;
        do {
          {
            tf_shared_lock l(mu_);
            if (!input_impl_) {
              *end_of_sequence = true;
              return Status::OK();
            }
            TF_RETURN_IF_ERROR(
                input_impl_->GetNext(ctx, out_tensors, end_of_sequence));
          }
          if (*end_of_sequence) {
            mutex_lock l(mu_);
            input_impl_.reset();
            return Status::OK();
          }

          // generate a number from random uniform [0, 1)
          float rand_val = Random();
          rand_val_hit = rand_val < dataset()->rate_;
          if (!rand_val_hit) {
            // Clear the output tensor list since it doesn't match.
            out_tensors->clear();
          }
        } while (!rand_val_hit);
        *end_of_sequence = false;
        return Status::OK();
      }

     protected:
      void ResetRngs() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
        // Reset the generators based on the current iterator seeds.
        parent_generator_ = random::PhiloxRandom(seed_, seed2_);
        generator_ =
          random::SimplePhilox(&parent_generator_);

        parent_generator_.Skip(num_random_samples_);
      }

      Status SaveInternal(IteratorStateWriter* writer) override {
        mutex_lock l(mu_);
        // Save state needed to restore the random number generators.
        TF_RETURN_IF_ERROR(writer->WriteScalar(
            this->full_name("num_random_samples"), num_random_samples_));
        TF_RETURN_IF_ERROR(writer->WriteScalar(this->full_name("seed"), seed_));
        TF_RETURN_IF_ERROR(
            writer->WriteScalar(this->full_name("seed2"), seed2_));

        if (input_impl_) {
          TF_RETURN_IF_ERROR(SaveInput(writer, input_impl_));
        } else {
          TF_RETURN_IF_ERROR(
              writer->WriteScalar(full_name("input_impl_empty"), ""));
        }
        return Status::OK();
      }

      Status RestoreInternal(IteratorContext* ctx,
                             IteratorStateReader* reader) override {
        mutex_lock l(mu_);
        // Restore the random number generators.
        TF_RETURN_IF_ERROR(reader->ReadScalar(
            this->full_name("num_random_samples"), &num_random_samples_));
        TF_RETURN_IF_ERROR(reader->ReadScalar(this->full_name("seed"), &seed_));
        TF_RETURN_IF_ERROR(
            reader->ReadScalar(this->full_name("seed2"), &seed2_));
        ResetRngs();

        if (!reader->Contains(full_name("input_impl_empty"))) {
          TF_RETURN_IF_ERROR(RestoreInput(ctx, reader, input_impl_));
        } else {
          input_impl_.reset();
        }
        return Status::OK();
      }

      mutex mu_;
      int64 seed_ GUARDED_BY(mu_);
      int64 seed2_ GUARDED_BY(mu_);

     private:
      std::unique_ptr<IteratorBase> input_impl_ GUARDED_BY(mu_);

      float Random()
          EXCLUSIVE_LOCKS_REQUIRED(mu_) {
        num_random_samples_++;
        auto out = generator_.RandFloat();
        return out;
      }

      // random util
      random::PhiloxRandom parent_generator_ GUARDED_BY(mu_);
      random::SimplePhilox generator_ GUARDED_BY(mu_);
      int64 num_random_samples_ GUARDED_BY(mu_) = 0;
    };

    const float rate_;
    const int64 seed_, seed2_;
    const DatasetBase* const input_;
  };
};

REGISTER_KERNEL_BUILDER(Name("ExperimentalSamplingDataset").Device(DEVICE_CPU),
                        SamplingDatasetOp);

}  // namespace
}  // namespace data
}  // namespace tensorflow
<commit_msg>Add lock in Random()<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/framework/partial_tensor_shape.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/dataset.h"
#include "tensorflow/core/lib/random/philox_random.h"
#include "tensorflow/core/lib/random/simple_philox.h"
#include "tensorflow/core/lib/random/random.h"
#include "tensorflow/core/lib/random/random_distributions.h"

namespace tensorflow {
namespace data {
namespace {

// See documentation in ../../ops/dataset_ops.cc for a high-level
// description of the following op.

class SamplingDatasetOp : public UnaryDatasetOpKernel {
 public:
  explicit SamplingDatasetOp(OpKernelConstruction* ctx)
      : UnaryDatasetOpKernel(ctx) {}

 protected:
  // Create a new SamplingDatasetOp::Dataset, and return it as the output.
  void MakeDataset(OpKernelContext* ctx, DatasetBase* input,
                   DatasetBase** output) override {
    float rate;
    int64 seed;
    int64 seed2;
    OP_REQUIRES_OK(ctx, ParseScalarArgument<float>(ctx, "rate", &rate));
    OP_REQUIRES_OK(ctx, ParseScalarArgument<int64>(ctx, "seed", &seed));
    OP_REQUIRES_OK(ctx, ParseScalarArgument<int64>(ctx, "seed2", &seed2));

    if (seed == 0 && seed2 == 0) {
      seed = random::New64();
      seed2 = random::New64();
    }
    *output = new Dataset(ctx, rate, seed, seed2, input);
  }

 private:
  class Dataset : public DatasetBase {
   public:
    Dataset(OpKernelContext* ctx, float rate, int64 seed, int64 seed2,
            const DatasetBase* input)
        : DatasetBase(DatasetContext(ctx)), rate_(rate), seed_(seed),
          seed2_(seed2), input_(input) {
      input_->Ref();
    }

    ~Dataset() override { input_->Unref(); }

    std::unique_ptr<IteratorBase> MakeIteratorInternal(
        const string& prefix) const override {
      return std::unique_ptr<IteratorBase>(
        new Iterator({this, strings::StrCat(prefix, "::Sampling")}, seed_, seed2_));
    }

    const DataTypeVector& output_dtypes() const override {
      return input_->output_dtypes();
    }

    const std::vector<PartialTensorShape>& output_shapes() const override {
      return input_->output_shapes();
    }

    string DebugString() const override { return "SamplingDatasetOp::Dataset"; }

   protected:
    Status AsGraphDefInternal(SerializationContext* ctx,
                              DatasetGraphDefBuilder* b,
                              Node** output) const override {
      Node* input_graph_node = nullptr;
      TF_RETURN_IF_ERROR(b->AddInputDataset(ctx, input_, &input_graph_node));
      Node* rate = nullptr;
      Node* seed = nullptr;
      Node* seed2 = nullptr;
      TF_RETURN_IF_ERROR(b->AddScalar(rate_, &rate));
      TF_RETURN_IF_ERROR(b->AddScalar(seed_, &seed));
      TF_RETURN_IF_ERROR(b->AddScalar(seed2_, &seed2));
      TF_RETURN_IF_ERROR(b->AddDataset(this, {input_graph_node, rate, seed,
                                              seed2}, output));
      return Status::OK();
    }

   private:
    class Iterator : public DatasetIterator<Dataset> {
     public:
      explicit Iterator(const Params& params, int64 seed, int64 seed2)
          : DatasetIterator<Dataset>(params),
            seed_(seed),
            seed2_(seed2),
            parent_generator_(seed, seed2),
            generator_(&parent_generator_) {
      }

      Status Initialize(IteratorContext* ctx) override {
        return dataset()->input_->MakeIterator(ctx, prefix(), &input_impl_);
      }

      Status GetNextInternal(IteratorContext* ctx,
                             std::vector<Tensor>* out_tensors,
                             bool* end_of_sequence) override {
        bool rand_val_hit;
        do {
          {
            tf_shared_lock l(mu_);
            if (!input_impl_) {
              *end_of_sequence = true;
              return Status::OK();
            }
            TF_RETURN_IF_ERROR(
                input_impl_->GetNext(ctx, out_tensors, end_of_sequence));
          }
          if (*end_of_sequence) {
            mutex_lock l(mu_);
            input_impl_.reset();
            return Status::OK();
          }

          // generate a number from random uniform [0, 1)
          float rand_val = Random();
          rand_val_hit = rand_val < dataset()->rate_;
          if (!rand_val_hit) {
            // Clear the output tensor list since it doesn't match.
            out_tensors->clear();
          }
        } while (!rand_val_hit);
        *end_of_sequence = false;
        return Status::OK();
      }

     protected:
      void ResetRngs() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
        // Reset the generators based on the current iterator seeds.
        parent_generator_ = random::PhiloxRandom(seed_, seed2_);
        generator_ =
          random::SimplePhilox(&parent_generator_);

        parent_generator_.Skip(num_random_samples_);
      }

      Status SaveInternal(IteratorStateWriter* writer) override {
        mutex_lock l(mu_);
        // Save state needed to restore the random number generators.
        TF_RETURN_IF_ERROR(writer->WriteScalar(
            this->full_name("num_random_samples"), num_random_samples_));
        TF_RETURN_IF_ERROR(writer->WriteScalar(this->full_name("seed"), seed_));
        TF_RETURN_IF_ERROR(
            writer->WriteScalar(this->full_name("seed2"), seed2_));

        if (input_impl_) {
          TF_RETURN_IF_ERROR(SaveInput(writer, input_impl_));
        } else {
          TF_RETURN_IF_ERROR(
              writer->WriteScalar(full_name("input_impl_empty"), ""));
        }
        return Status::OK();
      }

      Status RestoreInternal(IteratorContext* ctx,
                             IteratorStateReader* reader) override {
        mutex_lock l(mu_);
        // Restore the random number generators.
        TF_RETURN_IF_ERROR(reader->ReadScalar(
            this->full_name("num_random_samples"), &num_random_samples_));
        TF_RETURN_IF_ERROR(reader->ReadScalar(this->full_name("seed"), &seed_));
        TF_RETURN_IF_ERROR(
            reader->ReadScalar(this->full_name("seed2"), &seed2_));
        ResetRngs();

        if (!reader->Contains(full_name("input_impl_empty"))) {
          TF_RETURN_IF_ERROR(RestoreInput(ctx, reader, input_impl_));
        } else {
          input_impl_.reset();
        }
        return Status::OK();
      }

      mutex mu_;
      int64 seed_ GUARDED_BY(mu_);
      int64 seed2_ GUARDED_BY(mu_);

     private:
      std::unique_ptr<IteratorBase> input_impl_ GUARDED_BY(mu_);

      float Random() {
        mutex_lock l(mu_);
        num_random_samples_++;
        auto out = generator_.RandFloat();
        return out;
      }

      // random util
      random::PhiloxRandom parent_generator_ GUARDED_BY(mu_);
      random::SimplePhilox generator_ GUARDED_BY(mu_);
      int64 num_random_samples_ GUARDED_BY(mu_) = 0;
    };

    const float rate_;
    const int64 seed_, seed2_;
    const DatasetBase* const input_;
  };
};

REGISTER_KERNEL_BUILDER(Name("ExperimentalSamplingDataset").Device(DEVICE_CPU),
                        SamplingDatasetOp);

}  // namespace
}  // namespace data
}  // namespace tensorflow
<|endoftext|>