<commit_before>#include <activemq/ActiveMQTextMessage.h>
#include <cms/TopicConnectionFactory.h>
#include <cms/TopicConnection.h>
#include <cms/TopicSession.h>
#include <cms/TopicSubscriber.h>
#include <cms/Topic.h>
#include <activemq/ActiveMQConnectionFactory.h>
#include <cms/MessageListener.h>
#include <cms/ExceptionListener.h>
#include <cms/TopicPublisher.h>

#include <stdlib.h>
#include <sys/time.h>
#include <iostream>

using namespace std;

class Tester
:
    public cms::ExceptionListener,
    public cms::MessageListener
{
public:

    Tester(){numReceived = 0;}
    virtual ~Tester(){}

    void test(){

        try{

        	int numMessages = 1000;
        	int sleepTime = 10;

        	printf("Starting activemqcms test (sending %d messages and sleeping %d seconds) ...\n", numMessages, sleepTime );

            cms::TopicConnectionFactory* connectionFactory = new activemq::ActiveMQConnectionFactory( "127.0.0.1:61626" );
            cms::TopicConnection* connection = connectionFactory->createTopicConnection();
            connection->setExceptionListener( this );
            connection->start();
            cms::TopicSession* session = connection->createTopicSession( false );
            cms::Topic* topic = session->createTopic("mytopic");
            cms::TopicSubscriber* subscriber = session->createSubscriber( topic );
            subscriber->setMessageListener( this );
            cms::TopicPublisher* publisher = session->createPublisher( topic );

            const char* text = "this is a test!";
            cms::TextMessage* msg = session->createTextMessage( text );

            for( int ix=0; ix<numMessages; ++ix ){
                publisher->publish( msg );

                timespec sleepTime;
                sleepTime.tv_sec = 0;
                sleepTime.tv_nsec = 1000;
                nanosleep( &sleepTime, &sleepTime );
            }

            sleep( sleepTime );

            printf("received: %d\n", numReceived );

            delete publisher;
            subscriber->close();
            delete subscriber;
            session->close();
            delete session;
            connection->close();
            delete connection;
            delete connectionFactory;

        }catch( cms::CMSException& ex ){
            printf("StompTester::test() - %s\n", ex.getMessage() );
        }
    }

    virtual void onMessage( const cms::Message* message ){
        const cms::TextMessage* txtMsg = dynamic_cast<const cms::TextMessage*>(message);
        if( txtMsg == NULL ){
            printf("received non-text message\n" );
            return;
        }

        numReceived++;
        //printf( "[%d]: %s\n", ++ix, txtMsg->getMessage() );
    }

    virtual void onException( const cms::CMSException* error ){
        printf( "StompTester::onException() - %s\n", error->getMessage() );
    }

private:

    int numReceived;
};

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

        Tester tester;
        tester.test();

	}catch( ... ){
		printf("main - caught unknown exception\n" );
	}

	printf("done");

    cout.flush();

	return 0;
}

