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

#include <vector>

#include "testing/gtest/include/gtest/gtest.h"

#include "base/ref_counted.h"
#include "base/string16.h"
#include "base/time.h"
#include "base/waitable_event.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/autofill_change_processor.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_model_associator.h"
#include "chrome/browser/sync/glue/sync_backend_host.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/browser/sync/profile_sync_factory_mock.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_test_util.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
#include "chrome/browser/sync/test_profile_sync_service.h"
#include "chrome/browser/webdata/autofill_entry.h"
#include "chrome/browser/webdata/web_database.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/testing_profile.h"
#include "testing/gmock/include/gmock/gmock.h"

using base::Time;
using base::WaitableEvent;
using browser_sync::AutofillChangeProcessor;
using browser_sync::AutofillDataTypeController;
using browser_sync::AutofillModelAssociator;
using browser_sync::SyncBackendHost;
using browser_sync::UnrecoverableErrorHandler;
using sync_api::SyncManager;
using testing::_;
using testing::DoAll;
using testing::DoDefault;
using testing::Return;
using testing::SetArgumentPointee;

class TestAutofillModelAssociator
    : public TestModelAssociator<AutofillModelAssociator> {
 public:
  TestAutofillModelAssociator(ProfileSyncService* service,
                              WebDatabase* web_database,
                              UnrecoverableErrorHandler* error_handler)
      : TestModelAssociator<AutofillModelAssociator>(
          service, web_database, error_handler) {
  }
};

class WebDatabaseMock : public WebDatabase {
 public:
  MOCK_METHOD2(RemoveFormElement,
               bool(const string16& name, const string16& value));
  MOCK_METHOD1(GetAllAutofillEntries,
               bool(std::vector<AutofillEntry>* entries));
  MOCK_METHOD3(GetAutofillTimestamps,
               bool(const string16& name,
                    const string16& value,
                    std::vector<base::Time>* timestamps));
  MOCK_METHOD1(UpdateAutofillEntries,
               bool(const std::vector<AutofillEntry>& entries));
};

class ProfileMock : public TestingProfile {
 public:
  MOCK_METHOD1(GetWebDataService, WebDataService*(ServiceAccessType access));
};

class DBThreadNotificationService :
    public base::RefCountedThreadSafe<DBThreadNotificationService> {
 public:
  DBThreadNotificationService() : done_event_(false, false) {}

  void Init() {
    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
    ChromeThread::PostTask(
        ChromeThread::DB,
        FROM_HERE,
        NewRunnableMethod(this, &DBThreadNotificationService::InitTask));
    done_event_.Wait();
  }

  void TearDown() {
    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
    ChromeThread::PostTask(
        ChromeThread::DB,
        FROM_HERE,
        NewRunnableMethod(this, &DBThreadNotificationService::TearDownTask));
    done_event_.Wait();
  }

 private:
  friend class base::RefCountedThreadSafe<DBThreadNotificationService>;

  void InitTask() {
    service_.reset(new NotificationService());
    done_event_.Signal();
  }

  void TearDownTask() {
    service_.reset(NULL);
    done_event_.Signal();
  }

  WaitableEvent done_event_;
  scoped_ptr<NotificationService> service_;
};

class WebDataServiceFake : public WebDataService {
 public:
  virtual bool IsDatabaseLoaded() {
    return true;
  }

  // Note that we inject the WebDatabase through the
  // ProfileSyncFactory mock.
  virtual WebDatabase* GetDatabase() {
    return NULL;
  }
};

ACTION(QuitUIMessageLoop) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  MessageLoop::current()->Quit();
}

ACTION_P3(MakeAutofillSyncComponents, service, wd, dtc) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
  AutofillModelAssociator* model_associator =
      new TestAutofillModelAssociator(service, wd, dtc);
  AutofillChangeProcessor* change_processor =
      new AutofillChangeProcessor(model_associator, wd, service);
  return ProfileSyncFactory::SyncComponents(model_associator, change_processor);
}

class ProfileSyncServiceAutofillTest : public testing::Test {
 protected:
  ProfileSyncServiceAutofillTest()
      : ui_thread_(ChromeThread::UI, &message_loop_),
        db_thread_(ChromeThread::DB),
        done_event_(false, false) {
  }

  virtual void SetUp() {
    web_data_service_ = new WebDataServiceFake();
    db_thread_.Start();

    notification_service_ = new DBThreadNotificationService();
    notification_service_->Init();
  }

  virtual void TearDown() {
    service_.reset();
    notification_service_->TearDown();
    db_thread_.Stop();
    MessageLoop::current()->RunAllPending();
  }

  void StartSyncService() {
    if (!service_.get()) {
      service_.reset(new TestProfileSyncService(&factory_, &profile_, false));
      service_->AddObserver(&observer_);
      AutofillDataTypeController* data_type_controller =
          new AutofillDataTypeController(&factory_,
                                         &profile_,
                                         service_.get());

      EXPECT_CALL(factory_, CreateAutofillSyncComponents(_, _, _)).
          WillOnce(MakeAutofillSyncComponents(service_.get(),
                                              &web_database_,
                                              data_type_controller));
      EXPECT_CALL(factory_, CreateDataTypeManager(_)).
          WillOnce(MakeDataTypeManager());

      EXPECT_CALL(profile_, GetWebDataService(_)).
          WillOnce(Return(web_data_service_.get()));

      // State changes once for the backend init and once for startup done.
      EXPECT_CALL(observer_, OnStateChanged()).
          WillOnce(DoDefault()).
          WillOnce(QuitUIMessageLoop());
      service_->RegisterDataTypeController(data_type_controller);
      service_->Initialize();
      MessageLoop::current()->Run();
    }
  }

  void GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries) {
    sync_api::ReadTransaction trans(service_->backend()->GetUserShareHandle());
    int64 autofill_root_id =
        GetFakeServerTaggedNode(&trans, "google_chrome_autofill");
    if (autofill_root_id == sync_api::kInvalidId)
      return;

    sync_api::ReadNode autofill_root(&trans);
    if (!autofill_root.InitByIdLookup(autofill_root_id))
      return;

    int64 child_id = autofill_root.GetFirstChildId();
    while (child_id != sync_api::kInvalidId) {
      sync_api::ReadNode child_node(&trans);
      if (!child_node.InitByIdLookup(child_id))
        return;

      const sync_pb::AutofillSpecifics& autofill(
          child_node.GetAutofillSpecifics());
      AutofillKey key(UTF8ToUTF16(autofill.name()),
                      UTF8ToUTF16(autofill.value()));
      std::vector<base::Time> timestamps;
      int timestamps_count = autofill.usage_timestamp_size();
      for (int i = 0; i < timestamps_count; ++i) {
        timestamps.push_back(Time::FromInternalValue(
            autofill.usage_timestamp(i)));
      }
      entries->push_back(AutofillEntry(key, timestamps));
      child_id = child_node.GetSuccessorId();
    }
  }

  int64 GetFakeServerTaggedNode(sync_api::ReadTransaction* trans,
                                const std::string& tag) {
    std::wstring tag_wide;
    if (!UTF8ToWide(tag.c_str(), tag.length(), &tag_wide))
      return sync_api::kInvalidId;

    sync_api::ReadNode root(trans);
    root.InitByRootLookup();

    int64 last_child_id = sync_api::kInvalidId;
    for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) {
      sync_api::ReadNode child(trans);
      child.InitByIdLookup(id);
      last_child_id = id;
      if (tag_wide == child.GetTitle()) {
        return id;
      }
      id = child.GetSuccessorId();
    }

    return sync_api::kInvalidId;
  }

  void SetIdleChangeProcessorExpectations() {
    EXPECT_CALL(web_database_, RemoveFormElement(_, _)).Times(0);
    EXPECT_CALL(web_database_, GetAutofillTimestamps(_, _, _)).Times(0);
    EXPECT_CALL(web_database_, UpdateAutofillEntries(_)).Times(0);
  }

  static AutofillEntry MakeAutofillEntry(const char* name,
                                         const char* value,
                                         time_t timestamp) {
    std::vector<Time> timestamps;
    timestamps.push_back(Time::FromTimeT(timestamp));
    return AutofillEntry(
        AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps);
  }

  MessageLoopForUI message_loop_;
  ChromeThread ui_thread_;
  ChromeThread db_thread_;
  WaitableEvent done_event_;
  scoped_refptr<DBThreadNotificationService> notification_service_;

  scoped_ptr<TestProfileSyncService> service_;
  ProfileMock profile_;
  ProfileSyncFactoryMock factory_;
  ProfileSyncServiceObserverMock observer_;
  WebDatabaseMock web_database_;
  scoped_refptr<WebDataService> web_data_service_;
};

// TODO(sync): Test unrecoverable error during MA.

TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) {
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  EXPECT_EQ(0U, sync_entries.size());
}

TEST_F(ProfileSyncServiceAutofillTest, HasNativeEmptySync) {
  std::vector<AutofillEntry> entries;
  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  ASSERT_EQ(1U, entries.size());
  EXPECT_TRUE(entries[0] == sync_entries[0]);
}

TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) {
  // There is buggy autofill code that allows duplicate name/value
  // pairs to exist in the database with separate pair_ids.
  std::vector<AutofillEntry> entries;
  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
  entries.push_back(MakeAutofillEntry("dup", "", 2));
  entries.push_back(MakeAutofillEntry("dup", "", 3));
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  EXPECT_EQ(2U, sync_entries.size());
}
<commit_msg>Disable ProfileSyncServiceAutofillTest since they're causing hangs.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "testing/gtest/include/gtest/gtest.h"