<commit_msg>added snippet example and Apache header<commit_after>/*
 * Copyright 2006 The Apache Software Foundation or its licensors, as
 * applicable.
 *
 * 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 <activemq/ActiveMQTextMessage.h>
#include <cms/TopicConnectionFactory.h>
#include <cms/TopicConnection.h>
#include <cms/TopicSession.h>
#include <cms/TopicSubscriber.h>
#include <cms/Topic.h>
#include <activemq/ActiveMQConnectionFactory.h>
#include <cms/MessageListener.h>
#include <cms/ExceptionListener.h>
#include <cms/TopicPublisher.h>

#include <stdlib.h>
#include <sys/time.h>
#include <iostream>

using namespace std;

class Tester
:
    public cms::ExceptionListener,
    public cms::MessageListener
{
public:

    Tester(){numReceived = 0;}
    virtual ~Tester(){}

    void test(){

        try{

        	int numMessages = 1000;
        	int sleepTime = 10;

        	printf("Starting activemqcms test (sending %d messages and sleeping %d seconds) ...\n", numMessages, sleepTime );

            // START SNIPPET: demo
            cms::TopicConnectionFactory* connectionFactory = new activemq::ActiveMQConnectionFactory( "127.0.0.1:61626" );
            cms::TopicConnection* connection = connectionFactory->createTopicConnection();
            connection->setExceptionListener( this );
            connection->start();
            cms::TopicSession* session = connection->createTopicSession( false );
            cms::Topic* topic = session->createTopic("mytopic");
            cms::TopicSubscriber* subscriber = session->createSubscriber( topic );
            subscriber->setMessageListener( this );
            cms::TopicPublisher* publisher = session->createPublisher( topic );

            const char* text = "this is a test!";
            cms::TextMessage* msg = session->createTextMessage( text );

            for( int ix=0; ix<numMessages; ++ix ){
                publisher->publish( msg );
                doSleep();
            }
            // END SNIPPET: demo

            sleep( sleepTime );

            printf("received: %d\n", numReceived );

            delete publisher;
            subscriber->close();
            delete subscriber;
            session->close();
            delete session;
            connection->close();
            delete connection;
            delete connectionFactory;

        }catch( cms::CMSException& ex ){
            printf("StompTester::test() - %s\n", ex.getMessage() );
        }
    }

    virtual void onMessage( const cms::Message* message ){
        const cms::TextMessage* txtMsg = dynamic_cast<const cms::TextMessage*>(message);
        if( txtMsg == NULL ){
            printf("received non-text message\n" );
            return;
        }

        numReceived++;
        //printf( "[%d]: %s\n", ++ix, txtMsg->getMessage() );
    }

    virtual void onException( const cms::CMSException* error ){
        printf( "StompTester::onException() - %s\n", error->getMessage() );
    }

    virtual void doSleep() {
        timespec sleepTime;
        sleepTime.tv_sec = 0;
        sleepTime.tv_nsec = 1000;
        nanosleep( &sleepTime, &sleepTime );
    }

private:

    int numReceived;
};

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

        Tester tester;
        tester.test();

	}catch( ... ){
		printf("main - caught unknown exception\n" );
	}

	printf("done");

    cout.flush();

	return 0;
}

<|endoftext|>


<commit_before>#include "cnn/grad-check.h"

#include <cassert>
#include <iostream>

#include "cnn/model.h"
#include "cnn/cnn.h"
#include "cnn/tensor.h"

using namespace std;

namespace cnn {

void CheckGrad(Model& m, ComputationGraph& g) {
  float alpha = 1e-4;
  float E = as_scalar(g.forward());
  g.backward();

  bool flag = false;
  const vector<Parameters*>& params = m.parameters_list();
  for (auto pp : params) {
    cerr << "\nPARAMETERS " << pp << endl;
    Parameters& p = *pp;
    size_t ts = p.dim.size();
    for (size_t i = 0; i < ts; ++i) {
      float old = p.values.v[i];
      p.values.v[i] = old - alpha;
      float E_left = as_scalar(g.forward());

      p.values.v[i] = old + alpha;
      float E_right = as_scalar(g.forward());
      float g = (E_right - E_left) / (2 * alpha);
      float f = fabs(g - p.g.v[i]);
      float m = max(fabs(g), fabs(p.g.v[i]));
      if (m > 0.f) f /= m;
      if (f > 0.1) { flag = true; cerr << "*** "; }
      cerr << p.g.v[i] << ' ' << g << endl;
    }
  }
  if (flag) {
    cerr << "\n*** GRADIENT CHECK FAILED ***\n";
  } else {
    cerr << "\nGRADIENT CHECK PASSED\n";
  }
//  const vector<LookupParameters*>& lookup_params = m.lookup_parameters_list();
}

}

<commit_msg>lookup table check<commit_after>#include "cnn/grad-check.h"

#include <cassert>
#include <iostream>

#include "cnn/model.h"
#include "cnn/cnn.h"
#include "cnn/tensor.h"

using namespace std;

namespace cnn {

void CheckGrad(Model& m, ComputationGraph& g) {
  float alpha = 5e-4;
  float E = as_scalar(g.forward());
  g.backward();

  bool flag = false;
  const vector<Parameters*>& params = m.parameters_list();
  for (auto pp : params) {
    cerr << "\nPARAMETERS " << pp << endl;
    Parameters& p = *pp;
    size_t ts = p.dim.size();
    for (size_t i = 0; i < ts; ++i) {
      float old = p.values.v[i];
      p.values.v[i] = old - alpha;
      float E_left = as_scalar(g.forward());

      p.values.v[i] = old + alpha;
      float E_right = as_scalar(g.forward());
      float g = (E_right - E_left) / (2 * alpha);
      float f = fabs(g - p.g.v[i]);
      float m = max(fabs(g), fabs(p.g.v[i]));
      if (f > 0.1) {
        if (m > 0.f) f /= m;
        if (f > 0.1) { flag = true; cerr << "***[" << f << "] "; }
      }
      cerr << p.g.v[i] << ' ' << g << endl;
    }
  }

  const vector<LookupParameters*>& lookup_params = m.lookup_parameters_list();
  for (auto pp : lookup_params) {
    cerr << "\nLOOKUP PARAMETERS " << pp << endl;
    LookupParameters& p = *pp;
    size_t ts = p.dim.size();
    for (unsigned j : p.non_zero_grads) {
      cerr << "OBJECT=" << j << endl;
      Tensor& v = p.values[j];
      Tensor& ag = p.grads[j];
      for (size_t i = 0; i < ts; ++i) {
        float old = v.v[i];
        v.v[i] = old - alpha;
        float E_left = as_scalar(g.forward());

        v.v[i] = old + alpha;
        float E_right = as_scalar(g.forward());
        float g = (E_right - E_left) / (2 * alpha);
        float f = fabs(g - ag.v[i]);
        float m = max(fabs(g), fabs(ag.v[i]));
        if (f > 0.1) {
          if (m > 0.f) f /= m;
          if (f > 0.1) { flag = true; cerr << "*** "; }
        }
        cerr << ag.v[i] << ' ' << g << endl;
      }
    }
  }

  if (flag) {
    cerr << "\n*** GRADIENT CHECK FAILED ***\n";
  } else {
    cerr << "\nGRADIENT CHECK PASSED\n";
  }
}

}

<|endoftext|>


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

#include "dbus/bus.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/stringprintf.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"

namespace {

// Used for success ratio histograms. 1 for success, 0 for failure.
const int kSuccessRatioHistogramMaxValue = 2;

// Gets the absolute signal name by concatenating the interface name and
// the signal name. Used for building keys for method_table_ in
// ObjectProxy.
std::string GetAbsoluteSignalName(
    const std::string& interface_name,
    const std::string& signal_name) {
  return interface_name + "." + signal_name;
}

}  // namespace

namespace dbus {

ObjectProxy::ObjectProxy(Bus* bus,
                         const std::string& service_name,
                         const std::string& object_path)
    : bus_(bus),
      service_name_(service_name),
      object_path_(object_path),
      filter_added_(false) {
}

ObjectProxy::~ObjectProxy() {
}

// Originally we tried to make |method_call| a const reference, but we
// gave up as dbus_connection_send_with_reply_and_block() takes a
// non-const pointer of DBusMessage as the second parameter.
Response* ObjectProxy::CallMethodAndBlock(MethodCall* method_call,
                                          int timeout_ms) {
  bus_->AssertOnDBusThread();

  if (!bus_->Connect())
    return NULL;

  method_call->SetDestination(service_name_);
  method_call->SetPath(object_path_);
  DBusMessage* request_message = method_call->raw_message();

  ScopedDBusError error;

  // Send the message synchronously.
  const base::TimeTicks start_time = base::TimeTicks::Now();
  DBusMessage* response_message =
      bus_->SendWithReplyAndBlock(request_message, timeout_ms, error.get());
  // Record if the method call is successful, or not. 1 if successful.
  UMA_HISTOGRAM_ENUMERATION("DBus.SyncMethodCallSuccess",
                            response_message ? 1 : 0,
                            kSuccessRatioHistogramMaxValue);

  if (!response_message) {
    LOG(ERROR) << "Failed to call method: "
               << (error.is_set() ? error.message() : "");
    return NULL;
  }
  // Record time spent for the method call. Don't include failures.
  UMA_HISTOGRAM_TIMES("DBus.SyncMethodCallTime",
                      base::TimeTicks::Now() - start_time);

  return Response::FromRawMessage(response_message);
}

void ObjectProxy::CallMethod(MethodCall* method_call,
                             int timeout_ms,
                             ResponseCallback callback) {
  bus_->AssertOnOriginThread();

  method_call->SetDestination(service_name_);
  method_call->SetPath(object_path_);
  // Increment the reference count so we can safely reference the
  // underlying request message until the method call is complete. This
  // will be unref'ed in StartAsyncMethodCall().
  DBusMessage* request_message = method_call->raw_message();
  dbus_message_ref(request_message);

  const base::TimeTicks start_time = base::TimeTicks::Now();
  base::Closure task = base::Bind(&ObjectProxy::StartAsyncMethodCall,
                                  this,
                                  timeout_ms,
                                  request_message,
                                  callback,
                                  start_time);
  // Wait for the response in the D-Bus thread.
  bus_->PostTaskToDBusThread(FROM_HERE, task);
}

void ObjectProxy::ConnectToSignal(const std::string& interface_name,
                                  const std::string& signal_name,
                                  SignalCallback signal_callback,
                                  OnConnectedCallback on_connected_callback) {
  bus_->AssertOnOriginThread();

  bus_->PostTaskToDBusThread(FROM_HERE,
                             base::Bind(&ObjectProxy::ConnectToSignalInternal,
                                        this,
                                        interface_name,
                                        signal_name,
                                        signal_callback,
                                        on_connected_callback));
}

void ObjectProxy::Detach() {
  bus_->AssertOnDBusThread();

  if (filter_added_) {
    if (!bus_->RemoveFilterFunction(&ObjectProxy::HandleMessageThunk, this)) {
      LOG(ERROR) << "Failed to remove filter function";
    }
  }

  for (size_t i = 0; i < match_rules_.size(); ++i) {
    ScopedDBusError error;
    bus_->RemoveMatch(match_rules_[i], error.get());
    if (error.is_set()) {
      // There is nothing we can do to recover, so just print the error.
      LOG(ERROR) << "Failed to remove match rule: " << match_rules_[i];
    }
  }
}

ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData(
    ObjectProxy* in_object_proxy,
    ResponseCallback in_response_callback,
    base::TimeTicks in_start_time)
    : object_proxy(in_object_proxy),
      response_callback(in_response_callback),
      start_time(in_start_time) {
}

ObjectProxy::OnPendingCallIsCompleteData::~OnPendingCallIsCompleteData() {
}

void ObjectProxy::StartAsyncMethodCall(int timeout_ms,
                                       DBusMessage* request_message,
                                       ResponseCallback response_callback,
                                       base::TimeTicks start_time) {
  bus_->AssertOnDBusThread();

  if (!bus_->Connect() || !bus_->SetUpAsyncOperations()) {
    // In case of a failure, run the callback with NULL response, that
    // indicates a failure.
    DBusMessage* response_message = NULL;
    base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
                                    this,
                                    response_callback,
                                    start_time,
                                    response_message);
    bus_->PostTaskToOriginThread(FROM_HERE, task);
    return;
  }

  DBusPendingCall* pending_call = NULL;

  bus_->SendWithReply(request_message, &pending_call, timeout_ms);

  // Prepare the data we'll be passing to OnPendingCallIsCompleteThunk().
  // The data will be deleted in OnPendingCallIsCompleteThunk().
  OnPendingCallIsCompleteData* data =
      new OnPendingCallIsCompleteData(this, response_callback, start_time);

  // This returns false only when unable to allocate memory.
  const bool success = dbus_pending_call_set_notify(
      pending_call,
      &ObjectProxy::OnPendingCallIsCompleteThunk,
      data,
      NULL);
  CHECK(success) << "Unable to allocate memory";
  dbus_pending_call_unref(pending_call);

  // It's now safe to unref the request message.
  dbus_message_unref(request_message);
}

void ObjectProxy::OnPendingCallIsComplete(DBusPendingCall* pending_call,
                                          ResponseCallback response_callback,
                                          base::TimeTicks start_time) {
  bus_->AssertOnDBusThread();

  DBusMessage* response_message = dbus_pending_call_steal_reply(pending_call);
  base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
                                  this,
                                  response_callback,
                                  start_time,
                                  response_message);
  bus_->PostTaskToOriginThread(FROM_HERE, task);
}

void ObjectProxy::RunResponseCallback(ResponseCallback response_callback,
                                      base::TimeTicks start_time,
                                      DBusMessage* response_message) {
  bus_->AssertOnOriginThread();

  bool response_callback_called = false;
  if (!response_message) {
    // The response is not received.
    response_callback.Run(NULL);
  } else if (dbus_message_get_type(response_message) ==
             DBUS_MESSAGE_TYPE_ERROR) {
    // This will take |response_message| and release (unref) it.
    scoped_ptr<dbus::ErrorResponse> error_response(
        dbus::ErrorResponse::FromRawMessage(response_message));
    // Error message may contain the error message as string.
    dbus::MessageReader reader(error_response.get());
    std::string error_message;
    reader.PopString(&error_message);
    LOG(ERROR) << "Failed to call method: " << error_response->GetErrorName()
               << ": " << error_message;
    // We don't give the error message to the callback.
    response_callback.Run(NULL);
  } else {
    // This will take |response_message| and release (unref) it.
    scoped_ptr<dbus::Response> response(
        dbus::Response::FromRawMessage(response_message));
    // The response is successfully received.
    response_callback.Run(response.get());
    response_callback_called = true;
    // Record time spent for the method call. Don't include failures.
    UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime",
                        base::TimeTicks::Now() - start_time);
  }
  // Record if the method call is successful, or not. 1 if successful.
  UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess",
                            response_callback_called,
                            kSuccessRatioHistogramMaxValue);
}

void ObjectProxy::OnPendingCallIsCompleteThunk(DBusPendingCall* pending_call,
                                               void* user_data) {
  OnPendingCallIsCompleteData* data =
      reinterpret_cast<OnPendingCallIsCompleteData*>(user_data);
  ObjectProxy* self = data->object_proxy;
  self->OnPendingCallIsComplete(pending_call,
                                data->response_callback,
                                data->start_time);
  delete data;
}

void ObjectProxy::ConnectToSignalInternal(
    const std::string& interface_name,
    const std::string& signal_name,
    SignalCallback signal_callback,
    OnConnectedCallback on_connected_callback) {
  bus_->AssertOnDBusThread();

  // Check if the object is already connected to the signal.
  const std::string absolute_signal_name =
      GetAbsoluteSignalName(interface_name, signal_name);
  if (method_table_.find(absolute_signal_name) != method_table_.end()) {
    LOG(ERROR) << "The object proxy is already connected to "
               << absolute_signal_name;
    return;
  }

  // Will become true, if everything is successful.
  bool success = false;

  if (bus_->Connect() && bus_->SetUpAsyncOperations()) {
    // We should add the filter only once. Otherwise, HandleMessage() will
    // be called more than once.
    if (!filter_added_) {
      if (bus_->AddFilterFunction(&ObjectProxy::HandleMessageThunk, this)) {
        filter_added_ = true;
      } else {
        LOG(ERROR) << "Failed to add filter function";
      }
    }
    // Add a match rule so the signal goes through HandleMessage().
    //
    // We don't restrict the sender object path to be |object_path_| here,
    // to make it easy to test D-Bus signal handling with dbus-send, that
    // uses "/" as the sender object path. We can make the object path
    // restriction customizable when it becomes necessary.
    const std::string match_rule =
        base::StringPrintf("type='signal', interface='%s'",
                           interface_name.c_str());
    ScopedDBusError error;
    bus_->AddMatch(match_rule, error.get());;
    if (error.is_set()) {
      LOG(ERROR) << "Failed to add match rule: " << match_rule;
    } else {
      // Store the match rule, so that we can remove this in Detach().
      match_rules_.push_back(match_rule);
      // Add the signal callback to the method table.
      method_table_[absolute_signal_name] = signal_callback;
      success = true;
    }
  }

  // Run on_connected_callback in the origin thread.
  bus_->PostTaskToOriginThread(
      FROM_HERE,
      base::Bind(&ObjectProxy::OnConnected,
                 this,
                 on_connected_callback,
                 interface_name,
                 signal_name,
                 success));
}

void ObjectProxy::OnConnected(OnConnectedCallback on_connected_callback,
                              const std::string& interface_name,
                              const std::string& signal_name,
                              bool success) {
  bus_->AssertOnOriginThread();

  on_connected_callback.Run(interface_name, signal_name, success);
}

DBusHandlerResult ObjectProxy::HandleMessage(
    DBusConnection* connection,
    DBusMessage* raw_message) {
  bus_->AssertOnDBusThread();
  if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  // raw_message will be unrefed on exit of the function. Increment the
  // reference so we can use it in Signal.
  dbus_message_ref(raw_message);
  scoped_ptr<Signal> signal(
      Signal::FromRawMessage(raw_message));

  VLOG(1) << "Signal received: " << signal->ToString();

  const std::string interface = signal->GetInterface();
  const std::string member = signal->GetMember();

  // Check if we know about the signal.
  const std::string absolute_signal_name = GetAbsoluteSignalName(
      interface, member);
  MethodTable::const_iterator iter = method_table_.find(absolute_signal_name);
  if (iter == method_table_.end()) {
    // Don't know about the signal.
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }

  const base::TimeTicks start_time = base::TimeTicks::Now();
  if (bus_->HasDBusThread()) {
    // Post a task to run the method in the origin thread.
    // Transfer the ownership of |signal| to RunMethod().
    // |released_signal| will be deleted in RunMethod().
    Signal* released_signal = signal.release();
    bus_->PostTaskToOriginThread(FROM_HERE,
                                 base::Bind(&ObjectProxy::RunMethod,
                                            this,
                                            start_time,
                                            iter->second,
                                            released_signal));
  } else {
    const base::TimeTicks start_time = base::TimeTicks::Now();
    // If the D-Bus thread is not used, just call the callback on the
    // current thread. Transfer the ownership of |signal| to RunMethod().
    Signal* released_signal = signal.release();
    RunMethod(start_time, iter->second, released_signal);
  }

  return DBUS_HANDLER_RESULT_HANDLED;
}

void ObjectProxy::RunMethod(base::TimeTicks start_time,
                            SignalCallback signal_callback,
                            Signal* signal) {
  bus_->AssertOnOriginThread();

  signal_callback.Run(signal);
  delete signal;
  // Record time spent for handling the signal.
  UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime",
                      base::TimeTicks::Now() - start_time);
}

DBusHandlerResult ObjectProxy::HandleMessageThunk(
    DBusConnection* connection,
    DBusMessage* raw_message,
    void* user_data) {
  ObjectProxy* self = reinterpret_cast<ObjectProxy*>(user_data);
  return self->HandleMessage(connection, raw_message);
}

}  // namespace dbus
<commit_msg>dbus: Silence VLOG(1) spam from ObjectProxy::HandleMessage().<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "dbus/bus.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/stringprintf.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/scoped_dbus_error.h"

namespace {

// Used for success ratio histograms. 1 for success, 0 for failure.
const int kSuccessRatioHistogramMaxValue = 2;

// Gets the absolute signal name by concatenating the interface name and
// the signal name. Used for building keys for method_table_ in
// ObjectProxy.
std::string GetAbsoluteSignalName(
    const std::string& interface_name,
    const std::string& signal_name) {
  return interface_name + "." + signal_name;
}

}  // namespace

namespace dbus {

ObjectProxy::ObjectProxy(Bus* bus,
                         const std::string& service_name,
                         const std::string& object_path)
    : bus_(bus),
      service_name_(service_name),
      object_path_(object_path),
      filter_added_(false) {
}

ObjectProxy::~ObjectProxy() {
}

// Originally we tried to make |method_call| a const reference, but we
// gave up as dbus_connection_send_with_reply_and_block() takes a
// non-const pointer of DBusMessage as the second parameter.
Response* ObjectProxy::CallMethodAndBlock(MethodCall* method_call,
                                          int timeout_ms) {
  bus_->AssertOnDBusThread();

  if (!bus_->Connect())
    return NULL;

  method_call->SetDestination(service_name_);
  method_call->SetPath(object_path_);
  DBusMessage* request_message = method_call->raw_message();

  ScopedDBusError error;

  // Send the message synchronously.
  const base::TimeTicks start_time = base::TimeTicks::Now();
  DBusMessage* response_message =
      bus_->SendWithReplyAndBlock(request_message, timeout_ms, error.get());
  // Record if the method call is successful, or not. 1 if successful.
  UMA_HISTOGRAM_ENUMERATION("DBus.SyncMethodCallSuccess",
                            response_message ? 1 : 0,
                            kSuccessRatioHistogramMaxValue);

  if (!response_message) {
    LOG(ERROR) << "Failed to call method: "
               << (error.is_set() ? error.message() : "");
    return NULL;
  }
  // Record time spent for the method call. Don't include failures.
  UMA_HISTOGRAM_TIMES("DBus.SyncMethodCallTime",
                      base::TimeTicks::Now() - start_time);

  return Response::FromRawMessage(response_message);
}

void ObjectProxy::CallMethod(MethodCall* method_call,
                             int timeout_ms,
                             ResponseCallback callback) {
  bus_->AssertOnOriginThread();

  method_call->SetDestination(service_name_);
  method_call->SetPath(object_path_);
  // Increment the reference count so we can safely reference the
  // underlying request message until the method call is complete. This
  // will be unref'ed in StartAsyncMethodCall().
  DBusMessage* request_message = method_call->raw_message();
  dbus_message_ref(request_message);

  const base::TimeTicks start_time = base::TimeTicks::Now();
  base::Closure task = base::Bind(&ObjectProxy::StartAsyncMethodCall,
                                  this,
                                  timeout_ms,
                                  request_message,
                                  callback,
                                  start_time);
  // Wait for the response in the D-Bus thread.
  bus_->PostTaskToDBusThread(FROM_HERE, task);
}

void ObjectProxy::ConnectToSignal(const std::string& interface_name,
                                  const std::string& signal_name,
                                  SignalCallback signal_callback,
                                  OnConnectedCallback on_connected_callback) {
  bus_->AssertOnOriginThread();

  bus_->PostTaskToDBusThread(FROM_HERE,
                             base::Bind(&ObjectProxy::ConnectToSignalInternal,
                                        this,
                                        interface_name,
                                        signal_name,
                                        signal_callback,
                                        on_connected_callback));
}

void ObjectProxy::Detach() {
  bus_->AssertOnDBusThread();

  if (filter_added_) {
    if (!bus_->RemoveFilterFunction(&ObjectProxy::HandleMessageThunk, this)) {
      LOG(ERROR) << "Failed to remove filter function";
    }
  }

  for (size_t i = 0; i < match_rules_.size(); ++i) {
    ScopedDBusError error;
    bus_->RemoveMatch(match_rules_[i], error.get());
    if (error.is_set()) {
      // There is nothing we can do to recover, so just print the error.
      LOG(ERROR) << "Failed to remove match rule: " << match_rules_[i];
    }
  }
}

ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData(
    ObjectProxy* in_object_proxy,
    ResponseCallback in_response_callback,
    base::TimeTicks in_start_time)
    : object_proxy(in_object_proxy),
      response_callback(in_response_callback),
      start_time(in_start_time) {
}

ObjectProxy::OnPendingCallIsCompleteData::~OnPendingCallIsCompleteData() {
}

void ObjectProxy::StartAsyncMethodCall(int timeout_ms,
                                       DBusMessage* request_message,
                                       ResponseCallback response_callback,
                                       base::TimeTicks start_time) {
  bus_->AssertOnDBusThread();

  if (!bus_->Connect() || !bus_->SetUpAsyncOperations()) {
    // In case of a failure, run the callback with NULL response, that
    // indicates a failure.
    DBusMessage* response_message = NULL;
    base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
                                    this,
                                    response_callback,
                                    start_time,
                                    response_message);
    bus_->PostTaskToOriginThread(FROM_HERE, task);
    return;
  }

  DBusPendingCall* pending_call = NULL;

  bus_->SendWithReply(request_message, &pending_call, timeout_ms);

  // Prepare the data we'll be passing to OnPendingCallIsCompleteThunk().
  // The data will be deleted in OnPendingCallIsCompleteThunk().
  OnPendingCallIsCompleteData* data =
      new OnPendingCallIsCompleteData(this, response_callback, start_time);

  // This returns false only when unable to allocate memory.
  const bool success = dbus_pending_call_set_notify(
      pending_call,
      &ObjectProxy::OnPendingCallIsCompleteThunk,
      data,
      NULL);
  CHECK(success) << "Unable to allocate memory";
  dbus_pending_call_unref(pending_call);

  // It's now safe to unref the request message.
  dbus_message_unref(request_message);
}

void ObjectProxy::OnPendingCallIsComplete(DBusPendingCall* pending_call,
                                          ResponseCallback response_callback,
                                          base::TimeTicks start_time) {
  bus_->AssertOnDBusThread();

  DBusMessage* response_message = dbus_pending_call_steal_reply(pending_call);
  base::Closure task = base::Bind(&ObjectProxy::RunResponseCallback,
                                  this,
                                  response_callback,
                                  start_time,
                                  response_message);
  bus_->PostTaskToOriginThread(FROM_HERE, task);
}

void ObjectProxy::RunResponseCallback(ResponseCallback response_callback,
                                      base::TimeTicks start_time,
                                      DBusMessage* response_message) {
  bus_->AssertOnOriginThread();

  bool response_callback_called = false;
  if (!response_message) {
    // The response is not received.
    response_callback.Run(NULL);
  } else if (dbus_message_get_type(response_message) ==
             DBUS_MESSAGE_TYPE_ERROR) {
    // This will take |response_message| and release (unref) it.
    scoped_ptr<dbus::ErrorResponse> error_response(
        dbus::ErrorResponse::FromRawMessage(response_message));
    // Error message may contain the error message as string.
    dbus::MessageReader reader(error_response.get());
    std::string error_message;
    reader.PopString(&error_message);
    LOG(ERROR) << "Failed to call method: " << error_response->GetErrorName()
               << ": " << error_message;
    // We don't give the error message to the callback.
    response_callback.Run(NULL);
  } else {
    // This will take |response_message| and release (unref) it.
    scoped_ptr<dbus::Response> response(
        dbus::Response::FromRawMessage(response_message));
    // The response is successfully received.
    response_callback.Run(response.get());
    response_callback_called = true;
    // Record time spent for the method call. Don't include failures.
    UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime",
                        base::TimeTicks::Now() - start_time);
  }
  // Record if the method call is successful, or not. 1 if successful.
  UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess",
                            response_callback_called,
                            kSuccessRatioHistogramMaxValue);
}

void ObjectProxy::OnPendingCallIsCompleteThunk(DBusPendingCall* pending_call,
                                               void* user_data) {
  OnPendingCallIsCompleteData* data =
      reinterpret_cast<OnPendingCallIsCompleteData*>(user_data);
  ObjectProxy* self = data->object_proxy;
  self->OnPendingCallIsComplete(pending_call,
                                data->response_callback,
                                data->start_time);
  delete data;
}

void ObjectProxy::ConnectToSignalInternal(
    const std::string& interface_name,
    const std::string& signal_name,
    SignalCallback signal_callback,
    OnConnectedCallback on_connected_callback) {
  bus_->AssertOnDBusThread();

  // Check if the object is already connected to the signal.
  const std::string absolute_signal_name =
      GetAbsoluteSignalName(interface_name, signal_name);
  if (method_table_.find(absolute_signal_name) != method_table_.end()) {
    LOG(ERROR) << "The object proxy is already connected to "
               << absolute_signal_name;
    return;
  }

  // Will become true, if everything is successful.
  bool success = false;

  if (bus_->Connect() && bus_->SetUpAsyncOperations()) {
    // We should add the filter only once. Otherwise, HandleMessage() will
    // be called more than once.
    if (!filter_added_) {
      if (bus_->AddFilterFunction(&ObjectProxy::HandleMessageThunk, this)) {
        filter_added_ = true;
      } else {
        LOG(ERROR) << "Failed to add filter function";
      }
    }
    // Add a match rule so the signal goes through HandleMessage().
    //
    // We don't restrict the sender object path to be |object_path_| here,
    // to make it easy to test D-Bus signal handling with dbus-send, that
    // uses "/" as the sender object path. We can make the object path
    // restriction customizable when it becomes necessary.
    const std::string match_rule =
        base::StringPrintf("type='signal', interface='%s'",
                           interface_name.c_str());
    ScopedDBusError error;
    bus_->AddMatch(match_rule, error.get());;
    if (error.is_set()) {
      LOG(ERROR) << "Failed to add match rule: " << match_rule;
    } else {
      // Store the match rule, so that we can remove this in Detach().
      match_rules_.push_back(match_rule);
      // Add the signal callback to the method table.
      method_table_[absolute_signal_name] = signal_callback;
      success = true;
    }
  }

  // Run on_connected_callback in the origin thread.
  bus_->PostTaskToOriginThread(
      FROM_HERE,
      base::Bind(&ObjectProxy::OnConnected,
                 this,
                 on_connected_callback,
                 interface_name,
                 signal_name,
                 success));
}

void ObjectProxy::OnConnected(OnConnectedCallback on_connected_callback,
                              const std::string& interface_name,
                              const std::string& signal_name,
                              bool success) {
  bus_->AssertOnOriginThread();

  on_connected_callback.Run(interface_name, signal_name, success);
}

DBusHandlerResult ObjectProxy::HandleMessage(
    DBusConnection* connection,
    DBusMessage* raw_message) {
  bus_->AssertOnDBusThread();
  if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  // raw_message will be unrefed on exit of the function. Increment the
  // reference so we can use it in Signal.
  dbus_message_ref(raw_message);
  scoped_ptr<Signal> signal(
      Signal::FromRawMessage(raw_message));

  const std::string interface = signal->GetInterface();
  const std::string member = signal->GetMember();

  // Check if we know about the signal.
  const std::string absolute_signal_name = GetAbsoluteSignalName(
      interface, member);
  MethodTable::const_iterator iter = method_table_.find(absolute_signal_name);
  if (iter == method_table_.end()) {
    // Don't know about the signal.
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }
  VLOG(1) << "Signal received: " << signal->ToString();

  const base::TimeTicks start_time = base::TimeTicks::Now();
  if (bus_->HasDBusThread()) {
    // Post a task to run the method in the origin thread.
    // Transfer the ownership of |signal| to RunMethod().
    // |released_signal| will be deleted in RunMethod().
    Signal* released_signal = signal.release();
    bus_->PostTaskToOriginThread(FROM_HERE,
                                 base::Bind(&ObjectProxy::RunMethod,
                                            this,
                                            start_time,
                                            iter->second,
                                            released_signal));
  } else {
    const base::TimeTicks start_time = base::TimeTicks::Now();
    // If the D-Bus thread is not used, just call the callback on the
    // current thread. Transfer the ownership of |signal| to RunMethod().
    Signal* released_signal = signal.release();
    RunMethod(start_time, iter->second, released_signal);
  }

  return DBUS_HANDLER_RESULT_HANDLED;
}

void ObjectProxy::RunMethod(base::TimeTicks start_time,
                            SignalCallback signal_callback,
                            Signal* signal) {
  bus_->AssertOnOriginThread();

  signal_callback.Run(signal);
  delete signal;
  // Record time spent for handling the signal.
  UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime",
                      base::TimeTicks::Now() - start_time);
}

DBusHandlerResult ObjectProxy::HandleMessageThunk(
    DBusConnection* connection,
    DBusMessage* raw_message,
    void* user_data) {
  ObjectProxy* self = reinterpret_cast<ObjectProxy*>(user_data);
  return self->HandleMessage(connection, raw_message);
}

}  // namespace dbus
<|endoftext|>


<commit_before>#include "box.hpp"
#include <glm/vec3.hpp>
#include <iostream>
#include <glm/glm.hpp>
#include <algorithm>

Box::Box() :
	Shape{},
	min_{0,0,0},
	max_{1,1,1}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::Box(glm::vec3 const& min, glm::vec3 const& max) :
	Shape{},
	min_{
		min.x<max.x ? min.x : max.x,
		min.y<max.y ? min.y : max.y,
		min.z<max.z ? min.z : max.z
	},
	max_{
		max.x>min.x ? max.x : min.x,
		max.y>min.y ? max.y : min.y,
		max.z>min.z ? max.z : min.z
	}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::Box(glm::vec3 const& min, glm::vec3 const& max, Material const& material, std::string const& name) :
	Shape{material,name},
	min_{
		min.x<max.x ? min.x : max.x,
		min.y<max.y ? min.y : max.y,
		min.z<max.z ? min.z : max.z
	},
	max_{
		max.x>min.x ? max.x : min.x,
		max.y>min.y ? max.y : min.y,
		max.z>min.z ? max.z : min.z
	}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::~Box() {
	// std::cout << "Destruction of box" << std::endl;
}

glm::vec3 Box::min() const {
	return min_;
}

glm::vec3 Box::max() const {
	return max_;
}

double Box::area() const {
	double a = max_[0] - min_[0];
	double b = max_[1] - min_[1];
	double c = max_[2] - min_[2];
	return 2 * (a * b + b * c + a * c);
}

double Box::volume() const {
	double a = max_[0] - min_[0];
	double b = max_[1] - min_[1];
	double c = max_[2] - min_[2];
	return a * b * c;
}

std::ostream& Box::print(std::ostream& os) const {
	Shape::print(os) << "min: [" << min_.x << "," << min_.y
		<< "," << min_.z << "]\r\n" << "max: [" << max_.x
		<< "," << max_.y << "," << max_.z << "]" << "\r\n";
	return os;
}

std::ostream& operator<<(std::ostream& os, Box const& s) {
	return s.print(os);
}

Hit Box::intersect(Ray const& ray) const {
	Hit hit;
	glm::vec3 invDirection{ (1 / ray.direction.x), (1 / ray.direction.y), (1 / ray.direction.z) };
	double t1 = (min_[0] - ray.origin[0])*invDirection[0];
	double t2 = (max_[0] - ray.origin[0])*invDirection[0];

	double tmin = std::min(t1, t2);
	double tmax = std::max(t1, t2);

	for (int i = 1; i < 3; ++i) {
		t1 = (min_[i] - ray.origin[i])*invDirection[i];
		t2 = (max_[i] - ray.origin[i])*invDirection[i];

		tmin = std::max(tmin, std::min(std::min(t1, t2), tmax));
		tmax = std::min(tmax, std::max(std::max(t1, t2), tmin));
	}

	if(tmax > std::max(tmin, 0.0)) {
		hit.hit = true;
	}
	else {
		hit.hit = false;
	}

	return hit;

	/*for(int i=0; i<3; i++) {
		float dmin{0.0}, dmax{0.0}, dtmp{0.0};
		dmin = (min_[i] - ray.origin[i]) / ray.direction[i];
		dmax = (max_[i] - ray.origin[i]) / ray.direction[i];
		dtmp = dmin < dmax ? dmin : dmax;
		glm::vec3 tmp{0.0,0.0,0.0};
		if(!std::isnan(dtmp) && !std::isinf(dtmp)) {
			tmp = {
				ray.origin.x + dtmp * ray.direction.x,
				ray.origin.y + dtmp * ray.direction.y,
				ray.origin.z + dtmp * ray.direction.z
			};
		} else {
			continue;
		}
		if(tmp.x>=min_.x && tmp.x<=max_.x &&
			tmp.y>=min_.y && tmp.y<=max_.y &&
			tmp.z>=min_.z && tmp.z<=max_.z) {
			glm::vec3 mvec{dtmp * ray.direction};
			distance = sqrt(pow(mvec.x,2) + pow(mvec.y,2) +pow(mvec.z,2));
			return true;
		}
	}
	return false;*/
}
<commit_msg>improved box intersect (maybe)<commit_after>#include "box.hpp"
#include <glm/vec3.hpp>
#include <iostream>
#include <glm/glm.hpp>
#include <algorithm>

Box::Box() :
	Shape{},
	min_{0,0,0},
	max_{1,1,1}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::Box(glm::vec3 const& min, glm::vec3 const& max) :
	Shape{},
	min_{
		min.x<max.x ? min.x : max.x,
		min.y<max.y ? min.y : max.y,
		min.z<max.z ? min.z : max.z
	},
	max_{
		max.x>min.x ? max.x : min.x,
		max.y>min.y ? max.y : min.y,
		max.z>min.z ? max.z : min.z
	}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::Box(glm::vec3 const& min, glm::vec3 const& max, Material const& material, std::string const& name) :
	Shape{material,name},
	min_{
		min.x<max.x ? min.x : max.x,
		min.y<max.y ? min.y : max.y,
		min.z<max.z ? min.z : max.z
	},
	max_{
		max.x>min.x ? max.x : min.x,
		max.y>min.y ? max.y : min.y,
		max.z>min.z ? max.z : min.z
	}
{
	// std::cout << "Construction of box" << std::endl;
}

Box::~Box() {
	// std::cout << "Destruction of box" << std::endl;
}

glm::vec3 Box::min() const {
	return min_;
}

glm::vec3 Box::max() const {
	return max_;
}

double Box::area() const {
	double a = max_[0] - min_[0];
	double b = max_[1] - min_[1];
	double c = max_[2] - min_[2];
	return 2 * (a * b + b * c + a * c);
}