#include "base/ref_counted.h"
#include "base/string16.h"
#include "base/time.h"
#include "base/waitable_event.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/autofill_change_processor.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_model_associator.h"
#include "chrome/browser/sync/glue/sync_backend_host.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/browser/sync/profile_sync_factory_mock.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_test_util.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
#include "chrome/browser/sync/test_profile_sync_service.h"
#include "chrome/browser/webdata/autofill_entry.h"
#include "chrome/browser/webdata/web_database.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/testing_profile.h"
#include "testing/gmock/include/gmock/gmock.h"

using base::Time;
using base::WaitableEvent;
using browser_sync::AutofillChangeProcessor;
using browser_sync::AutofillDataTypeController;
using browser_sync::AutofillModelAssociator;
using browser_sync::SyncBackendHost;
using browser_sync::UnrecoverableErrorHandler;
using sync_api::SyncManager;
using testing::_;
using testing::DoAll;
using testing::DoDefault;
using testing::Return;
using testing::SetArgumentPointee;

class TestAutofillModelAssociator
    : public TestModelAssociator<AutofillModelAssociator> {
 public:
  TestAutofillModelAssociator(ProfileSyncService* service,
                              WebDatabase* web_database,
                              UnrecoverableErrorHandler* error_handler)
      : TestModelAssociator<AutofillModelAssociator>(
          service, web_database, error_handler) {
  }
};

class WebDatabaseMock : public WebDatabase {
 public:
  MOCK_METHOD2(RemoveFormElement,
               bool(const string16& name, const string16& value));
  MOCK_METHOD1(GetAllAutofillEntries,
               bool(std::vector<AutofillEntry>* entries));
  MOCK_METHOD3(GetAutofillTimestamps,
               bool(const string16& name,
                    const string16& value,
                    std::vector<base::Time>* timestamps));
  MOCK_METHOD1(UpdateAutofillEntries,
               bool(const std::vector<AutofillEntry>& entries));
};

class ProfileMock : public TestingProfile {
 public:
  MOCK_METHOD1(GetWebDataService, WebDataService*(ServiceAccessType access));
};

class DBThreadNotificationService :
    public base::RefCountedThreadSafe<DBThreadNotificationService> {
 public:
  DBThreadNotificationService() : done_event_(false, false) {}

  void Init() {
    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
    ChromeThread::PostTask(
        ChromeThread::DB,
        FROM_HERE,
        NewRunnableMethod(this, &DBThreadNotificationService::InitTask));
    done_event_.Wait();
  }

  void TearDown() {
    DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
    ChromeThread::PostTask(
        ChromeThread::DB,
        FROM_HERE,
        NewRunnableMethod(this, &DBThreadNotificationService::TearDownTask));
    done_event_.Wait();
  }

 private:
  friend class base::RefCountedThreadSafe<DBThreadNotificationService>;

  void InitTask() {
    service_.reset(new NotificationService());
    done_event_.Signal();
  }

  void TearDownTask() {
    service_.reset(NULL);
    done_event_.Signal();
  }

  WaitableEvent done_event_;
  scoped_ptr<NotificationService> service_;
};

class WebDataServiceFake : public WebDataService {
 public:
  virtual bool IsDatabaseLoaded() {
    return true;
  }

  // Note that we inject the WebDatabase through the
  // ProfileSyncFactory mock.
  virtual WebDatabase* GetDatabase() {
    return NULL;
  }
};

ACTION(QuitUIMessageLoop) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  MessageLoop::current()->Quit();
}

ACTION_P3(MakeAutofillSyncComponents, service, wd, dtc) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
  AutofillModelAssociator* model_associator =
      new TestAutofillModelAssociator(service, wd, dtc);
  AutofillChangeProcessor* change_processor =
      new AutofillChangeProcessor(model_associator, wd, service);
  return ProfileSyncFactory::SyncComponents(model_associator, change_processor);
}

class ProfileSyncServiceAutofillTest : public testing::Test {
 protected:
  ProfileSyncServiceAutofillTest()
      : ui_thread_(ChromeThread::UI, &message_loop_),
        db_thread_(ChromeThread::DB),
        done_event_(false, false) {
  }

  virtual void SetUp() {
    web_data_service_ = new WebDataServiceFake();
    db_thread_.Start();

    notification_service_ = new DBThreadNotificationService();
    notification_service_->Init();
  }

  virtual void TearDown() {
    service_.reset();
    notification_service_->TearDown();
    db_thread_.Stop();
    MessageLoop::current()->RunAllPending();
  }

  void StartSyncService() {
    if (!service_.get()) {
      service_.reset(new TestProfileSyncService(&factory_, &profile_, false));
      service_->AddObserver(&observer_);
      AutofillDataTypeController* data_type_controller =
          new AutofillDataTypeController(&factory_,
                                         &profile_,
                                         service_.get());

      EXPECT_CALL(factory_, CreateAutofillSyncComponents(_, _, _)).
          WillOnce(MakeAutofillSyncComponents(service_.get(),
                                              &web_database_,
                                              data_type_controller));
      EXPECT_CALL(factory_, CreateDataTypeManager(_)).
          WillOnce(MakeDataTypeManager());

      EXPECT_CALL(profile_, GetWebDataService(_)).
          WillOnce(Return(web_data_service_.get()));

      // State changes once for the backend init and once for startup done.
      EXPECT_CALL(observer_, OnStateChanged()).
          WillOnce(DoDefault()).
          WillOnce(QuitUIMessageLoop());
      service_->RegisterDataTypeController(data_type_controller);
      service_->Initialize();
      MessageLoop::current()->Run();
    }
  }

  void GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries) {
    sync_api::ReadTransaction trans(service_->backend()->GetUserShareHandle());
    int64 autofill_root_id =
        GetFakeServerTaggedNode(&trans, "google_chrome_autofill");
    if (autofill_root_id == sync_api::kInvalidId)
      return;

    sync_api::ReadNode autofill_root(&trans);
    if (!autofill_root.InitByIdLookup(autofill_root_id))
      return;

    int64 child_id = autofill_root.GetFirstChildId();
    while (child_id != sync_api::kInvalidId) {
      sync_api::ReadNode child_node(&trans);
      if (!child_node.InitByIdLookup(child_id))
        return;

      const sync_pb::AutofillSpecifics& autofill(
          child_node.GetAutofillSpecifics());
      AutofillKey key(UTF8ToUTF16(autofill.name()),
                      UTF8ToUTF16(autofill.value()));
      std::vector<base::Time> timestamps;
      int timestamps_count = autofill.usage_timestamp_size();
      for (int i = 0; i < timestamps_count; ++i) {
        timestamps.push_back(Time::FromInternalValue(
            autofill.usage_timestamp(i)));
      }
      entries->push_back(AutofillEntry(key, timestamps));
      child_id = child_node.GetSuccessorId();
    }
  }

  int64 GetFakeServerTaggedNode(sync_api::ReadTransaction* trans,
                                const std::string& tag) {
    std::wstring tag_wide;
    if (!UTF8ToWide(tag.c_str(), tag.length(), &tag_wide))
      return sync_api::kInvalidId;

    sync_api::ReadNode root(trans);
    root.InitByRootLookup();

    int64 last_child_id = sync_api::kInvalidId;
    for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) {
      sync_api::ReadNode child(trans);
      child.InitByIdLookup(id);
      last_child_id = id;
      if (tag_wide == child.GetTitle()) {
        return id;
      }
      id = child.GetSuccessorId();
    }

    return sync_api::kInvalidId;
  }

  void SetIdleChangeProcessorExpectations() {
    EXPECT_CALL(web_database_, RemoveFormElement(_, _)).Times(0);
    EXPECT_CALL(web_database_, GetAutofillTimestamps(_, _, _)).Times(0);
    EXPECT_CALL(web_database_, UpdateAutofillEntries(_)).Times(0);
  }

  static AutofillEntry MakeAutofillEntry(const char* name,
                                         const char* value,
                                         time_t timestamp) {
    std::vector<Time> timestamps;
    timestamps.push_back(Time::FromTimeT(timestamp));
    return AutofillEntry(
        AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), timestamps);
  }

  MessageLoopForUI message_loop_;
  ChromeThread ui_thread_;
  ChromeThread db_thread_;
  WaitableEvent done_event_;
  scoped_refptr<DBThreadNotificationService> notification_service_;

  scoped_ptr<TestProfileSyncService> service_;
  ProfileMock profile_;
  ProfileSyncFactoryMock factory_;
  ProfileSyncServiceObserverMock observer_;
  WebDatabaseMock web_database_;
  scoped_refptr<WebDataService> web_data_service_;
};

// TODO(sync): Test unrecoverable error during MA.

// http://code.google.com/p/chromium/issues/detail?id=37244
TEST_F(ProfileSyncServiceAutofillTest, DISABLED_EmptyNativeEmptySync) {
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).WillOnce(Return(true));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  EXPECT_EQ(0U, sync_entries.size());
}

// http://code.google.com/p/chromium/issues/detail?id=37244
TEST_F(ProfileSyncServiceAutofillTest, DISABLED_HasNativeEmptySync) {
  std::vector<AutofillEntry> entries;
  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  ASSERT_EQ(1U, entries.size());
  EXPECT_TRUE(entries[0] == sync_entries[0]);
}

// http://code.google.com/p/chromium/issues/detail?id=37244
TEST_F(ProfileSyncServiceAutofillTest, DISABLED_HasNativeWithDuplicatesEmptySync) {
  // There is buggy autofill code that allows duplicate name/value
  // pairs to exist in the database with separate pair_ids.
  std::vector<AutofillEntry> entries;
  entries.push_back(MakeAutofillEntry("foo", "bar", 1));
  entries.push_back(MakeAutofillEntry("dup", "", 2));
  entries.push_back(MakeAutofillEntry("dup", "", 3));
  EXPECT_CALL(web_database_, GetAllAutofillEntries(_)).
      WillOnce(DoAll(SetArgumentPointee<0>(entries), Return(true)));
  SetIdleChangeProcessorExpectations();
  StartSyncService();
  std::vector<AutofillEntry> sync_entries;
  GetAutofillEntriesFromSyncDB(&sync_entries);
  EXPECT_EQ(2U, sync_entries.size());
}
<|endoftext|>


<commit_before>#include "../Framework.hpp"

#include "../../core/jni_helper.hpp"

namespace {
  ::Framework * frm() { return g_framework->NativeFramework(); }
}

extern "C"
{
  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_bookmarks_PopupLayout_nDrawBookmark(JNIEnv * env, jobject thiz, jdouble x, jdouble y)
  {
    frm()->DrawPlacemark(frm()->PtoG(m2::PointD(x, y)));
  }

  JNIEXPORT void JNICALL
    Java_com_mapswithme_maps_bookmarks_PopupLayout_nRemoveBookmark(JNIEnv * env, jobject thiz)
    {
      frm()->DisablePlacemark();
    }
}
<commit_msg>[android] [bookmarks] invalidate map after draw preview pin<commit_after>#include "../Framework.hpp"

#include "../../core/jni_helper.hpp"

namespace {
  ::Framework * frm() { return g_framework->NativeFramework(); }
}

extern "C"
{
  JNIEXPORT void JNICALL
  Java_com_mapswithme_maps_bookmarks_PopupLayout_nDrawBookmark(JNIEnv * env, jobject thiz, jdouble x, jdouble y)
  {
    frm()->DrawPlacemark(frm()->PtoG(m2::PointD(x, y)));
    frm()->Invalidate();
  }

  JNIEXPORT void JNICALL
    Java_com_mapswithme_maps_bookmarks_PopupLayout_nRemoveBookmark(JNIEnv * env, jobject thiz)
    {
      frm()->DisablePlacemark();
      frm()->Invalidate();
    }
}
<|endoftext|>


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

#include "temp_scaffolding_stubs.h"

#include "base/file_util.h"
#include "base/logging.h"
#include "base/thread.h"
#include "base/path_service.h"
#include "base/singleton.h"
#include "base/task.h"
#include "build/build_config.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/process_watcher.h"
#include "chrome/common/resource_bundle.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webcursor.h"

// static
size_t SessionRestore::num_tabs_to_load_ = 0;

//--------------------------------------------------------------------------

UserDataManager* UserDataManager::instance_ = NULL;

UserDataManager* UserDataManager::Create() {
  DCHECK(!instance_);
  std::wstring user_data;
  PathService::Get(chrome::DIR_USER_DATA, &user_data);
  instance_ = new UserDataManager(user_data);
  return instance_;
}

UserDataManager* UserDataManager::Get() {
  DCHECK(instance_);
  return instance_;
}

bool ShellIntegration::SetAsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

//--------------------------------------------------------------------------

namespace browser_shutdown {
bool delete_resources_on_shutdown = true;
void ReadLastShutdownInfo()  { NOTIMPLEMENTED(); }
void Shutdown() { NOTIMPLEMENTED(); }
void OnShutdownStarting(ShutdownType type) { NOTIMPLEMENTED(); }
}

// static
bool FirstRun::IsChromeFirstRun() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details) {
  NOTIMPLEMENTED();
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  NOTIMPLEMENTED();
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  NOTIMPLEMENTED();
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  NOTIMPLEMENTED();
  return true;
}

void OpenFirstRunDialog(Profile* profile) { NOTIMPLEMENTED(); }

GURL NewTabUIURL() {
  NOTIMPLEMENTED();
  return GURL();
}

//--------------------------------------------------------------------------

PluginService* PluginService::GetInstance() {
  return Singleton<PluginService>::get();
}

PluginService::PluginService()
    : main_message_loop_(MessageLoop::current()),
      resource_dispatcher_host_(NULL),
      ui_locale_(g_browser_process->GetApplicationLocale()),
      plugin_shutdown_handler_(NULL) {
}

PluginService::~PluginService() {
}

void PluginService::SetChromePluginDataDir(const FilePath& data_dir) {
  AutoLock lock(lock_);
  chrome_plugin_data_dir_ = data_dir;
}

//--------------------------------------------------------------------------

void InstallJankometer(const CommandLine&) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

void Browser::Observe(NotificationType type,
                      const NotificationSource& source,
                      const NotificationDetails& details) {
  NOTIMPLEMENTED();
}

GURL Browser::GetHomePage() {
  NOTIMPLEMENTED();
  return GURL("http://dev.chromium.org");
}

void Browser::LoadingStateChanged(TabContents* source) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

TabContents* TabContents::CreateWithType(TabContentsType type,
                                         Profile* profile,
                                         SiteInstance* instance) {
  switch (type) {
    case TAB_CONTENTS_WEB:
      return new WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL);
    default:
      NOTIMPLEMENTED();
      return NULL;
  }
}

void TabContents::SetupController(Profile* profile) {
  DCHECK(!controller_);
  controller_ = new NavigationController(this, profile);
}

Profile* TabContents::profile() const {
  return controller_ ? controller_->profile() : NULL;
}

//--------------------------------------------------------------------------

class RenderWidgetHostViewStub : public RenderWidgetHostView {
 public:
  RenderWidgetHostViewStub(RenderWidgetHost* host) {
    host->set_view(this);
  }
};

RenderWidgetHostView*
    WebContentsView::CreateViewForWidget(RenderWidgetHost* host) {
  NOTIMPLEMENTED();
  return new RenderWidgetHostViewStub(host);
}

//--------------------------------------------------------------------------

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  NOTIMPLEMENTED();
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  NOTIMPLEMENTED();
  return false;
}

// This depends on porting all the plugin IPC messages.
bool IsPluginProcess() {
  NOTIMPLEMENTED();
  return false;
}

#if defined(OS_MACOSX)
// We link this in for now to avoid hauling in all of WebCore (which we will
// have to eventually do).
namespace webkit_glue {
std::string GetUserAgent(const GURL& url) {
  NOTIMPLEMENTED();
  return "";
}
// TODO(pinkerton): when these are removed, mock_webkit_glue.cc
// must be re-added to the unit_test target for tests.
void SetRecordPlaybackMode(bool) { }
void SetJavaScriptFlags(const std::wstring&) { }
void CheckForLeaks() { }
std::string CreateHistoryStateForURL(const GURL& url) { return ""; }
}
#endif

#if defined(OS_LINUX)
BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
  NOTIMPLEMENTED() << "CreateBrowserWindow";
  return NULL;
}
#endif

//--------------------------------------------------------------------------

namespace chrome_browser_net {

void EnableDnsPrefetch(bool) { NOTIMPLEMENTED(); }

}  // namespace chrome_browser_net

//--------------------------------------------------------------------------

void RunJavascriptMessageBox(WebContents* web_contents,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

bool SSLManager::DeserializeSecurityInfo(const std::string&, int*, int*, int*) {
  NOTIMPLEMENTED();
  return false;
}

void SSLManager::OnSSLCertificateError(
    ResourceDispatcherHost* resource_dispatcher,
    URLRequest* request,
    int cert_error,
    net::X509Certificate* cert,
    MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

ResourceMessageFilter::ResourceMessageFilter(
    ResourceDispatcherHost* resource_dispatcher_host,
    PluginService* plugin_service,
    printing::PrintJobManager* print_job_manager,
    int render_process_host_id,
    Profile* profile,
    RenderWidgetHelper* render_widget_helper,
    SpellChecker* spellchecker)
      : ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) {
}
ResourceMessageFilter::~ResourceMessageFilter() { NOTIMPLEMENTED(); }
void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
  NOTIMPLEMENTED();
}
void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
  NOTIMPLEMENTED();
}
void ResourceMessageFilter::OnChannelClosing() { NOTIMPLEMENTED(); }
bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
  NOTIMPLEMENTED();
  return false;
}
bool ResourceMessageFilter::Send(IPC::Message* message) {
  NOTIMPLEMENTED();
  return false;
}
void ResourceMessageFilter::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) { }
void ResourceMessageFilter::OnResolveProxyCompleted(
    IPC::Message* reply_msg,int result, const std::string& proxy_list) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;

// GetBitmapNamed() will leak, but there's no way around it for stubs.
SkBitmap* ResourceBundle::GetBitmapNamed(int) {
  NOTIMPLEMENTED();
  return new SkBitmap();
}
ResourceBundle::ResourceBundle() { }
ResourceBundle& ResourceBundle::GetSharedInstance() {
  NOTIMPLEMENTED();
  if (!g_shared_instance_)
    g_shared_instance_ = new ResourceBundle;
  return *g_shared_instance_;
}
#endif

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

namespace tab_util {

bool GetTabContentsID(URLRequest* request,
                      int* render_process_host_id,
                      int* routing_id) {
  NOTIMPLEMENTED();
  return true;
}

WebContents* GetWebContentsByID(int render_process_host_id,
                                int render_view_id) {
  NOTIMPLEMENTED();
  return NULL;
}

}  // namespace

void ProcessWatcher::EnsureProcessTerminated(int) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
WebCursor::WebCursor() {
}
WebCursor::~WebCursor() {
}
bool WebCursor::Deserialize(const Pickle* pickle, void** iter) {
  NOTIMPLEMENTED();
  return false;
}
#endif