double Box::volume() const {
	double a = max_[0] - min_[0];
	double b = max_[1] - min_[1];
	double c = max_[2] - min_[2];
	return a * b * c;
}

std::ostream& Box::print(std::ostream& os) const {
	Shape::print(os) << "min: [" << min_.x << "," << min_.y
		<< "," << min_.z << "]\r\n" << "max: [" << max_.x
		<< "," << max_.y << "," << max_.z << "]" << "\r\n";
	return os;
}

std::ostream& operator<<(std::ostream& os, Box const& s) {
	return s.print(os);
}

Hit Box::intersect(Ray const& ray) const {
	Hit min, max;
	glm::vec3 invDirection{ (1 / ray.direction.x), (1 / ray.direction.y), (1 / ray.direction.z) };
	double t1 = (min_[0] - ray.origin[0])*invDirection[0];
	double t2 = (max_[0] - ray.origin[0])*invDirection[0];

	double tmin = std::min(t1, t2);
	double tmax = std::max(t1, t2);

	min.intersection.x = tmin;
	max.intersection.x = tmax;
	for (int i = 1; i < 3; ++i) {
		t1 = (min_[i] - ray.origin[i])*invDirection[i];
		t2 = (max_[i] - ray.origin[i])*invDirection[i];

		tmin = std::max(tmin, std::min(std::min(t1, t2), tmax));
		tmax = std::min(tmax, std::max(std::max(t1, t2), tmin));

		min.intersection[i] = tmin;
		max.intersection[i] = tmax;
	}

	if(tmax > std::max(tmin, 0.0)) {
		max.distance = glm::distance(max.intersection, ray.origin);
		min.distance = glm::distance(min.intersection, ray.origin);

		if(max.distance > min.distance) {
			min.hit = true;
			return min;
		}

		max.hit = true;
		return max;
	}

	return Hit{};

	/*for(int i=0; i<3; i++) {
		float dmin{0.0}, dmax{0.0}, dtmp{0.0};
		dmin = (min_[i] - ray.origin[i]) / ray.direction[i];
		dmax = (max_[i] - ray.origin[i]) / ray.direction[i];
		dtmp = dmin < dmax ? dmin : dmax;
		glm::vec3 tmp{0.0,0.0,0.0};
		if(!std::isnan(dtmp) && !std::isinf(dtmp)) {
			tmp = {
				ray.origin.x + dtmp * ray.direction.x,
				ray.origin.y + dtmp * ray.direction.y,
				ray.origin.z + dtmp * ray.direction.z
			};
		} else {
			continue;
		}
		if(tmp.x>=min_.x && tmp.x<=max_.x &&
			tmp.y>=min_.y && tmp.y<=max_.y &&
			tmp.z>=min_.z && tmp.z<=max_.z) {
			glm::vec3 mvec{dtmp * ray.direction};
			distance = sqrt(pow(mvec.x,2) + pow(mvec.y,2) +pow(mvec.z,2));
			return true;
		}
	}
	return false;*/
}
<|endoftext|>


<commit_before>#include "box.hpp"

Box::Box(): // default constructor
        min_{0.0, 0.0, 0.0},
        max_{0.0, 0.0, 0.0}
        {}
Box::Box(Box const& b): // copy constructor
        min_{b.min_},
        max_{b.max_}
        {}
Box::Box(Box&& b): // move constructor
        Box()
        {
                swap(*this, b);
        }
Box::Box(glm::vec3 const& min, glm::vec3 const& max):
        min_{min},
        max_{max}
        {}

friend void Box::swap(Box & b1, Box & b2) {
        std::swap(b1.min_, b2.min_);
        std::swap(b1.max_, b2.max_);
}

glm::vec3 Box::getMin() const {
        return min_;
}

glm::vec3 Box::getMax() const {
        return max_;
}<commit_msg>Add whitespace.<commit_after>#include "box.hpp"

Box::Box(): // default constructor
        min_{0.0, 0.0, 0.0},
        max_{0.0, 0.0, 0.0}
        {}

Box::Box(Box const& b): // copy constructor
        min_{b.min_},
        max_{b.max_}
        {}

Box::Box(Box&& b): // move constructor
        Box()
        {
                swap(*this, b);
        }

Box::Box(glm::vec3 const& min, glm::vec3 const& max):
        min_{min},
        max_{max}
        {}

friend void Box::swap(Box & b1, Box & b2) {
        std::swap(b1.min_, b2.min_);
        std::swap(b1.max_, b2.max_);
}

glm::vec3 Box::getMin() const {
        return min_;
}

glm::vec3 Box::getMax() const {
        return max_;
}<|endoftext|>


<commit_before>#include "material/lambert.h"

namespace AT_NAME {
	AT_DEVICE_API real lambert::pdf(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v)
	{
		return pdf(normal, wo);
	}

	AT_DEVICE_API real lambert::pdf(
		const aten::vec3& normal,
		const aten::vec3& wo)
	{
		auto c = dot(normal, wo);
		//AT_ASSERT(c >= 0);
		//c = aten::abs(c);

		auto ret = c / AT_MATH_PI;

		return ret;
	}

	real lambert::pdf(
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v) const
	{
		auto ret = pdf(&m_param, normal, wi, wo, u, v);
		return ret;
	}

	AT_DEVICE_API aten::vec3 lambert::sampleDirection(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		real u, real v,
		aten::sampler* sampler)
	{
		return std::move(sampleDirection(normal, sampler));
	}

	AT_DEVICE_API aten::vec3 lambert::sampleDirection(
		const aten::vec3& normal,
		aten::sampler* sampler)
	{
		// normal̕ƂK(w, u, v).
		// ̊ɑ΂锼Ŏ̃C΂.
		aten::vec3 n, t, b;

		n = normal;

		// nƕsɂȂȂ悤ɂ.
		if (fabs(n.x) > AT_MATH_EPSILON) {
			t = normalize(cross(aten::make_float3(0.0, 1.0, 0.0), n));
		}
		else {
			t = normalize(cross(aten::make_float3(1.0, 0.0, 0.0), n));
		}
		b = cross(n, t);

		// RTCgd_ITvO.
		const real r1 = 2 * AT_MATH_PI * sampler->nextSample();
		const real r2 = sampler->nextSample();
		const real r2s = sqrt(r2);

		const real x = aten::cos(r1) * r2s;
		const real y = aten::sin(r1) * r2s;
		const real z = aten::sqrt(real(1) - r2);

		aten::vec3 dir = normalize((t * x + b * y + n * z));
		AT_ASSERT(dot(normal, dir) >= 0);

		return std::move(dir);
	}

	aten::vec3 lambert::sampleDirection(
		const aten::ray& ray,
		const aten::vec3& normal,
		real u, real v,
		aten::sampler* sampler) const
	{
		return std::move(sampleDirection(&m_param, normal, ray.dir, u, v, sampler));
	}

	AT_DEVICE_API aten::vec3 lambert::bsdf(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v)
	{
		return std::move(bsdf(param, u, v));
	}

	AT_DEVICE_API aten::vec3 lambert::bsdf(
		const aten::MaterialParameter* param,
		real u, real v)
	{
		aten::vec3 albedo = param->baseColor;
		albedo *= sampleTexture(
			(aten::texture*)param->albedoMap.ptr,
			u, v,
			real(1));

		aten::vec3 ret = albedo / AT_MATH_PI;
		return ret;
	}

	aten::vec3 lambert::bsdf(
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v) const
	{
		auto ret = bsdf(&m_param, normal, wi, wo, u, v);
		return std::move(ret);
	}

	AT_DEVICE_API void lambert::sample(
		MaterialSampling* result,
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& orgnormal,
		aten::sampler* sampler,
		real u, real v,
		bool isLightPath/*= false*/)
	{
		MaterialSampling ret;

		result->dir = sampleDirection(param, normal, wi, u, v, sampler);
		result->pdf = pdf(param, normal, wi, result->dir, u, v);
		result->bsdf = bsdf(param, normal, wi, result->dir, u, v);
	}

	MaterialSampling lambert::sample(
		const aten::ray& ray,
		const aten::vec3& normal,
		const aten::vec3& orgnormal,
		aten::sampler* sampler,
		real u, real v,
		bool isLightPath/*= false*/) const
	{
		MaterialSampling ret;

		sample(
			&ret,
			&m_param,
			normal,
			ray.dir,
			orgnormal,
			sampler,
			u, v,
			isLightPath);

		return std::move(ret);
	}
}<commit_msg>Simplify sampling direction.<commit_after>#include "material/lambert.h"

namespace AT_NAME {
	AT_DEVICE_API real lambert::pdf(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v)
	{
		return pdf(normal, wo);
	}

	AT_DEVICE_API real lambert::pdf(
		const aten::vec3& normal,
		const aten::vec3& wo)
	{
		auto c = dot(normal, wo);
		//AT_ASSERT(c >= 0);
		//c = aten::abs(c);

		auto ret = c / AT_MATH_PI;

		return ret;
	}

	real lambert::pdf(
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v) const
	{
		auto ret = pdf(&m_param, normal, wi, wo, u, v);
		return ret;
	}

	AT_DEVICE_API aten::vec3 lambert::sampleDirection(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		real u, real v,
		aten::sampler* sampler)
	{
		return std::move(sampleDirection(normal, sampler));
	}

	AT_DEVICE_API aten::vec3 lambert::sampleDirection(
		const aten::vec3& normal,
		aten::sampler* sampler)
	{
		// normal̕ƂK(w, u, v).
		// ̊ɑ΂锼Ŏ̃C΂.
#if 1
		auto n = normal;
		auto t = getOrthoVector(n);
		auto b = cross(n, t);
#else
		aten::vec3 n, t, b;

		n = normal;

		// nƕsɂȂȂ悤ɂ.
		if (fabs(n.x) > AT_MATH_EPSILON) {
			t = normalize(cross(aten::make_float3(0.0, 1.0, 0.0), n));
		}
		else {
			t = normalize(cross(aten::make_float3(1.0, 0.0, 0.0), n));
		}
		b = cross(n, t);
#endif

		// RTCgd_ITvO.
		const real r1 = 2 * AT_MATH_PI * sampler->nextSample();
		const real r2 = sampler->nextSample();
		const real r2s = sqrt(r2);

		const real x = aten::cos(r1) * r2s;
		const real y = aten::sin(r1) * r2s;
		const real z = aten::sqrt(real(1) - r2);

		aten::vec3 dir = normalize((t * x + b * y + n * z));
		AT_ASSERT(dot(normal, dir) >= 0);

		return std::move(dir);
	}

	aten::vec3 lambert::sampleDirection(
		const aten::ray& ray,
		const aten::vec3& normal,
		real u, real v,
		aten::sampler* sampler) const
	{
		return std::move(sampleDirection(&m_param, normal, ray.dir, u, v, sampler));
	}

	AT_DEVICE_API aten::vec3 lambert::bsdf(
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v)
	{
		return std::move(bsdf(param, u, v));
	}

	AT_DEVICE_API aten::vec3 lambert::bsdf(
		const aten::MaterialParameter* param,
		real u, real v)
	{
		aten::vec3 albedo = param->baseColor;
		albedo *= sampleTexture(
			(aten::texture*)param->albedoMap.ptr,
			u, v,
			real(1));

		aten::vec3 ret = albedo / AT_MATH_PI;
		return ret;
	}

	aten::vec3 lambert::bsdf(
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& wo,
		real u, real v) const
	{
		auto ret = bsdf(&m_param, normal, wi, wo, u, v);
		return std::move(ret);
	}