<commit_msg>Fix linker error on Linux & Mac by stubbing out a function. Review URL: http://codereview.chromium.org/20100<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "base/file_util.h"
#include "base/logging.h"
#include "base/thread.h"
#include "base/path_service.h"
#include "base/singleton.h"
#include "base/task.h"
#include "build/build_config.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/cache_manager_host.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_service.h"
#include "chrome/common/process_watcher.h"
#include "chrome/common/resource_bundle.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webcursor.h"

// static
size_t SessionRestore::num_tabs_to_load_ = 0;

//--------------------------------------------------------------------------

UserDataManager* UserDataManager::instance_ = NULL;

UserDataManager* UserDataManager::Create() {
  DCHECK(!instance_);
  std::wstring user_data;
  PathService::Get(chrome::DIR_USER_DATA, &user_data);
  instance_ = new UserDataManager(user_data);
  return instance_;
}

UserDataManager* UserDataManager::Get() {
  DCHECK(instance_);
  return instance_;
}

bool ShellIntegration::SetAsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

//--------------------------------------------------------------------------

namespace browser_shutdown {
bool delete_resources_on_shutdown = true;
void ReadLastShutdownInfo()  { NOTIMPLEMENTED(); }
void Shutdown() { NOTIMPLEMENTED(); }
void OnShutdownStarting(ShutdownType type) { NOTIMPLEMENTED(); }
}

// static
bool FirstRun::IsChromeFirstRun() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details) {
  NOTIMPLEMENTED();
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  NOTIMPLEMENTED();
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  NOTIMPLEMENTED();
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  NOTIMPLEMENTED();
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  NOTIMPLEMENTED();
  return true;
}

void OpenFirstRunDialog(Profile* profile) { NOTIMPLEMENTED(); }

GURL NewTabUIURL() {
  NOTIMPLEMENTED();
  return GURL();
}

//--------------------------------------------------------------------------

PluginService* PluginService::GetInstance() {
  return Singleton<PluginService>::get();
}

PluginService::PluginService()
    : main_message_loop_(MessageLoop::current()),
      resource_dispatcher_host_(NULL),
      ui_locale_(g_browser_process->GetApplicationLocale()),
      plugin_shutdown_handler_(NULL) {
}

PluginService::~PluginService() {
}

void PluginService::SetChromePluginDataDir(const FilePath& data_dir) {
  AutoLock lock(lock_);
  chrome_plugin_data_dir_ = data_dir;
}

//--------------------------------------------------------------------------

void InstallJankometer(const CommandLine&) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

void Browser::Observe(NotificationType type,
                      const NotificationSource& source,
                      const NotificationDetails& details) {
  NOTIMPLEMENTED();
}

GURL Browser::GetHomePage() {
  NOTIMPLEMENTED();
  return GURL("http://dev.chromium.org");
}

void Browser::LoadingStateChanged(TabContents* source) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

TabContents* TabContents::CreateWithType(TabContentsType type,
                                         Profile* profile,
                                         SiteInstance* instance) {
  switch (type) {
    case TAB_CONTENTS_WEB:
      return new WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL);
    default:
      NOTIMPLEMENTED();
      return NULL;
  }
}

void TabContents::SetupController(Profile* profile) {
  DCHECK(!controller_);
  controller_ = new NavigationController(this, profile);
}

Profile* TabContents::profile() const {
  return controller_ ? controller_->profile() : NULL;
}

//--------------------------------------------------------------------------

class RenderWidgetHostViewStub : public RenderWidgetHostView {
 public:
  RenderWidgetHostViewStub(RenderWidgetHost* host) {
    host->set_view(this);
  }
};

RenderWidgetHostView*
    WebContentsView::CreateViewForWidget(RenderWidgetHost* host) {
  NOTIMPLEMENTED();
  return new RenderWidgetHostViewStub(host);
}

//--------------------------------------------------------------------------

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  NOTIMPLEMENTED();
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  NOTIMPLEMENTED();
  return false;
}

// This depends on porting all the plugin IPC messages.
bool IsPluginProcess() {
  NOTIMPLEMENTED();
  return false;
}

#if defined(OS_MACOSX)
// We link this in for now to avoid hauling in all of WebCore (which we will
// have to eventually do).
namespace webkit_glue {
std::string GetUserAgent(const GURL& url) {
  NOTIMPLEMENTED();
  return "";
}
// TODO(pinkerton): when these are removed, mock_webkit_glue.cc
// must be re-added to the unit_test target for tests.
void SetRecordPlaybackMode(bool) { }
void SetJavaScriptFlags(const std::wstring&) { }
void CheckForLeaks() { }
std::string CreateHistoryStateForURL(const GURL& url) { return ""; }
}
#endif

#if defined(OS_LINUX)
BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
  NOTIMPLEMENTED() << "CreateBrowserWindow";
  return NULL;
}
#endif

//--------------------------------------------------------------------------

namespace chrome_browser_net {

void EnableDnsPrefetch(bool) { NOTIMPLEMENTED(); }

}  // namespace chrome_browser_net

//--------------------------------------------------------------------------

void RunJavascriptMessageBox(WebContents* web_contents,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  NOTIMPLEMENTED();
}

bool SSLManager::DeserializeSecurityInfo(const std::string&, int*, int*, int*) {
  NOTIMPLEMENTED();
  return false;
}

void SSLManager::OnSSLCertificateError(
    ResourceDispatcherHost* resource_dispatcher,
    URLRequest* request,
    int cert_error,
    net::X509Certificate* cert,
    MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

ResourceMessageFilter::ResourceMessageFilter(
    ResourceDispatcherHost* resource_dispatcher_host,
    PluginService* plugin_service,
    printing::PrintJobManager* print_job_manager,
    int render_process_host_id,
    Profile* profile,
    RenderWidgetHelper* render_widget_helper,
    SpellChecker* spellchecker)
      : ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) {
}
ResourceMessageFilter::~ResourceMessageFilter() { NOTIMPLEMENTED(); }
void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
  NOTIMPLEMENTED();
}
void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
  NOTIMPLEMENTED();
}
void ResourceMessageFilter::OnChannelClosing() { NOTIMPLEMENTED(); }
bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
  NOTIMPLEMENTED();
  return false;
}
bool ResourceMessageFilter::Send(IPC::Message* message) {
  NOTIMPLEMENTED();
  return false;
}
void ResourceMessageFilter::Observe(NotificationType type,
                                    const NotificationSource& source,
                                    const NotificationDetails& details) { }
void ResourceMessageFilter::OnResolveProxyCompleted(
    IPC::Message* reply_msg,int result, const std::string& proxy_list) {
  NOTIMPLEMENTED();
}

void RunRepostFormWarningDialog(NavigationController*) {
}

#if defined(OS_MACOSX)
ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;

// GetBitmapNamed() will leak, but there's no way around it for stubs.
SkBitmap* ResourceBundle::GetBitmapNamed(int) {
  NOTIMPLEMENTED();
  return new SkBitmap();
}
ResourceBundle::ResourceBundle() { }
ResourceBundle& ResourceBundle::GetSharedInstance() {
  NOTIMPLEMENTED();
  if (!g_shared_instance_)
    g_shared_instance_ = new ResourceBundle;
  return *g_shared_instance_;
}
#endif

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

namespace tab_util {

bool GetTabContentsID(URLRequest* request,
                      int* render_process_host_id,
                      int* routing_id) {
  NOTIMPLEMENTED();
  return true;
}

WebContents* GetWebContentsByID(int render_process_host_id,
                                int render_view_id) {
  NOTIMPLEMENTED();
  return NULL;
}

}  // namespace

void ProcessWatcher::EnsureProcessTerminated(int) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
WebCursor::WebCursor() {
}
WebCursor::~WebCursor() {
}
bool WebCursor::Deserialize(const Pickle* pickle, void** iter) {
  NOTIMPLEMENTED();
  return false;
}
#endif

<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "defines.hpp"
#include "strongint.hpp"
#include "typetraits.hpp"
#include "utility.hpp"

#define OxError(...) ox::Error(__FILE__, __LINE__, __VA_ARGS__)

namespace ox {

using ErrorCode = uint16_t;

struct [[nodiscard]] Error {
	const char *msg = nullptr;
	const char *file = nullptr;
	uint16_t line = 0;
	ErrorCode errCode = 0;

	explicit constexpr Error(ErrorCode ec = 0) noexcept: errCode(ec) {
	}

	explicit constexpr Error(const char *file, uint32_t line, ErrorCode errCode, const char *msg = nullptr) noexcept {
		this->file = file;
		this->line = line;
		this->msg = msg;
		this->errCode = errCode;
	}

	constexpr Error(const Error &o) noexcept {
		this->msg = o.msg;
		this->file = o.file;
		this->line = o.line;
		this->errCode = o.errCode;
	}

	constexpr Error &operator=(const Error &o) noexcept {
		this->msg = o.msg;
		this->file = o.file;
		this->line = o.line;
		this->errCode = o.errCode;
		return *this;
	}

	constexpr operator uint64_t() const noexcept {
		return errCode;
	}

};

template<typename T>
struct [[nodiscard]] Result {

	using type = typename remove_reference<T>::type;

	T value;
	Error error;

	constexpr Result() noexcept: error(0) {
	}

	constexpr Result(const Error &error) noexcept: error(error) {
	}

	constexpr Result(const type &value, const Error &error = OxError(0)) noexcept: value(const_cast<type&>(value)), error(error) {
	}

	constexpr Result(type &&value, const Error &error = OxError(0)) noexcept: value(move(value)), error(error) {
	}

	explicit constexpr operator const type&() const noexcept {
		return value;
	}

	explicit constexpr operator type&() noexcept {
		return value;
	}

	[[nodiscard]]
	constexpr bool ok() const noexcept {
		return error == 0;
	}

	constexpr Error get(type *val) const noexcept {
		*val = value;
		return error;
	}

	constexpr Error get(type *val) noexcept {
		*val = value;
		return error;
	}

	constexpr Error moveTo(type *val) noexcept {
		*val = move(value);
		return error;
	}

};

namespace detail {

constexpr Error toError(const Error &e) noexcept {
	return e;
}

template<typename T>
constexpr Error toError(const Result<T> &ve) noexcept {
	return ve.error;
}

}

}

constexpr void oxIgnoreError(ox::Error) noexcept {}
#if __cplusplus >= 202002L
#define oxReturnError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] return _ox_error
#define oxThrowError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] throw _ox_error
#else
#define oxReturnError(err) if (const auto _ox_error = ox::detail::toError(err)) return _ox_error
#define oxThrowError(err) if (const auto _ox_error = ox::detail::toError(err)) throw _ox_error
#endif
#define oxConcatImpl(a, b) a##b
#define oxConcat(a, b) oxConcatImpl(a, b)
// oxRequire Mutable
#define oxRequireM(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
#define oxRequire(out, x) const oxRequireM(out, x)
// oxRequire Mutable Throw
#define oxRequireMT(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxThrowError(oxConcat(oxRequire_err_, __LINE__))
// oxRequire Throw
#define oxRequireT(out, x) const oxRequireMT(out, x)

<commit_msg>[ox/std] Make oxThrowError do a move to satisfy clang-tidy<commit_after>/*
 * Copyright 2015 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "defines.hpp"
#include "strongint.hpp"
#include "typetraits.hpp"
#include "utility.hpp"

#define OxError(...) ox::Error(__FILE__, __LINE__, __VA_ARGS__)

namespace ox {

using ErrorCode = uint16_t;

struct [[nodiscard]] Error {
	const char *msg = nullptr;
	const char *file = nullptr;
	uint16_t line = 0;
	ErrorCode errCode = 0;

	explicit constexpr Error(ErrorCode ec = 0) noexcept: errCode(ec) {
	}

	explicit constexpr Error(const char *file, uint32_t line, ErrorCode errCode, const char *msg = nullptr) noexcept {
		this->file = file;
		this->line = line;
		this->msg = msg;
		this->errCode = errCode;
	}

	constexpr Error(const Error &o) noexcept {
		this->msg = o.msg;
		this->file = o.file;
		this->line = o.line;
		this->errCode = o.errCode;
	}

	constexpr Error &operator=(const Error &o) noexcept {
		this->msg = o.msg;
		this->file = o.file;
		this->line = o.line;
		this->errCode = o.errCode;
		return *this;
	}

	constexpr operator uint64_t() const noexcept {
		return errCode;
	}

};

template<typename T>
struct [[nodiscard]] Result {

	using type = typename remove_reference<T>::type;

	T value;
	Error error;

	constexpr Result() noexcept: error(0) {
	}

	constexpr Result(const Error &error) noexcept: error(error) {
	}

	constexpr Result(const type &value, const Error &error = OxError(0)) noexcept: value(const_cast<type&>(value)), error(error) {
	}

	constexpr Result(type &&value, const Error &error = OxError(0)) noexcept: value(move(value)), error(error) {
	}

	explicit constexpr operator const type&() const noexcept {
		return value;
	}

	explicit constexpr operator type&() noexcept {
		return value;
	}

	[[nodiscard]]
	constexpr bool ok() const noexcept {
		return error == 0;
	}

	constexpr Error get(type *val) const noexcept {
		*val = value;
		return error;
	}

	constexpr Error get(type *val) noexcept {
		*val = value;
		return error;
	}

	constexpr Error moveTo(type *val) noexcept {
		*val = move(value);
		return error;
	}

};

namespace detail {

constexpr Error toError(const Error &e) noexcept {
	return e;
}

template<typename T>
constexpr Error toError(const Result<T> &ve) noexcept {
	return ve.error;
}

}

}

constexpr void oxIgnoreError(ox::Error) noexcept {}
#if __cplusplus >= 202002L
#define oxReturnError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] return _ox_error
#define oxThrowError(x) if (const auto _ox_error = ox::detail::toError(x)) [[unlikely]] throw _ox_error
#else
#define oxReturnError(err) if (const auto _ox_error = ox::detail::toError(err)) return _ox_error
#define oxThrowError(err) if (const auto _ox_error = ox::detail::toError(err)) throw ox::move(_ox_error)
#endif
#define oxConcatImpl(a, b) a##b
#define oxConcat(a, b) oxConcatImpl(a, b)
// oxRequire Mutable
#define oxRequireM(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
#define oxRequire(out, x) const oxRequireM(out, x)
// oxRequire Mutable Throw
#define oxRequireMT(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxThrowError(oxConcat(oxRequire_err_, __LINE__))
// oxRequire Throw
#define oxRequireT(out, x) const oxRequireMT(out, x)

<|endoftext|>


<commit_before>/*
 * Copyright 2014 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.
 */

//
// Test for resource open before PPAPI initialization.
//

#include <stdio.h>
#include <string.h>

#include <sstream>
#include <string>
#include <vector>

#include "native_client/src/untrusted/irt/irt.h"
#include "native_client/src/untrusted/nacl/nacl_irt.h"

#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"

std::vector<std::string> result;

pp::Instance* g_instance = NULL;

std::string LoadManifestSuccess(TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }
  int desc;
  int error;
  error = nacl_irt_resource_open.open_resource("test_file", &desc);
  if (0 != error) {
    printf("Can't open file, error=%d", error);
    return "Can't open file";
  }

  std::string str;

  char buffer[4096];
  int len;
  while ((len = read(desc, buffer, sizeof buffer - 1)) > 0) {
    // Null terminate.
    buffer[len] = '\0';
    str += buffer;
  }

  if (str != "Test File Content") {
    printf("Wrong file content: \"%s\"\n", str.c_str());
    return "Wrong file content: " + str;
  }

  return "Pass";
}

std::string LoadManifestNonExistentEntry(
    TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }

  int desc;
  int error = nacl_irt_resource_open.open_resource("non_existent_entry", &desc);

  // We expect ENOENT here, as it does not exist.
  if (error != ENOENT) {
    printf("Unexpected error code: %d\n", error);
    char buf[80];
    snprintf(buf, sizeof(buf), "open_resource() result: %d", error);
    return std::string(buf);
  }

  return "Pass";
}

std::string LoadManifestNonExistentFile(
    TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }

  int desc;
  int error = nacl_irt_resource_open.open_resource("dummy_test_file", &desc);

  // We expect ENOENT here, as it does not exist.
  if (error != ENOENT) {
    printf("Unexpected error code: %d\n", error);
    char buf[80];
    snprintf(buf, sizeof(buf), "open_resource() result: %d", error);
    return std::string(buf);
  }

  return "Pass";
}

void RunTests() {
  result.push_back(LoadManifestSuccess(&__nacl_irt_query));
  result.push_back(LoadManifestNonExistentEntry(&__nacl_irt_query));
  result.push_back(LoadManifestNonExistentFile(&__nacl_irt_query));
}

void PostReply(void* user_data, int32_t status) {
  pp::VarArray reply = pp::VarArray();
  for (size_t i = 0; i < result.size(); ++i)
    reply.Set(i, pp::Var(result[i]));
  g_instance->PostMessage(reply);
}

void* RunTestsOnBackgroundThread(void *thread_id) {
  RunTests();
  pp::Module::Get()->core()->CallOnMainThread(
      0, pp::CompletionCallback(&PostReply, NULL));
  return NULL;
}

class TestInstance : public pp::Instance {
 public:
  explicit TestInstance(PP_Instance instance) : pp::Instance(instance) {
    g_instance = this;
  }

  virtual ~TestInstance() {}
  virtual void HandleMessage(const pp::Var& var_message) {
    if (!var_message.is_string()) {
      return;
    }
    if (var_message.AsString() != "hello") {
      return;
    }

    // We test the manifest routines again after PPAPI has initialized to
    // ensure that they still work.
    //
    // irt_open_resource() isn't allowed to be called on the main thread once
    // pepper starts, so these tests must happen on a background thread.
    pthread_create(&thread_, NULL, &RunTestsOnBackgroundThread, NULL);
  }
 private:
  pthread_t thread_;
};

class TestModule : public pp::Module {
 public:
  TestModule() : pp::Module() {}
  virtual ~TestModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new TestInstance(instance);
  }
};

namespace pp {
Module* CreateModule() {
  return new TestModule();
}
}

int main() {
  RunTests();
  return PpapiPluginMain();
}
<commit_msg>Fix build failure on linux_arm_cross_compile.<commit_after>/*
 * Copyright 2014 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.
 */

//
// Test for resource open before PPAPI initialization.
//

#include <pthread.h>
#include <stdio.h>
#include <string.h>

#include <sstream>
#include <string>
#include <vector>

#include "native_client/src/untrusted/irt/irt.h"
#include "native_client/src/untrusted/nacl/nacl_irt.h"

#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"

std::vector<std::string> result;

pp::Instance* g_instance = NULL;