	AT_DEVICE_API void lambert::sample(
		MaterialSampling* result,
		const aten::MaterialParameter* param,
		const aten::vec3& normal,
		const aten::vec3& wi,
		const aten::vec3& orgnormal,
		aten::sampler* sampler,
		real u, real v,
		bool isLightPath/*= false*/)
	{
		MaterialSampling ret;

		result->dir = sampleDirection(param, normal, wi, u, v, sampler);
		result->pdf = pdf(param, normal, wi, result->dir, u, v);
		result->bsdf = bsdf(param, normal, wi, result->dir, u, v);
	}

	MaterialSampling lambert::sample(
		const aten::ray& ray,
		const aten::vec3& normal,
		const aten::vec3& orgnormal,
		aten::sampler* sampler,
		real u, real v,
		bool isLightPath/*= false*/) const
	{
		MaterialSampling ret;

		sample(
			&ret,
			&m_param,
			normal,
			ray.dir,
			orgnormal,
			sampler,
			u, v,
			isLightPath);

		return std::move(ret);
	}
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cf_service.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-02-28 10:40:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include "osl/mutex.hxx"
#include "osl/process.h"
#include "cppuhelper/implementationentry.hxx"
#include "cppuhelper/factory.hxx"
#include "cppuhelper/implbase3.hxx"
#include "vcl/configsettings.hxx"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"
#include "com/sun/star/container/XContentEnumerationAccess.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/beans/PropertyValue.hpp"

#include <vector>
#include <algorithm>

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
#define ARLEN(x) (sizeof (x) / sizeof *(x))

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using ::rtl::OUString;

namespace {

OUString SAL_CALL getImplName()
{
    return OUSTR("com.sun.star.comp.rendering.CanvasFactory");
}

Sequence<OUString> SAL_CALL getSuppServices()
{
    OUString name = OUSTR("com.sun.star.rendering.CanvasFactory");
    return Sequence<OUString>(&name, 1);
}

//==============================================================================
class CanvasFactory
    : public ::cppu::WeakImplHelper3< lang::XServiceInfo,
                                      lang::XMultiComponentFactory,
                                      lang::XMultiServiceFactory >
{
    ::osl::Mutex m_mutex;
    Reference<XComponentContext> m_xContext;
    Sequence<OUString> m_services;
    OUString m_serviceName;
    Reference<lang::XSingleComponentFactory> m_xFactory;

    Reference<XInterface> use(
        Reference<lang::XSingleComponentFactory> const & xFactory,
        Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext );
    Reference<XInterface> lookupAndUse(
        OUString const & serviceName, Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext );

public:
    virtual ~CanvasFactory();
    CanvasFactory( Reference<XComponentContext> const & xContext );

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
        throw (RuntimeException);
    virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
        throw (RuntimeException);

    // XMultiComponentFactory
    virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
        throw (RuntimeException);
    virtual Reference<XInterface> SAL_CALL createInstanceWithContext(
        OUString const & name,
        Reference<XComponentContext> const & xContext ) throw (Exception);
    virtual Reference<XInterface> SAL_CALL
    createInstanceWithArgumentsAndContext(
        OUString const & name,
        Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext ) throw (Exception);

    // XMultiServiceFactory
    virtual Reference<XInterface> SAL_CALL createInstance(
        OUString const & name )
        throw (Exception);
    virtual Reference<XInterface> SAL_CALL createInstanceWithArguments(
        OUString const & name, Sequence<Any> const & args )
        throw (Exception);
//     virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
//         throw (RuntimeException);
};

CanvasFactory::CanvasFactory(
    Reference<XComponentContext> const & xContext )
    : m_xContext(xContext)
{
    ::rtl::OUString preferredServices;

    try
    {
        // read out configuration for preferred services:
        Reference<lang::XMultiServiceFactory> xConfigProvider(
            m_xContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.configuration.ConfigurationProvider"),
                m_xContext ), UNO_QUERY_THROW );

        Any propValue(
            makeAny( beans::PropertyValue(
                         OUSTR("nodepath"), -1,
                         makeAny( OUSTR("/org.openoffice.VCL/Settings/Canvas") ),
                         beans::PropertyState_DIRECT_VALUE ) ) );

        Reference<container::XNameAccess> xNameAccess(
            xConfigProvider->createInstanceWithArguments(
                OUSTR("com.sun.star.configuration.ConfigurationAccess"),
                Sequence<Any>( &propValue, 1 ) ), UNO_QUERY );

        if (xNameAccess.is())
            xNameAccess->getByName( OUSTR("PreferredServices") ) >>= preferredServices;
    }
    catch (RuntimeException &) {
        throw;
    }
    catch (Exception & exc) {
        (void) exc;
    }

    ::std::vector< ::rtl::OUString > services;
    sal_Int32 tokenPos = 0;
    do
    {
        ::rtl::OUString oneService = preferredServices.getToken( 0, ';', tokenPos );
        if ( oneService.getLength() )
            services.push_back( oneService );
    }
    while ( tokenPos > 0 );
    m_services.realloc( services.size() );
    ::std::copy( services.begin(), services.end(), m_services.getArray() );

    // append the usual preferred ones:
    sal_Int32 pos = m_services.getLength();
#if defined WNT
    m_services.realloc( pos + 5 );
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.DXCanvas");
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.GLCanvas");
#else
    m_services.realloc( pos + 4 );
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.GLCanvas");
#endif
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.CairoCanvas");
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.JavaCanvas");
    m_services[ pos   ] = OUSTR("com.sun.star.rendering.VCLCanvas");
}

CanvasFactory::~CanvasFactory()
{
}

//------------------------------------------------------------------------------
Reference<XInterface> create( Reference<XComponentContext> const & xContext )
{
    return static_cast< ::cppu::OWeakObject * >(
        new CanvasFactory( xContext ) );
}

// XServiceInfo
//______________________________________________________________________________
OUString CanvasFactory::getImplementationName() throw (RuntimeException)
{
    return getImplName();
}

//______________________________________________________________________________
sal_Bool CanvasFactory::supportsService( OUString const & serviceName )
    throw (RuntimeException)
{
    return serviceName.equals(getSuppServices()[0]);
}

//______________________________________________________________________________
Sequence<OUString> CanvasFactory::getSupportedServiceNames()
    throw (RuntimeException)
{
    return getSuppServices();
}

// XMultiComponentFactory
//______________________________________________________________________________
Sequence<OUString> CanvasFactory::getAvailableServiceNames()
    throw (RuntimeException)
{
    return m_services;
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithContext(
    OUString const & name, Reference<XComponentContext> const & xContext )
    throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, Sequence<Any>(), xContext );
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::use(
    Reference<lang::XSingleComponentFactory> const & xFactory,
    Sequence<Any> const & args, Reference<XComponentContext> const & xContext )
{
    try {
        return xFactory->createInstanceWithArgumentsAndContext(args, xContext);
    }
    catch (RuntimeException &) {
        throw;
    }
    catch (Exception &) {
        return Reference<XInterface>();
    }
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::lookupAndUse(
    OUString const & serviceName, Sequence<Any> const & args,
    Reference<XComponentContext> const & xContext )
{
    {
        // try to reuse:
        ::osl::ClearableMutexGuard guard(m_mutex);
        if (m_serviceName.equals(serviceName)) {
            Reference<lang::XSingleComponentFactory> xFac(m_xFactory);
            guard.clear();
            Reference<XInterface> xCanvas( use( xFac, args, xContext ) );
            if (xCanvas.is())
                return xCanvas;
        }
    }

    Reference<container::XContentEnumerationAccess> xEnumAccess(
        // use service manager of factory:
        m_xContext->getServiceManager(), UNO_QUERY_THROW );
    Reference<container::XEnumeration> xEnum(
        xEnumAccess->createContentEnumeration( serviceName ) );
    if (xEnum.is()) {
        while (xEnum->hasMoreElements()) {
            Reference<lang::XSingleComponentFactory> xFactory(
                xEnum->nextElement(), UNO_QUERY );
            OSL_ASSERT( xFactory.is() );
            if (xFactory.is()) {
                Reference<XInterface> xCanvas(
                    use( xFactory, args, xContext ) );
                if (xCanvas.is()) {
                    ::osl::MutexGuard guard(m_mutex);
                    // init for reuse:
                    m_xFactory.set(xFactory);
                    m_serviceName = serviceName;
                    return xCanvas;
                }
            }
        }
    }

    return Reference<XInterface>();
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithArgumentsAndContext(
    OUString const & preferredOne, Sequence<Any> const & args,
    Reference<XComponentContext> const & xContext ) throw (Exception)
{
    // preferred one overrides previously used one:
    if (preferredOne.getLength() > 0) {
        Reference<XInterface> xCanvas(
            lookupAndUse( preferredOne, args, xContext ) );
        if (xCanvas.is())
            return xCanvas;
    }

    {
        // try to reuse previously installed factory:
        ::osl::ClearableMutexGuard guard(m_mutex);
        if (m_xFactory.is()) {
            Reference<lang::XSingleComponentFactory> xFac(m_xFactory);
            guard.clear();
            Reference<XInterface> xCanvas( use( xFac, args, xContext ) );
            if (xCanvas.is())
                return xCanvas;
        }
    }

    // try configured ones:
    OUString const * pservices = m_services.getConstArray();
    sal_Int32 pos = 0, len = m_services.getLength();
    for ( ; pos < len; ++pos ) {
        Reference<XInterface> xCanvas(
            lookupAndUse( pservices[pos], args, xContext ) );
        if (xCanvas.is())
            return xCanvas;
    }

    OSL_ENSURE( 0, "### no canvas available!?" );
    return Reference<XInterface>();
}

// XMultiServiceFactory
//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstance( OUString const & name )
    throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, Sequence<Any>(), m_xContext );
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithArguments(
    OUString const & name, Sequence<Any> const & args ) throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, args, m_xContext );
}

const ::cppu::ImplementationEntry s_entries [] = {
    {
        create,
        getImplName,
        getSuppServices,
        ::cppu::createSingleComponentFactory,
        0, 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

} // anon namespace

extern "C" {

void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo(
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return ::cppu::component_writeInfoHelper(
        pServiceManager, pRegistryKey, s_entries );
}

void * SAL_CALL component_getFactory(
    sal_Char const * pImplName,
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return ::cppu::component_getFactoryHelper(
        pImplName, pServiceManager, pRegistryKey, s_entries );
}

}

<commit_msg>INTEGRATION: CWS warnings01 (1.7.4); FILE MERGED 2006/04/07 20:34:53 sb 1.7.4.2: RESYNC: (1.7-1.8); FILE MERGED 2005/11/15 16:51:39 thb 1.7.4.1: #i55991# made code compile without warnings for gcc<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cf_service.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:14:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include "osl/mutex.hxx"
#include "osl/process.h"
#include "cppuhelper/implementationentry.hxx"
#include "cppuhelper/factory.hxx"
#include "cppuhelper/implbase3.hxx"
#include "vcl/configsettings.hxx"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"
#include "com/sun/star/container/XContentEnumerationAccess.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/beans/PropertyValue.hpp"

#include <vector>
#include <algorithm>

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
#define ARLEN(x) (sizeof (x) / sizeof *(x))

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using ::rtl::OUString;

namespace {

OUString SAL_CALL getImplName()
{
    return OUSTR("com.sun.star.comp.rendering.CanvasFactory");
}

Sequence<OUString> SAL_CALL getSuppServices()
{
    OUString name = OUSTR("com.sun.star.rendering.CanvasFactory");
    return Sequence<OUString>(&name, 1);
}

//==============================================================================
class CanvasFactory
    : public ::cppu::WeakImplHelper3< lang::XServiceInfo,
                                      lang::XMultiComponentFactory,
                                      lang::XMultiServiceFactory >
{
    ::osl::Mutex m_mutex;
    Reference<XComponentContext> m_xContext;
    Sequence<OUString> m_services;
    OUString m_serviceName;
    Reference<lang::XSingleComponentFactory> m_xFactory;

    Reference<XInterface> use(
        Reference<lang::XSingleComponentFactory> const & xFactory,
        Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext );
    Reference<XInterface> lookupAndUse(
        OUString const & serviceName, Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext );

public:
    virtual ~CanvasFactory();
    CanvasFactory( Reference<XComponentContext> const & xContext );

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
        throw (RuntimeException);
    virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
        throw (RuntimeException);

    // XMultiComponentFactory
    virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
        throw (RuntimeException);
    virtual Reference<XInterface> SAL_CALL createInstanceWithContext(
        OUString const & name,
        Reference<XComponentContext> const & xContext ) throw (Exception);
    virtual Reference<XInterface> SAL_CALL
    createInstanceWithArgumentsAndContext(
        OUString const & name,
        Sequence<Any> const & args,
        Reference<XComponentContext> const & xContext ) throw (Exception);

    // XMultiServiceFactory
    virtual Reference<XInterface> SAL_CALL createInstance(
        OUString const & name )
        throw (Exception);
    virtual Reference<XInterface> SAL_CALL createInstanceWithArguments(
        OUString const & name, Sequence<Any> const & args )
        throw (Exception);
//     virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
//         throw (RuntimeException);
};

CanvasFactory::CanvasFactory(
    Reference<XComponentContext> const & xContext )
    : m_xContext(xContext)
{
    ::rtl::OUString preferredServices;

    try
    {
        // read out configuration for preferred services:
        Reference<lang::XMultiServiceFactory> xConfigProvider(
            m_xContext->getServiceManager()->createInstanceWithContext(
                OUSTR("com.sun.star.configuration.ConfigurationProvider"),
                m_xContext ), UNO_QUERY_THROW );

        Any propValue(
            makeAny( beans::PropertyValue(
                         OUSTR("nodepath"), -1,
                         makeAny( OUSTR("/org.openoffice.VCL/Settings/Canvas") ),
                         beans::PropertyState_DIRECT_VALUE ) ) );

        Reference<container::XNameAccess> xNameAccess(
            xConfigProvider->createInstanceWithArguments(
                OUSTR("com.sun.star.configuration.ConfigurationAccess"),
                Sequence<Any>( &propValue, 1 ) ), UNO_QUERY );

        if (xNameAccess.is())
            xNameAccess->getByName( OUSTR("PreferredServices") ) >>= preferredServices;
    }
    catch (RuntimeException &) {
        throw;
    }
    catch (Exception & exc) {
        (void) exc;
    }

    ::std::vector< ::rtl::OUString > services;
    sal_Int32 tokenPos = 0;
    do
    {
        ::rtl::OUString oneService = preferredServices.getToken( 0, ';', tokenPos );
        if ( oneService.getLength() )
            services.push_back( oneService );
    }
    while ( tokenPos > 0 );
    m_services.realloc( services.size() );
    ::std::copy( services.begin(), services.end(), m_services.getArray() );

    // append the usual preferred ones:
    sal_Int32 pos = m_services.getLength();
#if defined WNT
    m_services.realloc( pos + 5 );
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.DXCanvas");
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.GLCanvas");
#else
    m_services.realloc( pos + 4 );
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.GLCanvas");
#endif
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.CairoCanvas");
    m_services[ pos++ ] = OUSTR("com.sun.star.rendering.JavaCanvas");
    m_services[ pos   ] = OUSTR("com.sun.star.rendering.VCLCanvas");
}

CanvasFactory::~CanvasFactory()
{
}

//------------------------------------------------------------------------------
Reference<XInterface> create( Reference<XComponentContext> const & xContext )
{
    return static_cast< ::cppu::OWeakObject * >(
        new CanvasFactory( xContext ) );
}

// XServiceInfo
//______________________________________________________________________________
OUString CanvasFactory::getImplementationName() throw (RuntimeException)
{
    return getImplName();
}

//______________________________________________________________________________
sal_Bool CanvasFactory::supportsService( OUString const & serviceName )
    throw (RuntimeException)
{
    return serviceName.equals(getSuppServices()[0]);
}

//______________________________________________________________________________
Sequence<OUString> CanvasFactory::getSupportedServiceNames()
    throw (RuntimeException)
{
    return getSuppServices();
}

// XMultiComponentFactory
//______________________________________________________________________________
Sequence<OUString> CanvasFactory::getAvailableServiceNames()
    throw (RuntimeException)
{
    return m_services;
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithContext(
    OUString const & name, Reference<XComponentContext> const & xContext )
    throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, Sequence<Any>(), xContext );
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::use(
    Reference<lang::XSingleComponentFactory> const & xFactory,
    Sequence<Any> const & args, Reference<XComponentContext> const & xContext )
{
    try {
        return xFactory->createInstanceWithArgumentsAndContext(args, xContext);
    }
    catch (RuntimeException &) {
        throw;
    }
    catch (Exception &) {
        return Reference<XInterface>();
    }
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::lookupAndUse(
    OUString const & serviceName, Sequence<Any> const & args,
    Reference<XComponentContext> const & xContext )
{
    {
        // try to reuse:
        ::osl::ClearableMutexGuard guard(m_mutex);
        if (m_serviceName.equals(serviceName)) {
            Reference<lang::XSingleComponentFactory> xFac(m_xFactory);
            guard.clear();
            Reference<XInterface> xCanvas( use( xFac, args, xContext ) );
            if (xCanvas.is())
                return xCanvas;
        }
    }

    Reference<container::XContentEnumerationAccess> xEnumAccess(
        // use service manager of factory:
        m_xContext->getServiceManager(), UNO_QUERY_THROW );
    Reference<container::XEnumeration> xEnum(
        xEnumAccess->createContentEnumeration( serviceName ) );
    if (xEnum.is()) {
        while (xEnum->hasMoreElements()) {
            Reference<lang::XSingleComponentFactory> xFactory(
                xEnum->nextElement(), UNO_QUERY );
            OSL_ASSERT( xFactory.is() );
            if (xFactory.is()) {
                Reference<XInterface> xCanvas(
                    use( xFactory, args, xContext ) );
                if (xCanvas.is()) {
                    ::osl::MutexGuard guard(m_mutex);
                    // init for reuse:
                    m_xFactory.set(xFactory);
                    m_serviceName = serviceName;
                    return xCanvas;
                }
            }
        }
    }

    return Reference<XInterface>();
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithArgumentsAndContext(
    OUString const & preferredOne, Sequence<Any> const & args,
    Reference<XComponentContext> const & xContext ) throw (Exception)
{
    // preferred one overrides previously used one:
    if (preferredOne.getLength() > 0) {
        Reference<XInterface> xCanvas(
            lookupAndUse( preferredOne, args, xContext ) );
        if (xCanvas.is())
            return xCanvas;
    }

    {
        // try to reuse previously installed factory:
        ::osl::ClearableMutexGuard guard(m_mutex);
        if (m_xFactory.is()) {
            Reference<lang::XSingleComponentFactory> xFac(m_xFactory);
            guard.clear();
            Reference<XInterface> xCanvas( use( xFac, args, xContext ) );
            if (xCanvas.is())
                return xCanvas;
        }
    }

    // try configured ones:
    OUString const * pservices = m_services.getConstArray();
    sal_Int32 pos = 0, len = m_services.getLength();
    for ( ; pos < len; ++pos ) {
        Reference<XInterface> xCanvas(
            lookupAndUse( pservices[pos], args, xContext ) );
        if (xCanvas.is())
            return xCanvas;
    }

    OSL_ENSURE( 0, "### no canvas available!?" );
    return Reference<XInterface>();
}

// XMultiServiceFactory
//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstance( OUString const & name )
    throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, Sequence<Any>(), m_xContext );
}

//______________________________________________________________________________
Reference<XInterface> CanvasFactory::createInstanceWithArguments(
    OUString const & name, Sequence<Any> const & args ) throw (Exception)
{
    return createInstanceWithArgumentsAndContext(
        name, args, m_xContext );
}

const ::cppu::ImplementationEntry s_entries [] = {
    {
        create,
        getImplName,
        getSuppServices,
        ::cppu::createSingleComponentFactory,
        0, 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

} // anon namespace

extern "C" {

void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo(
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return ::cppu::component_writeInfoHelper(
        pServiceManager, pRegistryKey, s_entries );
}

void * SAL_CALL component_getFactory(
    sal_Char const * pImplName,
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return ::cppu::component_getFactoryHelper(
        pImplName, pServiceManager, pRegistryKey, s_entries );
}

}

<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "argumentsCount.hpp"

using But::Format::Invalid;
using But::Format::detail::argumentsCount;

namespace
{

struct ButFormatDetailArgumentsCount: public testing::Test
{ };

TEST_F(ButFormatDetailArgumentsCount, SimpleStrings)
{
  {
    constexpr auto cnt = argumentsCount("");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("teST STRIng");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("!@#%^%^*(()");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $$ data");
    EXPECT_EQ( 0u, cnt );
  }
}

TEST_F(ButFormatDetailArgumentsCount, OneArgument)
{
  {
    constexpr auto cnt = argumentsCount("$1");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1 data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test${1}data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${V1} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${V1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${T1} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${T1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\ndata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\rdata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\tdata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1 data");
    EXPECT_EQ( 1u, cnt );
  }
}

TEST_F(ButFormatDetailArgumentsCount, ExceptionIsThrownOnInvalidFormat)
{
  EXPECT_THROW( argumentsCount("$1oops"), Invalid ) << "invalid number";
  EXPECT_THROW( argumentsCount("${1"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("${1 x"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("${1# x"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("test$"), Invalid ) << "variable declaration too short";
  EXPECT_THROW( argumentsCount("test $1}"), Invalid ) << "invalid number";
}

TEST_F(ButFormatDetailArgumentsCount, MultipleArguments)
{
  {
    constexpr auto cnt = argumentsCount("test $1 data $3\t$4\n");
    EXPECT_EQ( 3u, cnt );
  }
}

TEST_F(ButFormatDetailArgumentsCount, MultipleArgumentsMultipleStyles)
{
  constexpr auto cnt = argumentsCount("test $1 data ${3} ${V4#xx} ${T8}");
  EXPECT_EQ( 4u, cnt );
}

}
<commit_msg>added some tests for non-consecutive arguments<commit_after>#include "gtest/gtest.h"
#include "argumentsCount.hpp"

using But::Format::Invalid;
using But::Format::detail::argumentsCount;

namespace
{

struct ButFormatDetailArgumentsCount: public testing::Test
{ };

TEST_F(ButFormatDetailArgumentsCount, SimpleStrings)
{
  {
    constexpr auto cnt = argumentsCount("");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("teST STRIng");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("!@#%^%^*(()");
    EXPECT_EQ( 0u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $$ data");
    EXPECT_EQ( 0u, cnt );
  }
}

TEST_F(ButFormatDetailArgumentsCount, OneArgument)
{
  {
    constexpr auto cnt = argumentsCount("$1");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1 data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test${1}data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${V1} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${V1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${T1} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test ${T1#ignored text} data");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\ndata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\rdata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1\tdata");
    EXPECT_EQ( 1u, cnt );
  }
  {
    constexpr auto cnt = argumentsCount("test $1 data");
    EXPECT_EQ( 1u, cnt );
  }
}

TEST_F(ButFormatDetailArgumentsCount, ExceptionIsThrownOnInvalidFormat)
{
  EXPECT_THROW( argumentsCount("$1oops"), Invalid ) << "invalid number";
  EXPECT_THROW( argumentsCount("${1"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("${1 x"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("${1# x"), Invalid ) << "missing closing brace";
  EXPECT_THROW( argumentsCount("test$"), Invalid ) << "variable declaration too short";
  EXPECT_THROW( argumentsCount("test $1}"), Invalid ) << "invalid number";
}

TEST_F(ButFormatDetailArgumentsCount, MultipleArguments)
{
  constexpr auto cnt = argumentsCount("test $1 data $3\t$2\n");
  EXPECT_EQ( 3u, cnt );
}

TEST_F(ButFormatDetailArgumentsCount, MultipleArgumentsMultipleStyles)
{
  constexpr auto cnt = argumentsCount("test $1 data ${3} ${V2#xx} ${T4}");
  EXPECT_EQ( 4u, cnt );
}

TEST_F(ButFormatDetailArgumentsCount, RepeatedArguments)
{
  constexpr auto cnt = argumentsCount("test $1 data $1\t$2\n");
  EXPECT_EQ( 2u, cnt );
}

TEST_F(ButFormatDetailArgumentsCount, NonContinuousArguments)
{
  constexpr auto cnt = argumentsCount("test $42 data $1");
  EXPECT_EQ( 42u, cnt );
}

}
<|endoftext|>


<commit_before><commit_msg>A boring change to make synchronous calls in TabRestore.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2008 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/user_script_slave.h"

#include "base/logging.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/renderer/renderer_resources.h"
#include "googleurl/src/gurl.h"

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {";
static const char kUserScriptTail[] = "\n})(window);";

// UserScript

bool UserScript::MatchesUrl(const GURL& url) {
  for (std::vector<std::string>::iterator pattern = include_patterns_.begin();
       pattern != include_patterns_.end(); ++pattern) {
    if (MatchPattern(url.spec(), *pattern)) {
      return true;
    }
  }

  return false;
}

void UserScript::AddInclude(const std::string &glob_pattern) {
  include_patterns_.push_back(EscapeGlob(glob_pattern));
}

std::string UserScript::EscapeGlob(const std::string& input_pattern) {
  std::string output_pattern;

  for (size_t i = 0; i < input_pattern.length(); ++i) {
    switch (input_pattern[i]) {
      // These characters have special meaning to the MatchPattern() function,
      // so we escape them.
      case '\\':
      case '?':
        output_pattern += '\\';
        // fall through

      default:
        output_pattern += input_pattern[i];
    }
  }

  return output_pattern;
}

// UserScriptSlave
UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      user_script_start_line_(0) {
  // TODO: Only windows supports resources and only windows supports user
  // scrips, so only load the Greasemonkey API on windows.  Fix this when
  // better cross platofrm support is available.
#if defined(OS_WIN)
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);
#endif

  // Count the number of lines that will be injected before the user script.
  StringPiece::size_type pos = 0;
  while ((pos = api_js_.find('\n', pos)) != StringPiece::npos) {
    user_script_start_line_++;
    pos++;
  }

  // Add one more line to account for the function that wraps everything.
  user_script_start_line_++;
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  for (size_t i = 0; i < num_scripts; ++i) {
    const char* url = NULL;
    int url_length = 0;
    const char* body = NULL;
    int body_length = 0;

    pickle.ReadData(&iter, &url, &url_length);
    pickle.ReadData(&iter, &body, &body_length);

    scripts_.push_back(UserScript(StringPiece(url, url_length),
                                  StringPiece(body, body_length)));
    UserScript& script = scripts_.back();

    size_t num_includes;
    pickle.ReadSize(&iter, &num_includes);
    for (size_t j = 0; j < num_includes; ++j) {
      std::string include;
      pickle.ReadString(&iter, &include);
      script.AddInclude(include);
    }
  }

  return true;
}

bool UserScriptSlave::InjectScripts(WebFrame* frame) {
  for (std::vector<UserScript>::iterator script = scripts_.begin();
       script != scripts_.end(); ++script) {
    if (script->MatchesUrl(frame->GetURL())) {
      std::string inject(kUserScriptHead);
      inject.append(api_js_.as_string());
      inject.append(script->GetBody().as_string());
      inject.append(kUserScriptTail);
      frame->ExecuteJavaScript(inject,
                               GURL(script->GetURL().as_string()),
                               -user_script_start_line_);
    }
  }

  return true;
}
<commit_msg>TBR: Fix error line numbers.<commit_after>// Copyright (c) 2008 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/user_script_slave.h"

#include "base/logging.h"
#include "base/pickle.h"
#include "base/shared_memory.h"
#include "chrome/common/resource_bundle.h"
#include "chrome/renderer/renderer_resources.h"
#include "googleurl/src/gurl.h"

// These two strings are injected before and after the Greasemonkey API and
// user script to wrap it in an anonymous scope.
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";

// UserScript

bool UserScript::MatchesUrl(const GURL& url) {
  for (std::vector<std::string>::iterator pattern = include_patterns_.begin();
       pattern != include_patterns_.end(); ++pattern) {
    if (MatchPattern(url.spec(), *pattern)) {
      return true;
    }
  }

  return false;
}

void UserScript::AddInclude(const std::string &glob_pattern) {
  include_patterns_.push_back(EscapeGlob(glob_pattern));
}

std::string UserScript::EscapeGlob(const std::string& input_pattern) {
  std::string output_pattern;

  for (size_t i = 0; i < input_pattern.length(); ++i) {
    switch (input_pattern[i]) {
      // These characters have special meaning to the MatchPattern() function,
      // so we escape them.
      case '\\':
      case '?':
        output_pattern += '\\';
        // fall through

      default:
        output_pattern += input_pattern[i];
    }
  }

  return output_pattern;
}

// UserScriptSlave
UserScriptSlave::UserScriptSlave()
    : shared_memory_(NULL),
      user_script_start_line_(0) {
  // TODO: Only windows supports resources and only windows supports user
  // scrips, so only load the Greasemonkey API on windows.  Fix this when
  // better cross platofrm support is available.
#if defined(OS_WIN)
  api_js_ = ResourceBundle::GetSharedInstance().GetRawDataResource(
                IDR_GREASEMONKEY_API_JS);
#endif

  // Count the number of lines that will be injected before the user script.
  StringPiece::size_type pos = 0;
  while ((pos = api_js_.find('\n', pos)) != StringPiece::npos) {
    user_script_start_line_++;
    pos++;
  }

  // NOTE: There is actually one extra line in the injected script because the
  // function header includes a newline as well. But WebKit expects the
  // numbering to be one-based, not zero-based, so actually *not* accounting for
  // this extra line ends us up with the right offset.
}

bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
  scripts_.clear();

  // Create the shared memory object (read only).
  shared_memory_.reset(new base::SharedMemory(shared_memory, true));
  if (!shared_memory_.get())
    return false;

  // First get the size of the memory block.
  if (!shared_memory_->Map(sizeof(Pickle::Header)))
    return false;
  Pickle::Header* pickle_header =
      reinterpret_cast<Pickle::Header*>(shared_memory_->memory());

  // Now map in the rest of the block.
  int pickle_size = sizeof(Pickle::Header) + pickle_header->payload_size;
  shared_memory_->Unmap();
  if (!shared_memory_->Map(pickle_size))
    return false;

  // Unpickle scripts.
  void* iter = NULL;
  size_t num_scripts = 0;
  Pickle pickle(reinterpret_cast<char*>(shared_memory_->memory()),
                pickle_size);
  pickle.ReadSize(&iter, &num_scripts);

  for (size_t i = 0; i < num_scripts; ++i) {
    const char* url = NULL;
    int url_length = 0;
    const char* body = NULL;
    int body_length = 0;

    pickle.ReadData(&iter, &url, &url_length);
    pickle.ReadData(&iter, &body, &body_length);

    scripts_.push_back(UserScript(StringPiece(url, url_length),
                                  StringPiece(body, body_length)));
    UserScript& script = scripts_.back();

    size_t num_includes;
    pickle.ReadSize(&iter, &num_includes);
    for (size_t j = 0; j < num_includes; ++j) {
      std::string include;
      pickle.ReadString(&iter, &include);
      script.AddInclude(include);
    }
  }

  return true;
}

bool UserScriptSlave::InjectScripts(WebFrame* frame) {
  for (std::vector<UserScript>::iterator script = scripts_.begin();
       script != scripts_.end(); ++script) {
    if (script->MatchesUrl(frame->GetURL())) {
      std::string inject(kUserScriptHead);
      inject.append(api_js_.as_string());
      inject.append(script->GetBody().as_string());
      inject.append(kUserScriptTail);
      frame->ExecuteJavaScript(inject,
                               GURL(script->GetURL().as_string()),
                               -user_script_start_line_);
    }
  }

  return true;
}
<|endoftext|>