std::string LoadManifestSuccess(TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }
  int desc;
  int error;
  error = nacl_irt_resource_open.open_resource("test_file", &desc);
  if (0 != error) {
    printf("Can't open file, error=%d", error);
    return "Can't open file";
  }

  std::string str;

  char buffer[4096];
  int len;
  while ((len = read(desc, buffer, sizeof buffer - 1)) > 0) {
    // Null terminate.
    buffer[len] = '\0';
    str += buffer;
  }

  if (str != "Test File Content") {
    printf("Wrong file content: \"%s\"\n", str.c_str());
    return "Wrong file content: " + str;
  }

  return "Pass";
}

std::string LoadManifestNonExistentEntry(
    TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }

  int desc;
  int error = nacl_irt_resource_open.open_resource("non_existent_entry", &desc);

  // We expect ENOENT here, as it does not exist.
  if (error != ENOENT) {
    printf("Unexpected error code: %d\n", error);
    char buf[80];
    snprintf(buf, sizeof(buf), "open_resource() result: %d", error);
    return std::string(buf);
  }

  return "Pass";
}

std::string LoadManifestNonExistentFile(
    TYPE_nacl_irt_query *query_func) {
  struct nacl_irt_resource_open nacl_irt_resource_open;
  if (sizeof(nacl_irt_resource_open) !=
      (*query_func)(
          NACL_IRT_RESOURCE_OPEN_v0_1,
          &nacl_irt_resource_open,
          sizeof(nacl_irt_resource_open))) {
    return "irt manifest api not found";
  }

  int desc;
  int error = nacl_irt_resource_open.open_resource("dummy_test_file", &desc);

  // We expect ENOENT here, as it does not exist.
  if (error != ENOENT) {
    printf("Unexpected error code: %d\n", error);
    char buf[80];
    snprintf(buf, sizeof(buf), "open_resource() result: %d", error);
    return std::string(buf);
  }

  return "Pass";
}

void RunTests() {
  result.push_back(LoadManifestSuccess(&__nacl_irt_query));
  result.push_back(LoadManifestNonExistentEntry(&__nacl_irt_query));
  result.push_back(LoadManifestNonExistentFile(&__nacl_irt_query));
}

void PostReply(void* user_data, int32_t status) {
  pp::VarArray reply = pp::VarArray();
  for (size_t i = 0; i < result.size(); ++i)
    reply.Set(i, pp::Var(result[i]));
  g_instance->PostMessage(reply);
}

void* RunTestsOnBackgroundThread(void *thread_id) {
  RunTests();
  pp::Module::Get()->core()->CallOnMainThread(
      0, pp::CompletionCallback(&PostReply, NULL));
  return NULL;
}

class TestInstance : public pp::Instance {
 public:
  explicit TestInstance(PP_Instance instance) : pp::Instance(instance) {
    g_instance = this;
  }

  virtual ~TestInstance() {}
  virtual void HandleMessage(const pp::Var& var_message) {
    if (!var_message.is_string()) {
      return;
    }
    if (var_message.AsString() != "hello") {
      return;
    }

    pthread_t thread;
    // We test the manifest routines again after PPAPI has initialized to
    // ensure that they still work.
    //
    // irt_open_resource() isn't allowed to be called on the main thread once
    // pepper starts, so these tests must happen on a background thread.
    //
    // TODO(teravest): Check the return value here.
    pthread_create(&thread, NULL, &RunTestsOnBackgroundThread, NULL);
  }
};

class TestModule : public pp::Module {
 public:
  TestModule() : pp::Module() {}
  virtual ~TestModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new TestInstance(instance);
  }
};

namespace pp {
Module* CreateModule() {
  return new TestModule();
}
}

int main() {
  RunTests();
  return PpapiPluginMain();
}
<|endoftext|>


<commit_before>/*
 * 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 <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <gtest/gtest.h>

#include "presto_cpp/main/common/tests/test_json.h"
#include "presto_cpp/main/types/PrestoToVeloxExpr.h"
#include "presto_cpp/presto_protocol/presto_protocol.h"

namespace fs = boost::filesystem;

using namespace facebook::presto;

namespace {
std::string getDataPath(const std::string& fileName) {
  std::string currentPath = fs::current_path().c_str();
  if (boost::algorithm::ends_with(currentPath, "fbcode")) {
    return currentPath + "/presto_cpp/presto_protocol/tests/data/" + fileName;
  }

  if (boost::algorithm::ends_with(currentPath, "fbsource")) {
    return currentPath + "/third-party/presto_cpp/presto_protocol/tests/data/" +
        fileName;
  }

  // CLion runs the tests from cmake-build-release/ or cmake-build-debug/
  // directory. Hard-coded json files are not copied there and test fails with
  // file not found. Fixing the path so that we can trigger these tests from
  // CLion.
  boost::algorithm::replace_all(currentPath, "cmake-build-release/", "");
  boost::algorithm::replace_all(currentPath, "cmake-build-debug/", "");

  return currentPath + "/data/" + fileName;
}

template <typename T>
void testJsonRoundTrip(const std::string& str) {
  json j = json::parse(str);
  T p = j;

  testJsonRoundtrip(j, p);
}

template <typename T>
void testJsonRoundTripFile(const std::string& filename) {
  testJsonRoundTrip<T>(slurp(getDataPath(filename)));
}
} // namespace

class TestPlanNodes : public ::testing::Test {};

TEST_F(TestPlanNodes, TestExchangeNode) {
  testJsonRoundTripFile<protocol::ExchangeNode>("ExchangeNode.json");
}

TEST_F(TestPlanNodes, TestFilterNode) {
  testJsonRoundTripFile<protocol::FilterNode>("FilterNode.json");
}

TEST_F(TestPlanNodes, TestOutputNode) {
  testJsonRoundTripFile<protocol::OutputNode>("OutputNode.json");
}

TEST_F(TestPlanNodes, TestValuesNode) {
  testJsonRoundTripFile<protocol::ValuesNode>("ValuesNode.json");
}
<commit_msg>Correct test data path for internal test runs<commit_after>/*
 * 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 <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <gtest/gtest.h>

#include "presto_cpp/main/common/tests/test_json.h"
#include "presto_cpp/main/types/PrestoToVeloxExpr.h"
#include "presto_cpp/presto_protocol/presto_protocol.h"

namespace fs = boost::filesystem;

using namespace facebook::presto;

namespace {
std::string getDataPath(const std::string& fileName) {
  static const std::string kFbcode = "fbcode";

  std::string currentPath = fs::current_path().c_str();
  if (boost::algorithm::ends_with(currentPath, kFbcode)) {
    return currentPath.substr(0, currentPath.length() - kFbcode.length()) + "third-party/presto_cpp/presto_protocol/tests/data/" + fileName;
  }

  if (boost::algorithm::ends_with(currentPath, "fbsource")) {
    return currentPath + "/third-party/presto_cpp/presto_protocol/tests/data/" +
        fileName;
  }

  // CLion runs the tests from cmake-build-release/ or cmake-build-debug/
  // directory. Hard-coded json files are not copied there and test fails with
  // file not found. Fixing the path so that we can trigger these tests from
  // CLion.
  boost::algorithm::replace_all(currentPath, "cmake-build-release/", "");
  boost::algorithm::replace_all(currentPath, "cmake-build-debug/", "");

  return currentPath + "/data/" + fileName;
}

template <typename T>
void testJsonRoundTrip(const std::string& str) {
  json j = json::parse(str);
  T p = j;

  testJsonRoundtrip(j, p);
}

template <typename T>
void testJsonRoundTripFile(const std::string& filename) {
  testJsonRoundTrip<T>(slurp(getDataPath(filename)));
}
} // namespace

class TestPlanNodes : public ::testing::Test {};

TEST_F(TestPlanNodes, TestExchangeNode) {
  testJsonRoundTripFile<protocol::ExchangeNode>("ExchangeNode.json");
}

TEST_F(TestPlanNodes, TestFilterNode) {
  testJsonRoundTripFile<protocol::FilterNode>("FilterNode.json");
}

TEST_F(TestPlanNodes, TestOutputNode) {
  testJsonRoundTripFile<protocol::OutputNode>("OutputNode.json");
}

TEST_F(TestPlanNodes, TestValuesNode) {
  testJsonRoundTripFile<protocol::ValuesNode>("ValuesNode.json");
}
<|endoftext|>


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

/* Author: Ioan Sucan, Sachin Chitta */

#include "ompl_interface_ros/ompl_interface_ros.h"
#include <pluginlib/class_loader.h>
#include <boost/thread/mutex.hpp>
#include <sstream>

namespace ompl_interface_ros
{
    class IKLoader
    {
    public:
        IKLoader(const std::map<std::string, std::vector<std::string> > &possible_ik_solvers) : possible_ik_solvers_(possible_ik_solvers)
        {
	    try
	    {
		kinematics_loader_.reset(new pluginlib::ClassLoader<kinematics::KinematicsBase>("kinematics_base", "kinematics::KinematicsBase"));
	    }
	    catch(pluginlib::PluginlibException& e)
	    {
		ROS_ERROR("Unable to construct IK loader. Error: %s", e.what());
	    }
	}

        boost::shared_ptr<kinematics::KinematicsBase> allocIKSolver(const planning_models::KinematicModel::JointModelGroup *jmg)
        {
            boost::shared_ptr<kinematics::KinematicsBase> result;
            ROS_DEBUG("Received request to allocate IK solver for group '%s'", jmg->getName().c_str());
            if (kinematics_loader_ && jmg)
            {
                std::map<std::string, std::vector<std::string> >::const_iterator it = possible_ik_solvers_.find(jmg->getName());
                if (it != possible_ik_solvers_.end())
                {
                    // just to be sure, do not call the same pluginlib instance allocation function in parallel
                    boost::mutex::scoped_lock slock(lock_);
                    for (std::size_t i = 0 ; !result && i < it->second.size() ; ++i)
                    {
                        try
                        {
                            result.reset(kinematics_loader_->createClassInstance(it->second[i]));
                            if (result)
                            {
				/// \todo What is the search discretization? any reasonable way to determine this?
                                if (!result->initialize(jmg->getName(), jmg->getJointModelNames().front(), jmg->getJointModelNames().back(), 0.1))
                                {
                                    ROS_ERROR("IK solver of type '%s' could not initialize for group '%s'", it->second[i].c_str(), jmg->getName().c_str());
                                    result.reset();
                                }
                                else
                                    ROS_DEBUG("Successfully allocated and initialized an IK solver of type '%s' for group '%s' at address %p",
                                              it->second[i].c_str(), jmg->getName().c_str(), result.get());
                            }
                        }
                        catch (pluginlib::PluginlibException& e)
                        {
                            ROS_ERROR("The IK plugin (%s) failed to load. Error: %s", it->first.c_str(), e.what());
                        }
                    }
                }
                else
                    ROS_DEBUG("No IK solver available for this group");
            }
            return result;
        }

    private:

        const std::map<std::string, std::vector<std::string> >                 possible_ik_solvers_;
        boost::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase> > kinematics_loader_;
        boost::mutex                                                           lock_;
    };
}

ompl_interface_ros::OMPLInterfaceROS::OMPLInterfaceROS(const std::string &robot_description) : ompl_interface::OMPLInterface(), nh_("~")
{
    planning_scene_ = new planning_scene_ros::PlanningSceneROS(robot_description);
    planning_scene_ptr_.reset(planning_scene_);
    if (planning_scene_->isConfigured())
    {
        if (configurePlanners())
        {
            configureIKSolvers();
            plan_service_ = nh_.advertiseService("plan_kinematic_path", &OMPLInterfaceROS::computePlan, this);
        }
    }
}

std::vector<std::string> ompl_interface_ros::OMPLInterfaceROS::getAdditionalConfigGroupNames(void)
{
    XmlRpc::XmlRpcValue group_list;
    std::vector<std::string> group_names;

    // read the list of group names that have additional configurations
    if (nh_.getParam("groups", group_list))
    {
        ROS_INFO("Found additional configurations for planning groups on param server");
        if (group_list.getType() == XmlRpc::XmlRpcValue::TypeArray)
        {
            for (int32_t i = 0; i < group_list.size(); ++i)
            {
                if (group_list[i].getType() == XmlRpc::XmlRpcValue::TypeString)
                {
                    std::string gnm = static_cast<std::string>(group_list[i]);
                    if (planning_scene_->getKinematicModel()->hasJointModelGroup(gnm))
                        group_names.push_back(gnm);
                    else
                        ROS_ERROR("Additional configuration specified for group '%s', but that group is not known to the kinematic model.", gnm.c_str());
                }
                else
                    ROS_ERROR("Group names should be strings");
            }
        }
        else
            ROS_ERROR("Group list should be of XmlRpc Array type");
    }
    else
        ROS_INFO("No additional configurations for planning groups found on param server");

    return group_names;
}

void ompl_interface_ros::OMPLInterfaceROS::configureIKSolvers(void)
{
    std::vector<std::string> group_names = getAdditionalConfigGroupNames();
    std::map<std::string, std::vector<std::string> > possible_ik_solvers;

    // read the list of plugin names for possible IK solvers
    for (std::size_t i = 0 ; i < group_names.size() ; ++i)
    {
        std::string ksolver;
        if (nh_.getParam(group_names[i] + "/kinematics_solver", ksolver))
        {
            std::stringstream ss(ksolver);
            while (ss.good() && !ss.eof())
            {
                std::string solver; ss >> solver >> std::ws;
                possible_ik_solvers[group_names[i]].push_back(solver);
                ROS_INFO("Using IK solver '%s' for group '%s'.", solver.c_str(), group_names[i].c_str());
            }
        }
    }

    ik_loader_.reset(new IKLoader(possible_ik_solvers));
    kinematic_constraints::IKAllocator ik_allocator = boost::bind(&IKLoader::allocIKSolver, ik_loader_.get(), _1);
    for (std::map<std::string, ompl_interface::PlanningGroupPtr>::iterator it = planning_groups_.begin() ; it != planning_groups_.end() ; ++it)
        if (possible_ik_solvers.find(it->second->getJointModelGroup()->getName()) != possible_ik_solvers.end())
        {
            ROS_DEBUG("Specifying IK solver for planning configuration '%s'", it->second->getName().c_str());
            it->second->setIKAllocator(ik_allocator);
        }
}

bool ompl_interface_ros::OMPLInterfaceROS::configurePlanners(void)
{
    std::vector<std::string> group_names = getAdditionalConfigGroupNames();

    // read the planning configuration for each group
    std::vector<ompl_interface::PlannerConfigs> pconfig;
    for (std::size_t i = 0 ; i < group_names.size() ; ++i)
    {
        // get parameters specific for the group
        std::string projection_evaluator, lvsf;
        nh_.getParam(group_names[i] + "/projection_evaluator", projection_evaluator);
        nh_.getParam(group_names[i] + "/longest_valid_segment_fraction", lvsf);

        // set the parameters (if any) for the default group configuration;
        if (!projection_evaluator.empty() || !lvsf.empty())
        {
            ompl_interface::PlannerConfigs pc;
            pc.name = group_names[i];
            pc.group = group_names[i];
            if (!projection_evaluator.empty())
                pc.config["projection_evaluator"] = projection_evaluator;
            if (!lvsf.empty())
                pc.config["longest_valid_segment_fraction"] = lvsf;
            pconfig.push_back(pc);
        }

        XmlRpc::XmlRpcValue config_names;
        if (nh_.getParam(group_names[i] + "/planner_configs", config_names))
        {
            if (config_names.getType() == XmlRpc::XmlRpcValue::TypeArray)
            {
                for (int32_t j = 0; j < config_names.size() ; ++j)
                    if (config_names[j].getType() == XmlRpc::XmlRpcValue::TypeString)
                    {
                        std::string planner_config = static_cast<std::string>(config_names[j]);
                        XmlRpc::XmlRpcValue xml_config;
                        if (nh_.getParam("planner_configs/" + planner_config, xml_config))
                        {
                            if (xml_config.getType() == XmlRpc::XmlRpcValue::TypeStruct)
                            {
                                ompl_interface::PlannerConfigs pc;
                                pc.name = group_names[i] + "[" + planner_config + "]";
                                pc.group = group_names[i];

                                // inherit parameters from the group (which can be overriden)
                                if (!projection_evaluator.empty())
                                    pc.config["projection_evaluator"] = projection_evaluator;
                                if (!lvsf.empty())
                                    pc.config["longest_valid_segment_fraction"] = lvsf;

                                // read parameters specific for this configuration
                                ROS_INFO("Configuring '%s'...", pc.name.c_str());
                                for (XmlRpc::XmlRpcValue::iterator it = xml_config.begin() ; it != xml_config.end() ; ++it)
                                    pc.config[it->first] = static_cast<std::string>(it->second);
                                pconfig.push_back(pc);
                            }
                            else
                                ROS_ERROR("A planning configuration should be of type XmlRpc Struct type (for configuration '%s')", planner_config.c_str());
                        }
                        else
                            ROS_ERROR("Could not find the planner configuration '%s' on the param server", planner_config.c_str());
                    }
                    else
                        ROS_ERROR("Planner configuration names must be of type string (for group '%s')", group_names[i].c_str());
            }
            else
                ROS_ERROR("The planner_configs argument of a group configuration should be an array of strings (for group '%s')", group_names[i].c_str());
        }
        else
            ROS_INFO("Group '%s' mentioned for additional configuration but no planner_configs specified. Using default settings.", group_names[i].c_str());
    }

    // this call will configure planning for all groups known to the kinematic model
    // and it will use additional configuration options, if available
    return configure(planning_scene_ptr_, pconfig);
}

bool ompl_interface_ros::OMPLInterfaceROS::computePlan(moveit_msgs::GetMotionPlan::Request &req, moveit_msgs::GetMotionPlan::Response &res)
{
    ROS_INFO("Received new planning request...");
    return solve(req, res);
}

void ompl_interface_ros::OMPLInterfaceROS::status(void)
{
    if (isConfigured())
    {
        std::stringstream ss;
        planning_scene_->getKinematicModel()->printModelInfo(ss);
        //        ROS_INFO("%s", ss.str().c_str());
        ROS_INFO("OMPL planning node started.");
    }
    else
    {
        ROS_ERROR("Cannot start OMPL planning node.");
    }
}
<commit_msg>fix call to IK<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2011, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan, Sachin Chitta */

#include "ompl_interface_ros/ompl_interface_ros.h"
#include <pluginlib/class_loader.h>
#include <boost/thread/mutex.hpp>
#include <sstream>

namespace ompl_interface_ros
{
    class IKLoader
    {
    public:
        IKLoader(const std::map<std::string, std::vector<std::string> > &possible_ik_solvers) : possible_ik_solvers_(possible_ik_solvers)
        {
            try
            {
                kinematics_loader_.reset(new pluginlib::ClassLoader<kinematics::KinematicsBase>("kinematics_base", "kinematics::KinematicsBase"));
            }
            catch(pluginlib::PluginlibException& e)
            {
                ROS_ERROR("Unable to construct IK loader. Error: %s", e.what());
            }
        }

        boost::shared_ptr<kinematics::KinematicsBase> allocIKSolver(const planning_models::KinematicModel::JointModelGroup *jmg)
        {
            boost::shared_ptr<kinematics::KinematicsBase> result;
            ROS_DEBUG("Received request to allocate IK solver for group '%s'", jmg->getName().c_str());
            if (kinematics_loader_ && jmg)
            {
                std::map<std::string, std::vector<std::string> >::const_iterator it = possible_ik_solvers_.find(jmg->getName());
                if (it != possible_ik_solvers_.end())
                {
                    // just to be sure, do not call the same pluginlib instance allocation function in parallel
                    boost::mutex::scoped_lock slock(lock_);
                    for (std::size_t i = 0 ; !result && i < it->second.size() ; ++i)
                    {
                        try
                        {
                            result.reset(kinematics_loader_->createClassInstance(it->second[i]));
                            if (result)
                            {
                                /// \todo What is the search discretization? any reasonable way to determine this?
                                const std::vector<const planning_models::KinematicModel::JointModel*> &jnts = jmg->getJointModels();
                                const std::string &base = jnts.front()->getParentLinkModel() ? jnts.front()->getParentLinkModel()->getName() :
                                    jmg->getParentModel()->getModelFrame();
                                const std::string &tip = jnts.back()->getChildLinkModel()->getName();
                                if (!result->initialize(jmg->getName(), base, tip, 0.1))
                                {
                                    ROS_ERROR("IK solver of type '%s' could not initialize for group '%s'", it->second[i].c_str(), jmg->getName().c_str());
                                    result.reset();
                                }
                                else
                                    ROS_DEBUG("Successfully allocated and initialized an IK solver of type '%s' for group '%s' at address %p",
                                              it->second[i].c_str(), jmg->getName().c_str(), result.get());
                            }
                        }
                        catch (pluginlib::PluginlibException& e)
                        {
                            ROS_ERROR("The IK plugin (%s) failed to load. Error: %s", it->first.c_str(), e.what());
                        }
                    }
                }
                else
                    ROS_DEBUG("No IK solver available for this group");
            }
            return result;
        }

    private:

        const std::map<std::string, std::vector<std::string> >                 possible_ik_solvers_;
        boost::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase> > kinematics_loader_;
        boost::mutex                                                           lock_;
    };
}

ompl_interface_ros::OMPLInterfaceROS::OMPLInterfaceROS(const std::string &robot_description) : ompl_interface::OMPLInterface(), nh_("~")
{
    planning_scene_ = new planning_scene_ros::PlanningSceneROS(robot_description);
    planning_scene_ptr_.reset(planning_scene_);
    if (planning_scene_->isConfigured())
    {
        if (configurePlanners())
        {
            configureIKSolvers();
            plan_service_ = nh_.advertiseService("plan_kinematic_path", &OMPLInterfaceROS::computePlan, this);
        }
    }
}

std::vector<std::string> ompl_interface_ros::OMPLInterfaceROS::getAdditionalConfigGroupNames(void)
{
    XmlRpc::XmlRpcValue group_list;
    std::vector<std::string> group_names;

    // read the list of group names that have additional configurations
    if (nh_.getParam("groups", group_list))
    {
        ROS_INFO("Found additional configurations for planning groups on param server");
        if (group_list.getType() == XmlRpc::XmlRpcValue::TypeArray)
        {
            for (int32_t i = 0; i < group_list.size(); ++i)
            {
                if (group_list[i].getType() == XmlRpc::XmlRpcValue::TypeString)
                {
                    std::string gnm = static_cast<std::string>(group_list[i]);
                    if (planning_scene_->getKinematicModel()->hasJointModelGroup(gnm))
                        group_names.push_back(gnm);
                    else
                        ROS_ERROR("Additional configuration specified for group '%s', but that group is not known to the kinematic model.", gnm.c_str());
                }
                else
                    ROS_ERROR("Group names should be strings");
            }
        }
        else
            ROS_ERROR("Group list should be of XmlRpc Array type");
    }
    else
        ROS_INFO("No additional configurations for planning groups found on param server");

    return group_names;
}

void ompl_interface_ros::OMPLInterfaceROS::configureIKSolvers(void)
{
    std::vector<std::string> group_names = getAdditionalConfigGroupNames();
    std::map<std::string, std::vector<std::string> > possible_ik_solvers;

    // read the list of plugin names for possible IK solvers
    for (std::size_t i = 0 ; i < group_names.size() ; ++i)
    {
        std::string ksolver;
        if (nh_.getParam(group_names[i] + "/kinematics_solver", ksolver))
        {
            std::stringstream ss(ksolver);
            while (ss.good() && !ss.eof())
            {
                std::string solver; ss >> solver >> std::ws;
                possible_ik_solvers[group_names[i]].push_back(solver);
                ROS_INFO("Using IK solver '%s' for group '%s'.", solver.c_str(), group_names[i].c_str());
            }
        }
    }

    ik_loader_.reset(new IKLoader(possible_ik_solvers));
    kinematic_constraints::IKAllocator ik_allocator = boost::bind(&IKLoader::allocIKSolver, ik_loader_.get(), _1);
    for (std::map<std::string, ompl_interface::PlanningGroupPtr>::iterator it = planning_groups_.begin() ; it != planning_groups_.end() ; ++it)
        if (possible_ik_solvers.find(it->second->getJointModelGroup()->getName()) != possible_ik_solvers.end())
        {
            ROS_DEBUG("Specifying IK solver for planning configuration '%s'", it->second->getName().c_str());
            it->second->setIKAllocator(ik_allocator);
        }
}

bool ompl_interface_ros::OMPLInterfaceROS::configurePlanners(void)
{
    std::vector<std::string> group_names = getAdditionalConfigGroupNames();

    // read the planning configuration for each group
    std::vector<ompl_interface::PlannerConfigs> pconfig;
    for (std::size_t i = 0 ; i < group_names.size() ; ++i)
    {
        // get parameters specific for the group
        std::string projection_evaluator, lvsf;
        nh_.getParam(group_names[i] + "/projection_evaluator", projection_evaluator);
        nh_.getParam(group_names[i] + "/longest_valid_segment_fraction", lvsf);

        // set the parameters (if any) for the default group configuration;
        if (!projection_evaluator.empty() || !lvsf.empty())
        {
            ompl_interface::PlannerConfigs pc;
            pc.name = group_names[i];
            pc.group = group_names[i];
            if (!projection_evaluator.empty())
                pc.config["projection_evaluator"] = projection_evaluator;
            if (!lvsf.empty())
                pc.config["longest_valid_segment_fraction"] = lvsf;
            pconfig.push_back(pc);
        }

        XmlRpc::XmlRpcValue config_names;
        if (nh_.getParam(group_names[i] + "/planner_configs", config_names))
        {
            if (config_names.getType() == XmlRpc::XmlRpcValue::TypeArray)
            {
                for (int32_t j = 0; j < config_names.size() ; ++j)
                    if (config_names[j].getType() == XmlRpc::XmlRpcValue::TypeString)
                    {
                        std::string planner_config = static_cast<std::string>(config_names[j]);
                        XmlRpc::XmlRpcValue xml_config;
                        if (nh_.getParam("planner_configs/" + planner_config, xml_config))
                        {
                            if (xml_config.getType() == XmlRpc::XmlRpcValue::TypeStruct)
                            {
                                ompl_interface::PlannerConfigs pc;
                                pc.name = group_names[i] + "[" + planner_config + "]";
                                pc.group = group_names[i];

                                // inherit parameters from the group (which can be overriden)
                                if (!projection_evaluator.empty())
                                    pc.config["projection_evaluator"] = projection_evaluator;
                                if (!lvsf.empty())
                                    pc.config["longest_valid_segment_fraction"] = lvsf;

                                // read parameters specific for this configuration
                                ROS_INFO("Configuring '%s'...", pc.name.c_str());
                                for (XmlRpc::XmlRpcValue::iterator it = xml_config.begin() ; it != xml_config.end() ; ++it)
                                    pc.config[it->first] = static_cast<std::string>(it->second);
                                pconfig.push_back(pc);
                            }
                            else
                                ROS_ERROR("A planning configuration should be of type XmlRpc Struct type (for configuration '%s')", planner_config.c_str());
                        }
                        else
                            ROS_ERROR("Could not find the planner configuration '%s' on the param server", planner_config.c_str());
                    }
                    else
                        ROS_ERROR("Planner configuration names must be of type string (for group '%s')", group_names[i].c_str());
            }
            else
                ROS_ERROR("The planner_configs argument of a group configuration should be an array of strings (for group '%s')", group_names[i].c_str());
        }
        else
            ROS_INFO("Group '%s' mentioned for additional configuration but no planner_configs specified. Using default settings.", group_names[i].c_str());
    }

    // this call will configure planning for all groups known to the kinematic model
    // and it will use additional configuration options, if available
    return configure(planning_scene_ptr_, pconfig);
}

bool ompl_interface_ros::OMPLInterfaceROS::computePlan(moveit_msgs::GetMotionPlan::Request &req, moveit_msgs::GetMotionPlan::Response &res)
{
    ROS_INFO("Received new planning request...");
    return solve(req, res);
}

void ompl_interface_ros::OMPLInterfaceROS::status(void)
{
    if (isConfigured())
    {
        std::stringstream ss;
        planning_scene_->getKinematicModel()->printModelInfo(ss);
        //        ROS_INFO("%s", ss.str().c_str());
        ROS_INFO("OMPL planning node started.");
    }
    else
    {
        ROS_ERROR("Cannot start OMPL planning node.");
    }
}
<|endoftext|>


<commit_before><commit_msg>Planning: modified a few lane-change params.<commit_after><|endoftext|>