<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* writerperfect
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * 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/.
 *
 * Major Contributor(s):
 * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com)
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

#include <string.h>

#include "StringDocumentHandler.hxx"

StringDocumentHandler::StringDocumentHandler() : m_data(""), m_isTagOpened(false), m_openedTagName("")
{
	m_data.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
}

void StringDocumentHandler::endDocument()
{
	if (!m_isTagOpened) return;
	m_data.append(">");
	m_isTagOpened = false;
}

void StringDocumentHandler::startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList)
{
	if (m_isTagOpened)
	{
		m_data.append(">");
		m_isTagOpened = false;
	}
	m_data.append("<");
	m_data.append(psName);
	librevenge::RVNGPropertyList::Iter i(xPropList);
	for (i.rewind(); i.next();)
	{
		// filter out librevenge elements
		if (!strncmp(i.key(), "librevenge:", 11)) continue;

		m_data.append(" ");
		m_data.append(i.key());
		m_data.append("=\"");
		if (i()->getStr().len()>0)
			m_data.append(i()->getStr().cstr());
		m_data.append("\"");
	}
	m_isTagOpened = true;
	m_openedTagName.sprintf("%s", psName);
}
void StringDocumentHandler::endElement(const char *psName)
{
	if (m_isTagOpened)
	{
		if (m_openedTagName == psName)
		{
			m_data.append("/>");
			m_isTagOpened = false;
		}
		else // should not happen, but handle it
		{
			m_data.append(">");
			m_data.append("</");
			m_data.append(psName);
			m_data.append(">");
			m_isTagOpened = false;
		}
	}
	else
	{
		m_data.append("</");
		m_data.append(psName);
		m_data.append(">");
		m_isTagOpened = false;
	}
}

void StringDocumentHandler::characters(const librevenge::RVNGString &sCharacters)
{
	if (m_isTagOpened)
	{
		m_data.append(">");
		m_isTagOpened = false;
	}
	librevenge::RVNGString sEscapedCharacters(sCharacters, true);
	if (sEscapedCharacters.len() > 0)
		m_data.append(sEscapedCharacters.cstr());
}

/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
<commit_msg>One more change in RVNGString<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* writerperfect
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * 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/.
 *
 * Major Contributor(s):
 * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com)
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

#include <string.h>

#include "StringDocumentHandler.hxx"

StringDocumentHandler::StringDocumentHandler() : m_data(""), m_isTagOpened(false), m_openedTagName("")
{
	m_data.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
}

void StringDocumentHandler::endDocument()
{
	if (!m_isTagOpened) return;
	m_data.append(">");
	m_isTagOpened = false;
}

void StringDocumentHandler::startElement(const char *psName, const librevenge::RVNGPropertyList &xPropList)
{
	if (m_isTagOpened)
	{
		m_data.append(">");
		m_isTagOpened = false;
	}
	m_data.append("<");
	m_data.append(psName);
	librevenge::RVNGPropertyList::Iter i(xPropList);
	for (i.rewind(); i.next();)
	{
		// filter out librevenge elements
		if (!strncmp(i.key(), "librevenge:", 11)) continue;

		m_data.append(" ");
		m_data.append(i.key());
		m_data.append("=\"");
		if (i()->getStr().len()>0)
			m_data.append(i()->getStr().cstr());
		m_data.append("\"");
	}
	m_isTagOpened = true;
	m_openedTagName.sprintf("%s", psName);
}
void StringDocumentHandler::endElement(const char *psName)
{
	if (m_isTagOpened)
	{
		if (m_openedTagName == psName)
		{
			m_data.append("/>");
			m_isTagOpened = false;
		}
		else // should not happen, but handle it
		{
			m_data.append(">");
			m_data.append("</");
			m_data.append(psName);
			m_data.append(">");
			m_isTagOpened = false;
		}
	}
	else
	{
		m_data.append("</");
		m_data.append(psName);
		m_data.append(">");
		m_isTagOpened = false;
	}
}

void StringDocumentHandler::characters(const librevenge::RVNGString &sCharacters)
{
	if (m_isTagOpened)
	{
		m_data.append(">");
		m_isTagOpened = false;
	}
	librevenge::RVNGString sEscapedCharacters;
	sEscapedCharacters.appendEscapedXML(sCharacters)
	if (sEscapedCharacters.len() > 0)
		m_data.append(sEscapedCharacters.cstr());
}

/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
<|endoftext|>


<commit_before>/**
 * @file edge.cpp
 * @brief Simple test for OpenCV
 * @author Denis Deryugin <deryugin.denis@gmail.com>
 * @version
 * @date 03.06.2019
 */

#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>

#include <drivers/video/fb.h>

using namespace cv;
using namespace std;

static void help(void) {
	printf("\nThis sample demonstrates Canny edge detection\n"
			"Call:\n"
			"	./edge [image [threshold]] \n\n");
}

static const char* keys = {
	"{help h||}"
	"{@image        | \"fruits.png\" | source image   }"
	"{@repeat |1     | number}"
};

int main(int argc, const char** argv) {
	int edgeThresh = 2;
	Mat image, gray, edge, cedge;

	struct fb_info *fbi = fb_lookup(0);

	CommandLineParser parser(argc, argv, keys);
	if (parser.has("help"))  {
		help();
		return 0;
	}

	edgeThresh = parser.get<int>(1);
	string filename = parser.get<String>("@image");
	image = imread(filename, 1);
	if(image.empty()) {
		printf("Cannot read image file: %s\n", filename.c_str());
		help();
		return -1;
	}

	cedge.create(image.size(), image.type());
	cvtColor(image, gray, COLOR_BGR2GRAY);

	blur(gray, edge, Size(3,3));
	Canny(edge, edge, edgeThresh, edgeThresh*3, 3);
	cedge = Scalar::all(0);

	image.copyTo(cedge, edge);

	printf("Framebuffer: %dx%d %dbpp\n", fbi->var.xres, fbi->var.yres, fbi->var.bits_per_pixel);
	printf("Image: %dx%d; Threshold=%d\n", cedge.cols, cedge.rows, edgeThresh);

	for (int y = 0; y < cedge.rows; y++) {
		const uchar *row = &cedge.at<uchar>(y, 0);
		for (int x = 0; x < 3 * cedge.cols; x += 3) {
			unsigned rgb888	=
				0xFF000000 |
				unsigned(row[x]) |
				(unsigned(row[x + 1]) << 8) |
				(unsigned(row[x + 2]) << 16);

			((uint32_t *) fbi->screen_base)[fbi->var.xres * y + x / 3] = rgb888;
		}
	}

	return 0;
}
<commit_msg>opencv: Extract fb drawing to a function in edges.cpp<commit_after>/**
 * @file edge.cpp
 * @brief Simple test for OpenCV
 * @author Denis Deryugin <deryugin.denis@gmail.com>
 * @version
 * @date 03.06.2019
 */

#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>

#include <drivers/video/fb.h>

using namespace cv;
using namespace std;

static void help(void) {
	printf("\nThis sample demonstrates Canny edge detection\n"
			"Call:\n"
			"	./edge [image [threshold]] \n\n");
}

static const char* keys = {
	"{help h||}"
	"{@image        | \"fruits.png\" | source image   }"
	"{@repeat |1     | number}"
};

static void imdrawfb(Mat& img) {
	struct fb_info *fbi;
	int w, h;

	fbi = fb_lookup(0);
	if (!fbi) {
		printf("fb0 not found\n");
		return;
	}

	printf("Framebuffer: %dx%d %dbpp\n", fbi->var.xres, fbi->var.yres, fbi->var.bits_per_pixel);

	h = min((int) fbi->var.yres, img.rows);
	w = min((int) (fbi->var.bits_per_pixel * fbi->var.xres) / 8, 3 * img.cols);

	for (int y = 0; y < h; y++) {
		const uchar *row = &img.at<uchar>(y, 0);
		for (int x = 0; x < w; x += 3) {
			unsigned rgb888	=
				0xFF000000 |
				unsigned(row[x]) |
				(unsigned(row[x + 1]) << 8) |
				(unsigned(row[x + 2]) << 16);

			((uint32_t *) fbi->screen_base)[fbi->var.xres * y + x / 3] = rgb888;
		}
	}
}

int main(int argc, const char** argv) {
	int edgeThresh = 2;
	Mat image, gray, edge, cedge;

	CommandLineParser parser(argc, argv, keys);
	if (parser.has("help"))  {
		help();
		return 0;
	}

	edgeThresh = parser.get<int>(1);
	string filename = parser.get<String>("@image");
	image = imread(filename, 1);
	if(image.empty()) {
		printf("Cannot read image file: %s\n", filename.c_str());
		help();
		return -1;
	}

	cedge.create(image.size(), image.type());
	cvtColor(image, gray, COLOR_BGR2GRAY);

	blur(gray, edge, Size(3,3));
	Canny(edge, edge, edgeThresh, edgeThresh*3, 3);
	cedge = Scalar::all(0);

	image.copyTo(cedge, edge);

	printf("Image: %dx%d; Threshold=%d\n", cedge.cols, cedge.rows, edgeThresh);

	imdrawfb(cedge);

	return 0;
}
<|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 "chrome/browser/net/url_fetcher.h"

#include "base/compiler_specific.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/net/url_request_context_getter.h"
#include "googleurl/src/gurl.h"
#include "net/base/load_flags.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

static const int kBufferSize = 4096;

bool URLFetcher::g_interception_enabled = false;

class URLFetcher::Core
    : public base::RefCountedThreadSafe<URLFetcher::Core>,
      public URLRequest::Delegate {
 public:
  // For POST requests, set |content_type| to the MIME type of the content
  // and set |content| to the data to upload.  |flags| are flags to apply to
  // the load operation--these should be one or more of the LOAD_* flags
  // defined in url_request.h.
  Core(URLFetcher* fetcher,
       const GURL& original_url,
       RequestType request_type,
       URLFetcher::Delegate* d);

  // Starts the load.  It's important that this not happen in the constructor
  // because it causes the IO thread to begin AddRef()ing and Release()ing
  // us.  If our caller hasn't had time to fully construct us and take a
  // reference, the IO thread could interrupt things, run a task, Release()
  // us, and destroy us, leaving the caller with an already-destroyed object
  // when construction finishes.
  void Start();

  // Stops any in-progress load and ensures no callback will happen.  It is
  // safe to call this multiple times.
  void Stop();

  // URLRequest::Delegate implementations
  virtual void OnResponseStarted(URLRequest* request);
  virtual void OnReadCompleted(URLRequest* request, int bytes_read);

  URLFetcher::Delegate* delegate() const { return delegate_; }

 private:
  friend class base::RefCountedThreadSafe<URLFetcher::Core>;

  ~Core() {}

  // Wrapper functions that allow us to ensure actions happen on the right
  // thread.
  void StartURLRequest();
  void CancelURLRequest();
  void OnCompletedURLRequest(const URLRequestStatus& status);

  URLFetcher* fetcher_;              // Corresponding fetcher object
  GURL original_url_;                // The URL we were asked to fetch
  GURL url_;                         // The URL we eventually wound up at
  RequestType request_type_;         // What type of request is this?
  URLFetcher::Delegate* delegate_;   // Object to notify on completion
  MessageLoop* delegate_loop_;       // Message loop of the creating thread
  URLRequest* request_;              // The actual request this wraps
  int load_flags_;                   // Flags for the load operation
  int response_code_;                // HTTP status code for the request
  std::string data_;                 // Results of the request
  scoped_refptr<net::IOBuffer> buffer_;
                                     // Read buffer
  scoped_refptr<URLRequestContextGetter> request_context_getter_;
                                     // Cookie/cache info for the request
  ResponseCookies cookies_;          // Response cookies
  std::string extra_request_headers_;// Extra headers for the request, if any
  scoped_refptr<net::HttpResponseHeaders> response_headers_;

  std::string upload_content_;       // HTTP POST payload
  std::string upload_content_type_;  // MIME type of POST payload

  // The overload protection entry for this URL.  This is used to
  // incrementally back off how rapidly we'll send requests to a particular
  // URL, to avoid placing too much demand on the remote resource.  We update
  // this with the status of all requests as they return, and in turn use it
  // to determine how long to wait before making another request.
  URLFetcherProtectEntry* protect_entry_;
  // |num_retries_| indicates how many times we've failed to successfully
  // fetch this URL.  Once this value exceeds the maximum number of retries
  // specified by the protection manager, we'll give up.
  int num_retries_;

  friend class URLFetcher;
  DISALLOW_COPY_AND_ASSIGN(Core);
};

// static
URLFetcher::Factory* URLFetcher::factory_ = NULL;

URLFetcher::URLFetcher(const GURL& url,
                       RequestType request_type,
                       Delegate* d)
    : ALLOW_THIS_IN_INITIALIZER_LIST(
      core_(new Core(this, url, request_type, d))) {
}

URLFetcher::~URLFetcher() {
  core_->Stop();
}

// static
URLFetcher* URLFetcher::Create(int id, const GURL& url,
                               RequestType request_type, Delegate* d) {
  return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) :
                    new URLFetcher(url, request_type, d);
}

URLFetcher::Core::Core(URLFetcher* fetcher,
                       const GURL& original_url,
                       RequestType request_type,
                       URLFetcher::Delegate* d)
    : fetcher_(fetcher),
      original_url_(original_url),
      request_type_(request_type),
      delegate_(d),
      delegate_loop_(MessageLoop::current()),
      request_(NULL),
      load_flags_(net::LOAD_NORMAL),
      response_code_(-1),
      buffer_(new net::IOBuffer(kBufferSize)),
      protect_entry_(URLFetcherProtectManager::GetInstance()->Register(
          original_url_.host())),
      num_retries_(0) {
}

void URLFetcher::Core::Start() {
  DCHECK(delegate_loop_);
  DCHECK(request_context_getter_) << "We need an URLRequestContext!";
  ChromeThread::PostDelayedTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &Core::StartURLRequest),
          protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND));
}

void URLFetcher::Core::Stop() {
  DCHECK_EQ(MessageLoop::current(), delegate_loop_);
  delegate_ = NULL;
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &Core::CancelURLRequest));
}

void URLFetcher::Core::OnResponseStarted(URLRequest* request) {
  DCHECK(request == request_);
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (request_->status().is_success()) {
    response_code_ = request_->GetResponseCode();
    response_headers_ = request_->response_headers();
  }

  int bytes_read = 0;
  // Some servers may treat HEAD requests as GET requests.  To free up the
  // network connection as soon as possible, signal that the request has
  // completed immediately, without trying to read any data back (all we care
  // about is the response code and headers, which we already have).
  if (request_->status().is_success() && (request_type_ != HEAD))
    request_->Read(buffer_, kBufferSize, &bytes_read);
  OnReadCompleted(request_, bytes_read);
}

void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) {
  DCHECK(request == request_);
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  url_ = request->url();

  do {
    if (!request_->status().is_success() || bytes_read <= 0)
      break;
    data_.append(buffer_->data(), bytes_read);
  } while (request_->Read(buffer_, kBufferSize, &bytes_read));

  if (request_->status().is_success())
    request_->GetResponseCookies(&cookies_);

  // See comments re: HEAD requests in OnResponseStarted().
  if (!request_->status().is_io_pending() || (request_type_ == HEAD)) {
    delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &Core::OnCompletedURLRequest, request_->status()));
    delete request_;
    request_ = NULL;
  }
}

void URLFetcher::Core::StartURLRequest() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  DCHECK(!request_);

  request_ = new URLRequest(original_url_, this);
  int flags = request_->load_flags() | load_flags_;
  if (!g_interception_enabled) {
    flags = flags | net::LOAD_DISABLE_INTERCEPT;
  }
  request_->set_load_flags(flags);
  request_->set_context(request_context_getter_->GetURLRequestContext());

  switch (request_type_) {
    case GET:
      break;

    case POST:
      DCHECK(!upload_content_.empty());
      DCHECK(!upload_content_type_.empty());

      request_->set_method("POST");
      if (!extra_request_headers_.empty())
        extra_request_headers_ += "\r\n";
      StringAppendF(&extra_request_headers_,
                    "Content-Type: %s", upload_content_type_.c_str());
      request_->AppendBytesToUpload(upload_content_.data(),
                                    static_cast<int>(upload_content_.size()));
      break;

    case HEAD:
      request_->set_method("HEAD");
      break;

    default:
      NOTREACHED();
  }

  if (!extra_request_headers_.empty())
    request_->SetExtraRequestHeaders(extra_request_headers_);

  request_->Start();
}

void URLFetcher::Core::CancelURLRequest() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (request_) {
    request_->Cancel();
    delete request_;
    request_ = NULL;
  }
  // Release the reference to the request context. There could be multiple
  // references to URLFetcher::Core at this point so it may take a while to
  // delete the object, but we cannot delay the destruction of the request
  // context.
  request_context_getter_ = NULL;
}

void URLFetcher::Core::OnCompletedURLRequest(const URLRequestStatus& status) {
  DCHECK(MessageLoop::current() == delegate_loop_);

  // Checks the response from server.
  if (response_code_ >= 500) {
    // When encountering a server error, we will send the request again
    // after backoff time.
    const int64 wait =
        protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE);
    ++num_retries_;
    // Restarts the request if we still need to notify the delegate.
    if (delegate_) {
      if (num_retries_ <= protect_entry_->max_retries()) {
        ChromeThread::PostDelayedTask(
            ChromeThread::IO, FROM_HERE,
            NewRunnableMethod(this, &Core::StartURLRequest), wait);
      } else {
        delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
                                      cookies_, data_);
      }
    }
  } else {
    protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS);
    if (delegate_)
      delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
                                    cookies_, data_);
  }
}

void URLFetcher::set_upload_data(const std::string& upload_content_type,
                     const std::string& upload_content) {
  core_->upload_content_type_ = upload_content_type;
  core_->upload_content_ = upload_content;
}

void URLFetcher::set_load_flags(int load_flags) {
  core_->load_flags_ = load_flags;
}

int URLFetcher::load_flags() const {
  return core_->load_flags_;
}

void URLFetcher::set_extra_request_headers(
    const std::string& extra_request_headers) {
  core_->extra_request_headers_ = extra_request_headers;
}

void URLFetcher::set_request_context(
    URLRequestContextGetter* request_context_getter) {
  core_->request_context_getter_ = request_context_getter;
}

net::HttpResponseHeaders* URLFetcher::response_headers() const {
  return core_->response_headers_;
}

void URLFetcher::Start() {
  core_->Start();
}

const GURL& URLFetcher::url() const {
  return core_->url_;
}

URLFetcher::Delegate* URLFetcher::delegate() const {
  return core_->delegate();
}
<commit_msg>Add instrumentation to track down a crash.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/url_fetcher.h"

#include "base/compiler_specific.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/net/url_request_context_getter.h"
#include "googleurl/src/gurl.h"
#include "net/base/load_flags.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

static const int kBufferSize = 4096;

bool URLFetcher::g_interception_enabled = false;

class URLFetcher::Core
    : public base::RefCountedThreadSafe<URLFetcher::Core>,
      public URLRequest::Delegate {
 public:
  // For POST requests, set |content_type| to the MIME type of the content
  // and set |content| to the data to upload.  |flags| are flags to apply to
  // the load operation--these should be one or more of the LOAD_* flags
  // defined in url_request.h.
  Core(URLFetcher* fetcher,
       const GURL& original_url,
       RequestType request_type,
       URLFetcher::Delegate* d);

  // Starts the load.  It's important that this not happen in the constructor
  // because it causes the IO thread to begin AddRef()ing and Release()ing
  // us.  If our caller hasn't had time to fully construct us and take a
  // reference, the IO thread could interrupt things, run a task, Release()
  // us, and destroy us, leaving the caller with an already-destroyed object
  // when construction finishes.
  void Start();

  // Stops any in-progress load and ensures no callback will happen.  It is
  // safe to call this multiple times.
  void Stop();

  // URLRequest::Delegate implementations
  virtual void OnResponseStarted(URLRequest* request);
  virtual void OnReadCompleted(URLRequest* request, int bytes_read);

  URLFetcher::Delegate* delegate() const { return delegate_; }

 private:
  friend class base::RefCountedThreadSafe<URLFetcher::Core>;

  ~Core() {}

  // Wrapper functions that allow us to ensure actions happen on the right
  // thread.
  void StartURLRequest();
  void CancelURLRequest();
  void OnCompletedURLRequest(const URLRequestStatus& status);

  URLFetcher* fetcher_;              // Corresponding fetcher object
  GURL original_url_;                // The URL we were asked to fetch
  GURL url_;                         // The URL we eventually wound up at
  RequestType request_type_;         // What type of request is this?
  URLFetcher::Delegate* delegate_;   // Object to notify on completion
  MessageLoop* delegate_loop_;       // Message loop of the creating thread
  URLRequest* request_;              // The actual request this wraps
  int load_flags_;                   // Flags for the load operation
  int response_code_;                // HTTP status code for the request
  std::string data_;                 // Results of the request
  scoped_refptr<net::IOBuffer> buffer_;
                                     // Read buffer
  scoped_refptr<URLRequestContextGetter> request_context_getter_;
                                     // Cookie/cache info for the request
  ResponseCookies cookies_;          // Response cookies
  std::string extra_request_headers_;// Extra headers for the request, if any
  scoped_refptr<net::HttpResponseHeaders> response_headers_;

  std::string upload_content_;       // HTTP POST payload
  std::string upload_content_type_;  // MIME type of POST payload

  // The overload protection entry for this URL.  This is used to
  // incrementally back off how rapidly we'll send requests to a particular
  // URL, to avoid placing too much demand on the remote resource.  We update
  // this with the status of all requests as they return, and in turn use it
  // to determine how long to wait before making another request.
  URLFetcherProtectEntry* protect_entry_;
  // |num_retries_| indicates how many times we've failed to successfully
  // fetch this URL.  Once this value exceeds the maximum number of retries
  // specified by the protection manager, we'll give up.
  int num_retries_;

  // Temporary member variable to test whether requests are being started
  // after they have already been cancelled.
  // TODO(eroman): Remove this after done investigating 27074.
  bool was_cancelled_;

  friend class URLFetcher;
  DISALLOW_COPY_AND_ASSIGN(Core);
};

// static
URLFetcher::Factory* URLFetcher::factory_ = NULL;

URLFetcher::URLFetcher(const GURL& url,
                       RequestType request_type,
                       Delegate* d)
    : ALLOW_THIS_IN_INITIALIZER_LIST(
      core_(new Core(this, url, request_type, d))) {
}

URLFetcher::~URLFetcher() {
  core_->Stop();
}

// static
URLFetcher* URLFetcher::Create(int id, const GURL& url,
                               RequestType request_type, Delegate* d) {
  return factory_ ? factory_->CreateURLFetcher(id, url, request_type, d) :
                    new URLFetcher(url, request_type, d);
}

URLFetcher::Core::Core(URLFetcher* fetcher,
                       const GURL& original_url,
                       RequestType request_type,
                       URLFetcher::Delegate* d)
    : fetcher_(fetcher),
      original_url_(original_url),
      request_type_(request_type),
      delegate_(d),
      delegate_loop_(MessageLoop::current()),
      request_(NULL),
      load_flags_(net::LOAD_NORMAL),
      response_code_(-1),
      buffer_(new net::IOBuffer(kBufferSize)),
      protect_entry_(URLFetcherProtectManager::GetInstance()->Register(
          original_url_.host())),
      num_retries_(0),
      was_cancelled_(false) {
}

void URLFetcher::Core::Start() {
  DCHECK(delegate_loop_);
  CHECK(request_context_getter_) << "We need an URLRequestContext!";
  ChromeThread::PostDelayedTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &Core::StartURLRequest),
          protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SEND));
}

void URLFetcher::Core::Stop() {
  DCHECK_EQ(MessageLoop::current(), delegate_loop_);
  delegate_ = NULL;
  ChromeThread::PostTask(
      ChromeThread::IO, FROM_HERE,
      NewRunnableMethod(this, &Core::CancelURLRequest));
}

void URLFetcher::Core::OnResponseStarted(URLRequest* request) {
  DCHECK(request == request_);
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (request_->status().is_success()) {
    response_code_ = request_->GetResponseCode();
    response_headers_ = request_->response_headers();
  }

  int bytes_read = 0;
  // Some servers may treat HEAD requests as GET requests.  To free up the
  // network connection as soon as possible, signal that the request has
  // completed immediately, without trying to read any data back (all we care
  // about is the response code and headers, which we already have).
  if (request_->status().is_success() && (request_type_ != HEAD))
    request_->Read(buffer_, kBufferSize, &bytes_read);
  OnReadCompleted(request_, bytes_read);
}

void URLFetcher::Core::OnReadCompleted(URLRequest* request, int bytes_read) {
  DCHECK(request == request_);
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  url_ = request->url();

  do {
    if (!request_->status().is_success() || bytes_read <= 0)
      break;
    data_.append(buffer_->data(), bytes_read);
  } while (request_->Read(buffer_, kBufferSize, &bytes_read));

  if (request_->status().is_success())
    request_->GetResponseCookies(&cookies_);

  // See comments re: HEAD requests in OnResponseStarted().
  if (!request_->status().is_io_pending() || (request_type_ == HEAD)) {
    delegate_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &Core::OnCompletedURLRequest, request_->status()));
    delete request_;
    request_ = NULL;
  }
}

void URLFetcher::Core::StartURLRequest() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  CHECK(!was_cancelled_);
  CHECK(request_context_getter_);
  CHECK(!request_);

  request_ = new URLRequest(original_url_, this);
  int flags = request_->load_flags() | load_flags_;
  if (!g_interception_enabled) {
    flags = flags | net::LOAD_DISABLE_INTERCEPT;
  }
  request_->set_load_flags(flags);
  request_->set_context(request_context_getter_->GetURLRequestContext());

  switch (request_type_) {
    case GET:
      break;

    case POST:
      DCHECK(!upload_content_.empty());
      DCHECK(!upload_content_type_.empty());

      request_->set_method("POST");
      if (!extra_request_headers_.empty())
        extra_request_headers_ += "\r\n";
      StringAppendF(&extra_request_headers_,
                    "Content-Type: %s", upload_content_type_.c_str());
      request_->AppendBytesToUpload(upload_content_.data(),
                                    static_cast<int>(upload_content_.size()));
      break;

    case HEAD:
      request_->set_method("HEAD");
      break;

    default:
      NOTREACHED();
  }

  if (!extra_request_headers_.empty())
    request_->SetExtraRequestHeaders(extra_request_headers_);

  request_->Start();
}

void URLFetcher::Core::CancelURLRequest() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (request_) {
    request_->Cancel();
    delete request_;
    request_ = NULL;
  }
  // Release the reference to the request context. There could be multiple
  // references to URLFetcher::Core at this point so it may take a while to
  // delete the object, but we cannot delay the destruction of the request
  // context.
  request_context_getter_ = NULL;
  was_cancelled_ = true;
}

void URLFetcher::Core::OnCompletedURLRequest(const URLRequestStatus& status) {
  DCHECK(MessageLoop::current() == delegate_loop_);

  // Checks the response from server.
  if (response_code_ >= 500) {
    // When encountering a server error, we will send the request again
    // after backoff time.
    const int64 wait =
        protect_entry_->UpdateBackoff(URLFetcherProtectEntry::FAILURE);
    ++num_retries_;
    // Restarts the request if we still need to notify the delegate.
    if (delegate_) {
      if (num_retries_ <= protect_entry_->max_retries()) {
        ChromeThread::PostDelayedTask(
            ChromeThread::IO, FROM_HERE,
            NewRunnableMethod(this, &Core::StartURLRequest), wait);
      } else {
        delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
                                      cookies_, data_);
      }
    }
  } else {
    protect_entry_->UpdateBackoff(URLFetcherProtectEntry::SUCCESS);
    if (delegate_)
      delegate_->OnURLFetchComplete(fetcher_, url_, status, response_code_,
                                    cookies_, data_);
  }
}

void URLFetcher::set_upload_data(const std::string& upload_content_type,
                     const std::string& upload_content) {
  core_->upload_content_type_ = upload_content_type;
  core_->upload_content_ = upload_content;
}

void URLFetcher::set_load_flags(int load_flags) {
  core_->load_flags_ = load_flags;
}

int URLFetcher::load_flags() const {
  return core_->load_flags_;
}

void URLFetcher::set_extra_request_headers(
    const std::string& extra_request_headers) {
  core_->extra_request_headers_ = extra_request_headers;
}

void URLFetcher::set_request_context(
    URLRequestContextGetter* request_context_getter) {
  core_->request_context_getter_ = request_context_getter;
}

net::HttpResponseHeaders* URLFetcher::response_headers() const {
  return core_->response_headers_;
}

void URLFetcher::Start() {
  core_->Start();
}

const GURL& URLFetcher::url() const {
  return core_->url_;
}

URLFetcher::Delegate* URLFetcher::delegate() const {
  return core_->delegate();
}
<|endoftext|>


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

#include "chrome/browser/page_menu_model.h"

#include "app/l10n_util.h"
#include "base/compiler_specific.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/encoding_menu_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"

PageMenuModel::PageMenuModel(menus::SimpleMenuModel::Delegate* delegate,
                             Browser* browser)
    : menus::SimpleMenuModel(delegate), browser_(browser) {
  Build();
}

void PageMenuModel::Build() {
#if !defined(OS_CHROMEOS)
#if defined(OS_MACOSX)
  AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_APPLICATION_MAC);
#else
  AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS);
#endif
  AddSeparator();
#endif
  AddItemWithStringId(IDC_CUT, IDS_CUT);
  AddItemWithStringId(IDC_COPY, IDS_COPY);
  AddItemWithStringId(IDC_PASTE, IDS_PASTE);
  AddSeparator();
  AddItemWithStringId(IDC_FIND, IDS_FIND);
  AddItemWithStringId(IDC_SAVE_PAGE, IDS_SAVE_PAGE);
  AddItemWithStringId(IDC_PRINT, IDS_PRINT);
  AddSeparator();

  zoom_menu_model_.reset(new ZoomMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, zoom_menu_model_.get());

  encoding_menu_model_.reset(new EncodingMenuModel(browser_));
  AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
                         encoding_menu_model_.get());

  AddSeparator();
  devtools_menu_model_.reset(new DevToolsMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_DEVELOPER_MENU, IDS_DEVELOPER_MENU,
                         devtools_menu_model_.get());

  AddSeparator();
  AddItemWithStringId(IDC_REPORT_BUG, IDS_REPORT_BUG);
}

////////////////////////////////////////////////////////////////////////////////
// EncodingMenuModel

EncodingMenuModel::EncodingMenuModel(Browser* browser)
    : ALLOW_THIS_IN_INITIALIZER_LIST(menus::SimpleMenuModel(this)),
      browser_(browser) {
  Build();
}

void EncodingMenuModel::Build() {
  EncodingMenuController::EncodingMenuItemList encoding_menu_items;
  EncodingMenuController encoding_menu_controller;
  encoding_menu_controller.GetEncodingMenuItems(browser_->profile(),
                                                &encoding_menu_items);

  int group_id = 0;
  EncodingMenuController::EncodingMenuItemList::iterator it =
      encoding_menu_items.begin();
  for (; it != encoding_menu_items.end(); ++it) {
    int id = it->first;
    string16& label = it->second;
    if (id == 0) {
      AddSeparator();
    } else {
      if (id == IDC_ENCODING_AUTO_DETECT) {
        AddCheckItem(id, label);
      } else {
        // Use the id of the first radio command as the id of the group.
        if (group_id <= 0)
          group_id = id;
        AddRadioItem(id, label, group_id);
      }
    }
  }
}

bool EncodingMenuModel::IsCommandIdChecked(int command_id) const {
  TabContents* current_tab = browser_->GetSelectedTabContents();
  if (!current_tab)
    return false;
  EncodingMenuController controller;
  return controller.IsItemChecked(browser_->profile(),
                                  current_tab->encoding(), command_id);
}

bool EncodingMenuModel::IsCommandIdEnabled(int command_id) const {
  return browser_->command_updater()->IsCommandEnabled(command_id);
}

bool EncodingMenuModel::GetAcceleratorForCommandId(
    int command_id,
    menus::Accelerator* accelerator) {
  return false;
}

void EncodingMenuModel::ExecuteCommand(int command_id) {
  browser_->ExecuteCommand(command_id);
}

////////////////////////////////////////////////////////////////////////////////
// ZoomMenuModel

ZoomMenuModel::ZoomMenuModel(menus::SimpleMenuModel::Delegate* delegate)
    : SimpleMenuModel(delegate) {
  Build();
}

void ZoomMenuModel::Build() {
  AddItemWithStringId(IDC_ZOOM_PLUS, IDS_ZOOM_PLUS);
  AddItemWithStringId(IDC_ZOOM_NORMAL, IDS_ZOOM_NORMAL);
  AddItemWithStringId(IDC_ZOOM_MINUS, IDS_ZOOM_MINUS);
}

////////////////////////////////////////////////////////////////////////////////
// DevToolsMenuModel

DevToolsMenuModel::DevToolsMenuModel(menus::SimpleMenuModel::Delegate* delegate)
    : SimpleMenuModel(delegate) {
  Build();
}

void DevToolsMenuModel::Build() {
  AddItemWithStringId(IDC_VIEW_SOURCE, IDS_VIEW_SOURCE);
  if (g_browser_process->have_inspector_files()) {
    AddItemWithStringId(IDC_DEV_TOOLS, IDS_DEV_TOOLS);
    AddItemWithStringId(IDC_DEV_TOOLS_CONSOLE, IDS_DEV_TOOLS_CONSOLE);
  }
  AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
}

////////////////////////////////////////////////////////////////////////////////
// PopupPageMenuModel

PopupPageMenuModel::PopupPageMenuModel(
    menus::SimpleMenuModel::Delegate* delegate,
    Browser* browser)
    : menus::SimpleMenuModel(delegate), browser_(browser) {
  Build();
}

void PopupPageMenuModel::Build() {
  AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
  AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
  AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
  AddSeparator();
  AddItemWithStringId(IDC_CUT, IDS_CUT);
  AddItemWithStringId(IDC_COPY, IDS_COPY);
  AddItemWithStringId(IDC_PASTE, IDS_PASTE);
  AddSeparator();
  AddItemWithStringId(IDC_FIND, IDS_FIND);
  AddItemWithStringId(IDC_PRINT, IDS_PRINT);
  zoom_menu_model_.reset(new ZoomMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, zoom_menu_model_.get());

  encoding_menu_model_.reset(new EncodingMenuModel(browser_));
  AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
                         encoding_menu_model_.get());
}
<commit_msg>GTK: Add "Show as Tab" to popup windows.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/page_menu_model.h"

#include "app/l10n_util.h"
#include "base/compiler_specific.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/encoding_menu_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"

PageMenuModel::PageMenuModel(menus::SimpleMenuModel::Delegate* delegate,
                             Browser* browser)
    : menus::SimpleMenuModel(delegate), browser_(browser) {
  Build();
}

void PageMenuModel::Build() {
#if !defined(OS_CHROMEOS)
#if defined(OS_MACOSX)
  AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_APPLICATION_MAC);
#else
  AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS);
#endif
  AddSeparator();
#endif
  AddItemWithStringId(IDC_CUT, IDS_CUT);
  AddItemWithStringId(IDC_COPY, IDS_COPY);
  AddItemWithStringId(IDC_PASTE, IDS_PASTE);
  AddSeparator();
  AddItemWithStringId(IDC_FIND, IDS_FIND);
  AddItemWithStringId(IDC_SAVE_PAGE, IDS_SAVE_PAGE);
  AddItemWithStringId(IDC_PRINT, IDS_PRINT);
  AddSeparator();

  zoom_menu_model_.reset(new ZoomMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, zoom_menu_model_.get());

  encoding_menu_model_.reset(new EncodingMenuModel(browser_));
  AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
                         encoding_menu_model_.get());

  AddSeparator();
  devtools_menu_model_.reset(new DevToolsMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_DEVELOPER_MENU, IDS_DEVELOPER_MENU,
                         devtools_menu_model_.get());

  AddSeparator();
  AddItemWithStringId(IDC_REPORT_BUG, IDS_REPORT_BUG);
}

////////////////////////////////////////////////////////////////////////////////
// EncodingMenuModel

EncodingMenuModel::EncodingMenuModel(Browser* browser)
    : ALLOW_THIS_IN_INITIALIZER_LIST(menus::SimpleMenuModel(this)),
      browser_(browser) {
  Build();
}

void EncodingMenuModel::Build() {
  EncodingMenuController::EncodingMenuItemList encoding_menu_items;
  EncodingMenuController encoding_menu_controller;
  encoding_menu_controller.GetEncodingMenuItems(browser_->profile(),
                                                &encoding_menu_items);

  int group_id = 0;
  EncodingMenuController::EncodingMenuItemList::iterator it =
      encoding_menu_items.begin();
  for (; it != encoding_menu_items.end(); ++it) {
    int id = it->first;
    string16& label = it->second;
    if (id == 0) {
      AddSeparator();
    } else {
      if (id == IDC_ENCODING_AUTO_DETECT) {
        AddCheckItem(id, label);
      } else {
        // Use the id of the first radio command as the id of the group.
        if (group_id <= 0)
          group_id = id;
        AddRadioItem(id, label, group_id);
      }
    }
  }
}

bool EncodingMenuModel::IsCommandIdChecked(int command_id) const {
  TabContents* current_tab = browser_->GetSelectedTabContents();
  if (!current_tab)
    return false;
  EncodingMenuController controller;
  return controller.IsItemChecked(browser_->profile(),
                                  current_tab->encoding(), command_id);
}

bool EncodingMenuModel::IsCommandIdEnabled(int command_id) const {
  return browser_->command_updater()->IsCommandEnabled(command_id);
}

bool EncodingMenuModel::GetAcceleratorForCommandId(
    int command_id,
    menus::Accelerator* accelerator) {
  return false;
}

void EncodingMenuModel::ExecuteCommand(int command_id) {
  browser_->ExecuteCommand(command_id);
}

////////////////////////////////////////////////////////////////////////////////
// ZoomMenuModel

ZoomMenuModel::ZoomMenuModel(menus::SimpleMenuModel::Delegate* delegate)
    : SimpleMenuModel(delegate) {
  Build();
}

void ZoomMenuModel::Build() {
  AddItemWithStringId(IDC_ZOOM_PLUS, IDS_ZOOM_PLUS);
  AddItemWithStringId(IDC_ZOOM_NORMAL, IDS_ZOOM_NORMAL);
  AddItemWithStringId(IDC_ZOOM_MINUS, IDS_ZOOM_MINUS);
}

////////////////////////////////////////////////////////////////////////////////
// DevToolsMenuModel

DevToolsMenuModel::DevToolsMenuModel(menus::SimpleMenuModel::Delegate* delegate)
    : SimpleMenuModel(delegate) {
  Build();
}

void DevToolsMenuModel::Build() {
  AddItemWithStringId(IDC_VIEW_SOURCE, IDS_VIEW_SOURCE);
  if (g_browser_process->have_inspector_files()) {
    AddItemWithStringId(IDC_DEV_TOOLS, IDS_DEV_TOOLS);
    AddItemWithStringId(IDC_DEV_TOOLS_CONSOLE, IDS_DEV_TOOLS_CONSOLE);
  }
  AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
}

////////////////////////////////////////////////////////////////////////////////
// PopupPageMenuModel

PopupPageMenuModel::PopupPageMenuModel(
    menus::SimpleMenuModel::Delegate* delegate,
    Browser* browser)
    : menus::SimpleMenuModel(delegate), browser_(browser) {
  Build();
}

void PopupPageMenuModel::Build() {
  AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
  AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
  AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
  AddSeparator();
  AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB);
  AddSeparator();
  AddItemWithStringId(IDC_CUT, IDS_CUT);
  AddItemWithStringId(IDC_COPY, IDS_COPY);
  AddItemWithStringId(IDC_PASTE, IDS_PASTE);
  AddSeparator();
  AddItemWithStringId(IDC_FIND, IDS_FIND);
  AddItemWithStringId(IDC_PRINT, IDS_PRINT);
  zoom_menu_model_.reset(new ZoomMenuModel(delegate()));
  AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, zoom_menu_model_.get());

  encoding_menu_model_.reset(new EncodingMenuModel(browser_));
  AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU,
                         encoding_menu_model_.get());
}
<|endoftext|>


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

#include "chrome_elf/blacklist/blacklist.h"

#include <string.h>

#include "base/basictypes.h"
#include "chrome_elf/blacklist/blacklist_interceptions.h"
#include "sandbox/win/src/interception_internal.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/sandbox_utils.h"
#include "sandbox/win/src/service_resolver.h"

// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace blacklist{

const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {};
int g_troublesome_dlls_cur_index = 0;

const wchar_t kRegistryBeaconPath[] = L"SOFTWARE\\Google\\Chrome\\BLBeacon";

}  // namespace blacklist

// Allocate storage for thunks in a RWX page of this module to save on doing
// an extra allocation at run time.
#if !defined(_WIN64) && (_MSC_VER < 1700)
// 64-bit images or images generated with 2012 and above appear to not support
// writeable and executable pages.
// This would yield compile warning C4330.
// TODO(robertshield): Figure out how / if to do this on 2012.
#pragma section(".crthunk",read,write,execute)
__declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;
#endif

namespace {

enum Version {
  VERSION_PRE_XP_SP2 = 0,  // Not supported.
  VERSION_XP_SP2,
  VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
  VERSION_VISTA,       // Also includes Windows Server 2008.
  VERSION_WIN7,        // Also includes Windows Server 2008 R2.
  VERSION_WIN8,        // Also includes Windows Server 2012.
  VERSION_WIN8_1,
  VERSION_WIN_LAST,    // Indicates error condition.
};

// Whether a process is running under WOW64 (the wrapper that allows 32-bit
// processes to run on 64-bit versions of Windows).  This will return
// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
// Chrome on 64-bit Windows".  WOW64_UNKNOWN means "an error occurred", e.g.
// the process does not have sufficient access rights to determine this.
enum WOW64Status {
  WOW64_DISABLED,
  WOW64_ENABLED,
  WOW64_UNKNOWN,
};

WOW64Status GetWOW64StatusForCurrentProcess() {
  typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
  IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
      GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
  if (!is_wow64_process)
    return WOW64_DISABLED;
  BOOL is_wow64 = FALSE;
  if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64))
    return WOW64_UNKNOWN;
  return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
}

class OSInfo {
 public:
  struct VersionNumber {
    int major;
    int minor;
    int build;
  };

  struct ServicePack {
    int major;
    int minor;
  };

  OSInfo() {
    OSVERSIONINFOEX version_info = { sizeof(version_info) };
    GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
    version_number_.major = version_info.dwMajorVersion;
    version_number_.minor = version_info.dwMinorVersion;
    version_number_.build = version_info.dwBuildNumber;
    if ((version_number_.major == 5) && (version_number_.minor > 0)) {
      // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
      version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 :
                                                VERSION_SERVER_2003;
      if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
        version_ = VERSION_PRE_XP_SP2;
    } else if (version_number_.major == 6) {
      switch (version_number_.minor) {
        case 0:
          // Treat Windows Server 2008 the same as Windows Vista.
          version_ = VERSION_VISTA;
          break;
        case 1:
          // Treat Windows Server 2008 R2 the same as Windows 7.
          version_ = VERSION_WIN7;
          break;
        case 2:
          // Treat Windows Server 2012 the same as Windows 8.
          version_ = VERSION_WIN8;
          break;
        default:
          version_ = VERSION_WIN8_1;
          break;
      }
    } else if (version_number_.major > 6) {
      version_ = VERSION_WIN_LAST;
    } else {
      version_ = VERSION_PRE_XP_SP2;
    }

    service_pack_.major = version_info.wServicePackMajor;
    service_pack_.minor = version_info.wServicePackMinor;
  }

  Version version() const { return version_; }
  VersionNumber version_number() const { return version_number_; }
  ServicePack service_pack() const { return service_pack_; }

 private:
  Version version_;
  VersionNumber version_number_;
  ServicePack service_pack_;

  DISALLOW_COPY_AND_ASSIGN(OSInfo);
};

bool IsNonBrowserProcess() {
  wchar_t* command_line = GetCommandLine();
  return (command_line && wcsstr(command_line, L"--type"));
}

}  // namespace

namespace blacklist {

bool CreateBeacon() {
  HKEY beacon_key = NULL;
  DWORD disposition = 0;
  LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
                                 kRegistryBeaconPath,
                                 0,
                                 NULL,
                                 0,
                                 KEY_WRITE,
                                 NULL,
                                 &beacon_key,
                                 &disposition);
  bool success = (result == ERROR_SUCCESS &&
                  disposition != REG_OPENED_EXISTING_KEY);
  if (result == ERROR_SUCCESS)
    ::RegCloseKey(beacon_key);
  return success;
}

bool ClearBeacon() {
  LONG result = ::RegDeleteKey(HKEY_CURRENT_USER, kRegistryBeaconPath);
  return (result == ERROR_SUCCESS);
}

bool AddDllToBlacklist(const wchar_t* dll_name) {
  if (g_troublesome_dlls_cur_index >= kTroublesomeDllsMaxCount)
    return false;
  for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
    if (!wcscmp(g_troublesome_dlls[i], dll_name))
      return true;
  }

  // Copy string to blacklist.
  wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1];
  wcscpy(str_buffer, dll_name);

  g_troublesome_dlls[g_troublesome_dlls_cur_index] = str_buffer;
  g_troublesome_dlls_cur_index++;
  return true;
}

bool RemoveDllFromBlacklist(const wchar_t* dll_name) {
  for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
    if (!wcscmp(g_troublesome_dlls[i], dll_name)) {
      // Found the thing to remove. Delete it then replace it with the last
      // element.
      g_troublesome_dlls_cur_index--;
      delete[] g_troublesome_dlls[i];
      g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index];
      g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL;
      return true;
    }
  }
  return false;
}

bool Initialize(bool force) {
#if defined(_WIN64)
  // TODO(robertshield): Implement 64-bit support by providing 64-bit
  //                     interceptors.
  return false;
#endif

  // Check to see that we found the functions we need in ntdll.
  if (!InitializeInterceptImports())
    return false;

  // Check to see if this is a non-browser process, abort if so.
  if (IsNonBrowserProcess())
    return false;

  // Check to see if a beacon is present, abort if so.
  if (!force && !CreateBeacon())
    return false;

  // Don't try blacklisting on unsupported OS versions.
  OSInfo os_info;
  if (os_info.version() <= VERSION_PRE_XP_SP2)
    return false;

  // Pseudo-handle, no need to close.
  HANDLE current_process = ::GetCurrentProcess();

  // Tells the resolver to patch already patched functions.
  const bool kRelaxed = true;

  // Create a thunk via the appropriate ServiceResolver instance.
  sandbox::ServiceResolverThunk* thunk;
#if defined(_WIN64)
  // TODO(robertshield): Use the appropriate thunk for 64-bit support
  // when said support is implemented.
#else
  if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
    if (os_info.version() >= VERSION_WIN8)
      thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed);
    else
      thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed);
  } else if (os_info.version() >= VERSION_WIN8) {
    thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed);
  } else {
    thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
  }
#endif

#if defined(_WIN64) || (_MSC_VER >= 1700)
  BYTE* thunk_storage = new BYTE[sizeof(sandbox::ThunkData)];
#else
  BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);
#endif

  thunk->AllowLocalPatches();

  // Get ntdll base, target name, interceptor address,
  NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName),
                              reinterpret_cast<void*>(&__ImageBase),
                              "NtMapViewOfSection",
                              NULL,
                              &blacklist::BlNtMapViewOfSection,
                              thunk_storage,
                              sizeof(sandbox::ThunkData),
                              NULL);

  delete thunk;
  return NT_SUCCESS(ret);
}

}  // namespace blacklist
<commit_msg>Fix Thunk Storage Allocation for blacklist.cc<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_elf/blacklist/blacklist.h"

#include <string.h>

#include "base/basictypes.h"
#include "chrome_elf/blacklist/blacklist_interceptions.h"
#include "sandbox/win/src/interception_internal.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/sandbox_utils.h"
#include "sandbox/win/src/service_resolver.h"

// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace blacklist{

const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {};
int g_troublesome_dlls_cur_index = 0;

const wchar_t kRegistryBeaconPath[] = L"SOFTWARE\\Google\\Chrome\\BLBeacon";

}  // namespace blacklist

// Allocate storage for thunks in a page of this module to save on doing
// an extra allocation at run time.
#pragma section(".crthunk",read,execute)
__declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;

namespace {

enum Version {
  VERSION_PRE_XP_SP2 = 0,  // Not supported.
  VERSION_XP_SP2,
  VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
  VERSION_VISTA,       // Also includes Windows Server 2008.
  VERSION_WIN7,        // Also includes Windows Server 2008 R2.
  VERSION_WIN8,        // Also includes Windows Server 2012.
  VERSION_WIN8_1,
  VERSION_WIN_LAST,    // Indicates error condition.
};

// Whether a process is running under WOW64 (the wrapper that allows 32-bit
// processes to run on 64-bit versions of Windows).  This will return
// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
// Chrome on 64-bit Windows".  WOW64_UNKNOWN means "an error occurred", e.g.
// the process does not have sufficient access rights to determine this.
enum WOW64Status {
  WOW64_DISABLED,
  WOW64_ENABLED,
  WOW64_UNKNOWN,
};

WOW64Status GetWOW64StatusForCurrentProcess() {
  typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
  IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
      GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
  if (!is_wow64_process)
    return WOW64_DISABLED;
  BOOL is_wow64 = FALSE;
  if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64))
    return WOW64_UNKNOWN;
  return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
}

class OSInfo {
 public:
  struct VersionNumber {
    int major;
    int minor;
    int build;
  };

  struct ServicePack {
    int major;
    int minor;
  };

  OSInfo() {
    OSVERSIONINFOEX version_info = { sizeof(version_info) };
    GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
    version_number_.major = version_info.dwMajorVersion;
    version_number_.minor = version_info.dwMinorVersion;
    version_number_.build = version_info.dwBuildNumber;
    if ((version_number_.major == 5) && (version_number_.minor > 0)) {
      // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
      version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 :
                                                VERSION_SERVER_2003;
      if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
        version_ = VERSION_PRE_XP_SP2;
    } else if (version_number_.major == 6) {
      switch (version_number_.minor) {
        case 0:
          // Treat Windows Server 2008 the same as Windows Vista.
          version_ = VERSION_VISTA;
          break;
        case 1:
          // Treat Windows Server 2008 R2 the same as Windows 7.
          version_ = VERSION_WIN7;
          break;
        case 2:
          // Treat Windows Server 2012 the same as Windows 8.
          version_ = VERSION_WIN8;
          break;
        default:
          version_ = VERSION_WIN8_1;
          break;
      }
    } else if (version_number_.major > 6) {
      version_ = VERSION_WIN_LAST;
    } else {
      version_ = VERSION_PRE_XP_SP2;
    }

    service_pack_.major = version_info.wServicePackMajor;
    service_pack_.minor = version_info.wServicePackMinor;
  }

  Version version() const { return version_; }
  VersionNumber version_number() const { return version_number_; }
  ServicePack service_pack() const { return service_pack_; }

 private:
  Version version_;
  VersionNumber version_number_;
  ServicePack service_pack_;

  DISALLOW_COPY_AND_ASSIGN(OSInfo);
};

bool IsNonBrowserProcess() {
  wchar_t* command_line = GetCommandLine();
  return (command_line && wcsstr(command_line, L"--type"));
}

}  // namespace

namespace blacklist {

bool CreateBeacon() {
  HKEY beacon_key = NULL;
  DWORD disposition = 0;
  LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
                                 kRegistryBeaconPath,
                                 0,
                                 NULL,
                                 0,
                                 KEY_WRITE,
                                 NULL,
                                 &beacon_key,
                                 &disposition);
  bool success = (result == ERROR_SUCCESS &&
                  disposition != REG_OPENED_EXISTING_KEY);
  if (result == ERROR_SUCCESS)
    ::RegCloseKey(beacon_key);
  return success;
}

bool ClearBeacon() {
  LONG result = ::RegDeleteKey(HKEY_CURRENT_USER, kRegistryBeaconPath);
  return (result == ERROR_SUCCESS);
}

bool AddDllToBlacklist(const wchar_t* dll_name) {
  if (g_troublesome_dlls_cur_index >= kTroublesomeDllsMaxCount)
    return false;
  for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
    if (!wcscmp(g_troublesome_dlls[i], dll_name))
      return true;
  }

  // Copy string to blacklist.
  wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1];
  wcscpy(str_buffer, dll_name);

  g_troublesome_dlls[g_troublesome_dlls_cur_index] = str_buffer;
  g_troublesome_dlls_cur_index++;
  return true;
}

bool RemoveDllFromBlacklist(const wchar_t* dll_name) {
  for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
    if (!wcscmp(g_troublesome_dlls[i], dll_name)) {
      // Found the thing to remove. Delete it then replace it with the last
      // element.
      g_troublesome_dlls_cur_index--;
      delete[] g_troublesome_dlls[i];
      g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index];
      g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL;
      return true;
    }
  }
  return false;
}

bool Initialize(bool force) {
#if defined(_WIN64)
  // TODO(robertshield): Implement 64-bit support by providing 64-bit
  //                     interceptors.
  return false;
#endif

  // Check to see that we found the functions we need in ntdll.
  if (!InitializeInterceptImports())
    return false;

  // Check to see if this is a non-browser process, abort if so.
  if (IsNonBrowserProcess())
    return false;

  // Check to see if a beacon is present, abort if so.
  if (!force && !CreateBeacon())
    return false;

  // Don't try blacklisting on unsupported OS versions.
  OSInfo os_info;
  if (os_info.version() <= VERSION_PRE_XP_SP2)
    return false;

  // Pseudo-handle, no need to close.
  HANDLE current_process = ::GetCurrentProcess();

  // Tells the resolver to patch already patched functions.
  const bool kRelaxed = true;

  // Create a thunk via the appropriate ServiceResolver instance.
  sandbox::ServiceResolverThunk* thunk;
#if defined(_WIN64)
  // TODO(robertshield): Use the appropriate thunk for 64-bit support
  // when said support is implemented.
#else
  if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
    if (os_info.version() >= VERSION_WIN8)
      thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed);
    else
      thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed);
  } else if (os_info.version() >= VERSION_WIN8) {
    thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed);
  } else {
    thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
  }
#endif

  BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);

  // Mark the thunk storage as readable and writeable, since we
  // ready to write to it.
  DWORD old_protect = 0;
  if (!VirtualProtect(&g_thunk_storage,
                      sizeof(g_thunk_storage),
                      PAGE_EXECUTE_READWRITE,
                      &old_protect))
    return false;

  thunk->AllowLocalPatches();

  // Get ntdll base, target name, interceptor address,
  NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName),
                              reinterpret_cast<void*>(&__ImageBase),
                              "NtMapViewOfSection",
                              NULL,
                              &blacklist::BlNtMapViewOfSection,
                              thunk_storage,
                              sizeof(sandbox::ThunkData),
                              NULL);

  delete thunk;

  // Mark the thunk storage as executable and prevent any future writes to it.
  BOOL page_executable = VirtualProtect(&g_thunk_storage,
                                        sizeof(g_thunk_storage),
                                        PAGE_EXECUTE_READ,
                                        &old_protect);

  return NT_SUCCESS(ret) && page_executable;
}

}  // namespace blacklist
<|endoftext|>


<commit_before>//===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the Machinelegalizer class for ARM.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//

#include "ARMLegalizerInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Target/TargetOpcodes.h"

using namespace llvm;

#ifndef LLVM_BUILD_GLOBAL_ISEL
#error "You shouldn't build this"
#endif

ARMLegalizerInfo::ARMLegalizerInfo() {
  using namespace TargetOpcode;

  const LLT p0 = LLT::pointer(0, 32);

  const LLT s1 = LLT::scalar(1);
  const LLT s8 = LLT::scalar(8);
  const LLT s16 = LLT::scalar(16);
  const LLT s32 = LLT::scalar(32);

  setAction({G_FRAME_INDEX, p0}, Legal);

  for (auto Ty : {s1, s8, s16, s32})
    setAction({G_LOAD, Ty}, Legal);
  setAction({G_LOAD, 1, p0}, Legal);

  for (auto Ty : {s1, s8, s16, s32})
    setAction({G_ADD, Ty}, Legal);

  for (auto Op : {G_SEXT, G_ZEXT}) {
    setAction({Op, s32}, Legal);
    for (auto Ty : {s1, s8, s16})
      setAction({Op, 1, Ty}, Legal);
  }

  computeTables();
}
<commit_msg>[ARM][LegalizerInfo] Specify the type of the opcode.<commit_after>//===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the Machinelegalizer class for ARM.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//

#include "ARMLegalizerInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Target/TargetOpcodes.h"

using namespace llvm;

#ifndef LLVM_BUILD_GLOBAL_ISEL
#error "You shouldn't build this"
#endif

ARMLegalizerInfo::ARMLegalizerInfo() {
  using namespace TargetOpcode;

  const LLT p0 = LLT::pointer(0, 32);

  const LLT s1 = LLT::scalar(1);
  const LLT s8 = LLT::scalar(8);
  const LLT s16 = LLT::scalar(16);
  const LLT s32 = LLT::scalar(32);

  setAction({G_FRAME_INDEX, p0}, Legal);

  for (auto Ty : {s1, s8, s16, s32})
    setAction({G_LOAD, Ty}, Legal);
  setAction({G_LOAD, 1, p0}, Legal);

  for (auto Ty : {s1, s8, s16, s32})
    setAction({G_ADD, Ty}, Legal);

  for (unsigned Op : {G_SEXT, G_ZEXT}) {
    setAction({Op, s32}, Legal);
    for (auto Ty : {s1, s8, s16})
      setAction({Op, 1, Ty}, Legal);
  }

  computeTables();
}
<|endoftext|>


<commit_before>#include "../../testing/testing.hpp"
#include "../trie.hpp"
#include "../trie_builder.hpp"
#include "../trie_reader.hpp"
#include "../byte_stream.hpp"
#include "../write_to_sink.hpp"
#include "../../base/logging.hpp"
#include "../../std/algorithm.hpp"
#include "../../std/scoped_ptr.hpp"
#include "../../std/string.hpp"
#include "../../std/vector.hpp"
#include <boost/utility/binary.hpp>

namespace
{

struct ChildNodeInfo
{
  bool m_isLeaf;
  uint32_t m_size;
  vector<uint32_t> m_edge;
  string m_edgeValue;
  ChildNodeInfo(bool isLeaf, uint32_t size, char const * edge, char const * edgeValue)
    : m_isLeaf(isLeaf), m_size(size), m_edgeValue(edgeValue)
  {
    while (*edge)
      m_edge.push_back(*edge++);
  }

  uint32_t Size() const { return m_size; }
  bool IsLeaf() const { return m_isLeaf; }
  uint32_t const * GetEdge() const { return &m_edge[0]; }
  uint32_t GetEdgeSize() const { return m_edge.size(); }
  void const * GetEdgeValue() const { return m_edgeValue.data(); }
  uint32_t GetEdgeValueSize() const { return m_edgeValue.size(); }
};

struct KeyValuePair
{
  buffer_vector<trie::TrieChar, 8> m_key;
  uint32_t m_value;

  KeyValuePair() {}

  template <class StringT>
  KeyValuePair(StringT const & key, int value)
    : m_key(key.begin(), key.end()), m_value(value)
  {}

  uint32_t GetKeySize() const { return m_key.size(); }
  trie::TrieChar const * GetKeyData() const { return m_key.data(); }

  template <class TCont> void SerializeValue(TCont & cont) const
  {
    cont.resize(4);
    memcpy(cont.data(), &m_value, 4);
  }

  bool operator == (KeyValuePair const & p) const
  {
    return (m_key == p.m_key && m_value == p.m_value);
  }

  bool operator < (KeyValuePair const & p) const
  {
    return ((m_key != p.m_key) ? m_key < p.m_key : m_value < p.m_value);
  }

  void Swap(KeyValuePair & r)
  {
    m_key.swap(r.m_key);
    swap(m_value, r.m_value);
  }
};

string DebugPrint(KeyValuePair const & p)
{
  string keyS = ::DebugPrint(p.m_key);
  ostringstream out;
  out << "KVP(" << keyS << ", " << p.m_value << ")";
  return out.str();
}

struct KeyValuePairBackInserter
{
  vector<KeyValuePair> m_v;
  template <class StringT>
  void operator() (StringT const & s,
                   trie::reader::FixedSizeValueReader<4>::ValueType const & rawValue)
  {
    uint32_t value;
    memcpy(&value, &rawValue, 4);
    m_v.push_back(KeyValuePair(s, value));
  }
};

struct MaxValueCalc
{
  typedef uint8_t ValueType;

  ValueType operator() (void const * p, uint32_t size) const
  {
    ASSERT_EQUAL(size, 4, ());
    uint32_t value;
    memcpy(&value, p, 4);
    ASSERT_LESS(value, 256, ());
    return static_cast<uint8_t>(value);
  }
};

}  // unnamed namespace

#define ZENC bits::ZigZagEncode
#define MKSC(x) static_cast<signed char>(x)

UNIT_TEST(TrieBuilder_WriteNode_Smoke)
{
  vector<uint8_t> serial;
  PushBackByteSink<vector<uint8_t> > sink(serial);
  ChildNodeInfo children[] =
  {
    ChildNodeInfo(true, 1, "1A", "i1"),
    ChildNodeInfo(false, 2, "B", "ii2"),
    ChildNodeInfo(false, 3, "zz", ""),
    ChildNodeInfo(true, 4,
                  "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij", "i4"),
    ChildNodeInfo(true, 5, "a", "5z")
  };
  trie::builder::WriteNode(sink, 0, 3, "123", 3,
                           &children[0], &children[0] + ARRAY_SIZE(children));
  uint8_t const expected [] =
  {
    BOOST_BINARY(11000101),                                                 // Header: [0b11] [0b000101]
    3,                                                                      // Number of values
    '1', '2', '3',                                                          // Values
    BOOST_BINARY(10000001),                                                 // Child 1: header: [+leaf] [-supershort]  [2 symbols]
    static_cast<uint8_t>(ZENC(MKSC('1'))), static_cast<uint8_t>(ZENC(MKSC('A') - MKSC('1'))), // Child 1: edge
    'i', '1',                                                               // Child 1: intermediate data
    1,                                                                      // Child 1: size
    static_cast<uint8_t>(64 | ZENC(MKSC('B') - MKSC('1'))),                 // Child 2: header: [-leaf] [+supershort]
    'i', 'i', '2',                                                          // Child 2: intermediate data
    2,                                                                      // Child 2: size
    BOOST_BINARY(00000001),                                                 // Child 3: header: [-leaf] [-supershort]  [2 symbols]
    static_cast<uint8_t>(ZENC(MKSC('z') - MKSC('B'))), 0,                   // Child 3: edge
    3,                                                                      // Child 3: size
    BOOST_BINARY(10111111),                                                 // Child 4: header: [+leaf] [-supershort]  [>= 63 symbols]
    69,                                                                     // Child 4: edgeSize - 1
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('z'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    static_cast<uint8_t>(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,   // Child 4: edge
    'i', '4',                                                               // Child 4: intermediate data
    4,                                                                      // Child 4: size
    static_cast<uint8_t>(BOOST_BINARY(11000000) | ZENC(0)),                 // Child 5: header: [+leaf] [+supershort]
    '5', 'z'                                                                // Child 5: intermediate data
  };

  TEST_EQUAL(serial, vector<uint8_t>(&expected[0], &expected[0] + ARRAY_SIZE(expected)), ());
}

UNIT_TEST(TrieBuilder_Build)
{
  int const base = 3;
  int const maxLen = 3;

  vector<string> possibleStrings(1, string());
  for (int len = 1; len <= maxLen; ++len)
  {
    for (int i = 0, p = static_cast<int>(pow((double) base, len)); i < p; ++i)
    {
      string s(len, 'A');
      int t = i;
      for (int l = len - 1; l >= 0; --l, t /= base)
        s[l] += (t % base);
      possibleStrings.push_back(s);
    }
  }
  sort(possibleStrings.begin(), possibleStrings.end());
  // LOG(LINFO, (possibleStrings));

  int const count = static_cast<int>(possibleStrings.size());
  for (int i0 = -1; i0 < count; ++i0)
    for (int i1 = i0; i1 < count; ++i1)
      for (int i2 = i1; i2 < count; ++i2)
  {
    vector<KeyValuePair> v;
    if (i0 >= 0) v.push_back(KeyValuePair(possibleStrings[i0], i0));
    if (i1 >= 0) v.push_back(KeyValuePair(possibleStrings[i1], i1 + 10));
    if (i2 >= 0) v.push_back(KeyValuePair(possibleStrings[i2], i2 + 100));
    vector<string> vs;
    for (size_t i = 0; i < v.size(); ++i)
      vs.push_back(string(v[i].m_key.begin(), v[i].m_key.end()));

    vector<uint8_t> serial;
    PushBackByteSink<vector<uint8_t> > sink(serial);
    trie::Build(sink, v.begin(), v.end(), trie::builder::MaxValueEdgeBuilder<MaxValueCalc>());
    reverse(serial.begin(), serial.end());
    // LOG(LINFO, (serial.size(), vs));

    MemReader memReader = MemReader(&serial[0], serial.size());
    typedef trie::Iterator<
        trie::reader::FixedSizeValueReader<4>::ValueType,
        trie::reader::FixedSizeValueReader<1>::ValueType
        > IteratorType;
    scoped_ptr<IteratorType> root(trie::reader::ReadTrie(memReader,
                                                         trie::reader::FixedSizeValueReader<4>(),
                                                         trie::reader::FixedSizeValueReader<1>()));
    vector<KeyValuePair> res;
    KeyValuePairBackInserter f;
    trie::ForEachRef(*root, f, vector<trie::TrieChar>());
    sort(f.m_v.begin(), f.m_v.end());
    TEST_EQUAL(v, f.m_v, ());

    uint32_t expectedMaxEdgeValue = 0;
    for (size_t i = 0; i < v.size(); ++i)
      if (!v[i].m_key.empty())
        expectedMaxEdgeValue = max(expectedMaxEdgeValue, v[i].m_value);
    uint32_t maxEdgeValue = 0;
    for (uint32_t i = 0; i < root->m_edge.size(); ++i)
      maxEdgeValue = max(maxEdgeValue, static_cast<uint32_t>(root->m_edge[i].m_value.m_data[0]));
    TEST_EQUAL(maxEdgeValue, expectedMaxEdgeValue, (v, f.m_v));
  }
}
<commit_msg>[tests] added MKUC macro<commit_after>#include "../../testing/testing.hpp"
#include "../trie.hpp"
#include "../trie_builder.hpp"
#include "../trie_reader.hpp"
#include "../byte_stream.hpp"
#include "../write_to_sink.hpp"
#include "../../base/logging.hpp"
#include "../../std/algorithm.hpp"
#include "../../std/scoped_ptr.hpp"
#include "../../std/string.hpp"
#include "../../std/vector.hpp"
#include <boost/utility/binary.hpp>

namespace
{

struct ChildNodeInfo
{
  bool m_isLeaf;
  uint32_t m_size;
  vector<uint32_t> m_edge;
  string m_edgeValue;
  ChildNodeInfo(bool isLeaf, uint32_t size, char const * edge, char const * edgeValue)
    : m_isLeaf(isLeaf), m_size(size), m_edgeValue(edgeValue)
  {
    while (*edge)
      m_edge.push_back(*edge++);
  }

  uint32_t Size() const { return m_size; }
  bool IsLeaf() const { return m_isLeaf; }
  uint32_t const * GetEdge() const { return &m_edge[0]; }
  uint32_t GetEdgeSize() const { return m_edge.size(); }
  void const * GetEdgeValue() const { return m_edgeValue.data(); }
  uint32_t GetEdgeValueSize() const { return m_edgeValue.size(); }
};

struct KeyValuePair
{
  buffer_vector<trie::TrieChar, 8> m_key;
  uint32_t m_value;

  KeyValuePair() {}

  template <class StringT>
  KeyValuePair(StringT const & key, int value)
    : m_key(key.begin(), key.end()), m_value(value)
  {}

  uint32_t GetKeySize() const { return m_key.size(); }
  trie::TrieChar const * GetKeyData() const { return m_key.data(); }

  template <class TCont> void SerializeValue(TCont & cont) const
  {
    cont.resize(4);
    memcpy(cont.data(), &m_value, 4);
  }

  bool operator == (KeyValuePair const & p) const
  {
    return (m_key == p.m_key && m_value == p.m_value);
  }

  bool operator < (KeyValuePair const & p) const
  {
    return ((m_key != p.m_key) ? m_key < p.m_key : m_value < p.m_value);
  }

  void Swap(KeyValuePair & r)
  {
    m_key.swap(r.m_key);
    swap(m_value, r.m_value);
  }
};

string DebugPrint(KeyValuePair const & p)
{
  string keyS = ::DebugPrint(p.m_key);
  ostringstream out;
  out << "KVP(" << keyS << ", " << p.m_value << ")";
  return out.str();
}

struct KeyValuePairBackInserter
{
  vector<KeyValuePair> m_v;
  template <class StringT>
  void operator() (StringT const & s,
                   trie::reader::FixedSizeValueReader<4>::ValueType const & rawValue)
  {
    uint32_t value;
    memcpy(&value, &rawValue, 4);
    m_v.push_back(KeyValuePair(s, value));
  }
};

struct MaxValueCalc
{
  typedef uint8_t ValueType;

  ValueType operator() (void const * p, uint32_t size) const
  {
    ASSERT_EQUAL(size, 4, ());
    uint32_t value;
    memcpy(&value, p, 4);
    ASSERT_LESS(value, 256, ());
    return static_cast<uint8_t>(value);
  }
};

}  // unnamed namespace

#define ZENC bits::ZigZagEncode
#define MKSC(x) static_cast<signed char>(x)
#define MKUC(x) static_cast<uint8_t>(x)

UNIT_TEST(TrieBuilder_WriteNode_Smoke)
{
  vector<uint8_t> serial;
  PushBackByteSink<vector<uint8_t> > sink(serial);
  ChildNodeInfo children[] =
  {
    ChildNodeInfo(true, 1, "1A", "i1"),
    ChildNodeInfo(false, 2, "B", "ii2"),
    ChildNodeInfo(false, 3, "zz", ""),
    ChildNodeInfo(true, 4,
                  "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij", "i4"),
    ChildNodeInfo(true, 5, "a", "5z")
  };
  trie::builder::WriteNode(sink, 0, 3, "123", 3,
                           &children[0], &children[0] + ARRAY_SIZE(children));
  uint8_t const expected [] =
  {
    BOOST_BINARY(11000101),                                                 // Header: [0b11] [0b000101]
    3,                                                                      // Number of values
    '1', '2', '3',                                                          // Values
    BOOST_BINARY(10000001),                                                 // Child 1: header: [+leaf] [-supershort]  [2 symbols]
    MKUC(ZENC(MKSC('1'))), MKUC(ZENC(MKSC('A') - MKSC('1'))),               // Child 1: edge
    'i', '1',                                                               // Child 1: intermediate data
    1,                                                                      // Child 1: size
    MKUC(64 | ZENC(MKSC('B') - MKSC('1'))),                                 // Child 2: header: [-leaf] [+supershort]
    'i', 'i', '2',                                                          // Child 2: intermediate data
    2,                                                                      // Child 2: size
    BOOST_BINARY(00000001),                                                 // Child 3: header: [-leaf] [-supershort]  [2 symbols]
    MKUC(ZENC(MKSC('z') - MKSC('B'))), 0,                                   // Child 3: edge
    3,                                                                      // Child 3: size
    BOOST_BINARY(10111111),                                                 // Child 4: header: [+leaf] [-supershort]  [>= 63 symbols]
    69,                                                                     // Child 4: edgeSize - 1
    MKUC(ZENC(MKSC('a') - MKSC('z'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    MKUC(ZENC(MKSC('a') - MKSC('j'))), 2,2,2,2,2,2,2,2,2,                   // Child 4: edge
    'i', '4',                                                               // Child 4: intermediate data
    4,                                                                      // Child 4: size
    MKUC(BOOST_BINARY(11000000) | ZENC(0)),                                 // Child 5: header: [+leaf] [+supershort]
    '5', 'z'                                                                // Child 5: intermediate data
  };

  TEST_EQUAL(serial, vector<uint8_t>(&expected[0], &expected[0] + ARRAY_SIZE(expected)), ());
}

UNIT_TEST(TrieBuilder_Build)
{
  int const base = 3;
  int const maxLen = 3;

  vector<string> possibleStrings(1, string());
  for (int len = 1; len <= maxLen; ++len)
  {
    for (int i = 0, p = static_cast<int>(pow((double) base, len)); i < p; ++i)
    {
      string s(len, 'A');
      int t = i;
      for (int l = len - 1; l >= 0; --l, t /= base)
        s[l] += (t % base);
      possibleStrings.push_back(s);
    }
  }
  sort(possibleStrings.begin(), possibleStrings.end());
  // LOG(LINFO, (possibleStrings));

  int const count = static_cast<int>(possibleStrings.size());
  for (int i0 = -1; i0 < count; ++i0)
    for (int i1 = i0; i1 < count; ++i1)
      for (int i2 = i1; i2 < count; ++i2)
  {
    vector<KeyValuePair> v;
    if (i0 >= 0) v.push_back(KeyValuePair(possibleStrings[i0], i0));
    if (i1 >= 0) v.push_back(KeyValuePair(possibleStrings[i1], i1 + 10));
    if (i2 >= 0) v.push_back(KeyValuePair(possibleStrings[i2], i2 + 100));
    vector<string> vs;
    for (size_t i = 0; i < v.size(); ++i)
      vs.push_back(string(v[i].m_key.begin(), v[i].m_key.end()));

    vector<uint8_t> serial;
    PushBackByteSink<vector<uint8_t> > sink(serial);
    trie::Build(sink, v.begin(), v.end(), trie::builder::MaxValueEdgeBuilder<MaxValueCalc>());
    reverse(serial.begin(), serial.end());
    // LOG(LINFO, (serial.size(), vs));

    MemReader memReader = MemReader(&serial[0], serial.size());
    typedef trie::Iterator<
        trie::reader::FixedSizeValueReader<4>::ValueType,
        trie::reader::FixedSizeValueReader<1>::ValueType
        > IteratorType;
    scoped_ptr<IteratorType> root(trie::reader::ReadTrie(memReader,
                                                         trie::reader::FixedSizeValueReader<4>(),
                                                         trie::reader::FixedSizeValueReader<1>()));
    vector<KeyValuePair> res;
    KeyValuePairBackInserter f;
    trie::ForEachRef(*root, f, vector<trie::TrieChar>());
    sort(f.m_v.begin(), f.m_v.end());
    TEST_EQUAL(v, f.m_v, ());

    uint32_t expectedMaxEdgeValue = 0;
    for (size_t i = 0; i < v.size(); ++i)
      if (!v[i].m_key.empty())
        expectedMaxEdgeValue = max(expectedMaxEdgeValue, v[i].m_value);
    uint32_t maxEdgeValue = 0;
    for (uint32_t i = 0; i < root->m_edge.size(); ++i)
      maxEdgeValue = max(maxEdgeValue, static_cast<uint32_t>(root->m_edge[i].m_value.m_data[0]));
    TEST_EQUAL(maxEdgeValue, expectedMaxEdgeValue, (v, f.m_v));
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, 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 <ORGANIZATION> 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: E. Gil Jones

#include <moveit_manipulation_visualization/place_generator_dummy.h>
#include <geometric_shapes/shape_operations.h>

namespace moveit_manipulation_visualization {

bool PlaceGeneratorDummy::generatePlaceLocations(const planning_scene::PlanningSceneConstPtr& planning_scene,
                                                 const std::string& object,
                                                 const std::string& support,
                                                 std::vector<geometry_msgs::PoseStamped>& place_locations)
{
  place_locations.clear();

  moveit_msgs::CollisionObject sup;
  if(!planning_scene->getCollisionObjectMsg(support,
                                            sup)) {
    ROS_WARN_STREAM("Don't appear to have object " << support << " in planning scene for place support");
    return false;
  }

  std::vector<const planning_models::KinematicState::AttachedBody*> ab;
  planning_scene->getCurrentState().getAttachedBodies(ab);

  if(ab.size() == 0) {
    ROS_WARN_STREAM("No attached bodies associated with current state of planning scene.  Can't place");
    return false;
  }
  moveit_msgs::Shape attached_shape;
  bool found = false;
  for(unsigned int i = 0; i < ab.size(); i++) {
    if(ab[i]->getName() == object) {
      shapes::constructMsgFromShape(ab[i]->getShapes()[0], attached_shape);
      found = true;
      break;
    }
  }
  if(!found) {
    ROS_WARN_STREAM("Don't appear to have object " << object << " in planning scene for place");
  }

  Eigen::Affine3d sup_pose;
  planning_models::poseFromMsg(sup.poses[0], sup_pose);

  if(sup.shapes[0].dimensions.size() != 3) {
    ROS_WARN_STREAM("Dummy generator can only deal with support surface boxes");
    return false;
  }

  double xex, yex, zex;
  shapes::getShapeExtents(attached_shape, xex, yex, zex);

  double l = sup.shapes[0].dimensions[0]-xex;
  double w = sup.shapes[0].dimensions[1]-yex;
  double d = sup.shapes[0].dimensions[2]/2.0;//+zex/2.0;

  double spacing = .1;

  unsigned int lnum = floor(l/spacing);
  unsigned int wnum = floor(w/spacing);

  l = ((lnum*1.0)*spacing);
  w = ((wnum*1.0)*spacing);

  std::vector<double> angles;
  angles.push_back(0);
  angles.push_back(M_PI/4.0);
  angles.push_back(-M_PI/4.0);
  angles.push_back(M_PI/2.0);
  angles.push_back(-M_PI/2.0);
  angles.push_back(-M_PI);
  angles.push_back(M_PI);

  unsigned int total_place_locations = lnum*wnum*angles.size();

  if(total_place_locations == 0) {
    ROS_WARN_STREAM("Surface too small for placing");
    return false;
  }

  std::vector<unsigned int> random_numbers(total_place_locations);
  for(unsigned int i = 0; i < total_place_locations; i++) {
    random_numbers[i] = i;
  }
  //random_shuffle(random_numbers.begin(), random_numbers.end());

  place_locations.resize(total_place_locations);
  unsigned int cur_ind = 0;
  for(unsigned int i = 0; i < lnum; i++) {
    for(unsigned int j = 0; j < wnum; j++) {
      for(unsigned int k = 0; k < angles.size(); k++, cur_ind++) {
        geometry_msgs::PoseStamped place_pose;
        place_pose.pose = sup.poses[0];
        place_pose.header.frame_id = planning_scene->getPlanningFrame();
        place_pose.pose.position.x += -(l/2.0)+((i*1.0)*spacing);
        place_pose.pose.position.y += -(w/2.0)+((j*1.0)*spacing);
        place_pose.pose.position.z += d;
        Eigen::Affine3d cur;
        planning_models::poseFromMsg(place_pose.pose, cur);
        Eigen::Affine3d trans(Eigen::AngleAxisd(angles[k], Eigen::Vector3d::UnitZ()));
        Eigen::Affine3d conv = cur*trans;
        planning_models::msgFromPose(conv, place_pose.pose);
        ROS_DEBUG_STREAM("Place location " << i << " " << j << " "
                         << place_pose.pose.position.x << " "
                         << place_pose.pose.position.y << " "
                         << place_pose.pose.position.z);
        place_locations[random_numbers[cur_ind]] = place_pose;
      }
    }
  }
  return true;
}

}
<commit_msg>Updating for shape API<commit_after>/*
 * Copyright (c) 2012, 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 <ORGANIZATION> 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: E. Gil Jones

#include <moveit_manipulation_visualization/place_generator_dummy.h>
#include <geometric_shapes/shape_operations.h>

namespace moveit_manipulation_visualization {

bool PlaceGeneratorDummy::generatePlaceLocations(const planning_scene::PlanningSceneConstPtr& planning_scene,
                                                 const std::string& object,
                                                 const std::string& support,
                                                 std::vector<geometry_msgs::PoseStamped>& place_locations)
{
  place_locations.clear();

  moveit_msgs::CollisionObject sup;
  if(!planning_scene->getCollisionObjectMsg(support,
                                            sup)) {
    ROS_WARN_STREAM("Don't appear to have object " << support << " in planning scene for place support");
    return false;
  }

  std::vector<const planning_models::KinematicState::AttachedBody*> ab;
  planning_scene->getCurrentState().getAttachedBodies(ab);

  if(ab.size() == 0) {
    ROS_WARN_STREAM("No attached bodies associated with current state of planning scene.  Can't place");
    return false;
  }
  moveit_msgs::Shape attached_shape;
  bool found = false;
  for(unsigned int i = 0; i < ab.size(); i++) {
    if(ab[i]->getName() == object) {
      shapes::constructMsgFromShape(ab[i]->getShapes()[0].get(), attached_shape);
      found = true;
      break;
    }
  }
  if(!found) {
    ROS_WARN_STREAM("Don't appear to have object " << object << " in planning scene for place");
  }

  Eigen::Affine3d sup_pose;
  planning_models::poseFromMsg(sup.poses[0], sup_pose);

  if(sup.shapes[0].dimensions.size() != 3) {
    ROS_WARN_STREAM("Dummy generator can only deal with support surface boxes");
    return false;
  }

  double xex, yex, zex;
  shapes::getShapeExtents(attached_shape, xex, yex, zex);

  double l = sup.shapes[0].dimensions[0]-xex;
  double w = sup.shapes[0].dimensions[1]-yex;
  double d = sup.shapes[0].dimensions[2]/2.0;//+zex/2.0;

  double spacing = .1;

  unsigned int lnum = floor(l/spacing);
  unsigned int wnum = floor(w/spacing);

  l = ((lnum*1.0)*spacing);
  w = ((wnum*1.0)*spacing);

  std::vector<double> angles;
  angles.push_back(0);
  angles.push_back(M_PI/4.0);
  angles.push_back(-M_PI/4.0);
  angles.push_back(M_PI/2.0);
  angles.push_back(-M_PI/2.0);
  angles.push_back(-M_PI);
  angles.push_back(M_PI);

  unsigned int total_place_locations = lnum*wnum*angles.size();

  if(total_place_locations == 0) {
    ROS_WARN_STREAM("Surface too small for placing");
    return false;
  }

  std::vector<unsigned int> random_numbers(total_place_locations);
  for(unsigned int i = 0; i < total_place_locations; i++) {
    random_numbers[i] = i;
  }
  //random_shuffle(random_numbers.begin(), random_numbers.end());

  place_locations.resize(total_place_locations);
  unsigned int cur_ind = 0;
  for(unsigned int i = 0; i < lnum; i++) {
    for(unsigned int j = 0; j < wnum; j++) {
      for(unsigned int k = 0; k < angles.size(); k++, cur_ind++) {
        geometry_msgs::PoseStamped place_pose;
        place_pose.pose = sup.poses[0];
        place_pose.header.frame_id = planning_scene->getPlanningFrame();
        place_pose.pose.position.x += -(l/2.0)+((i*1.0)*spacing);
        place_pose.pose.position.y += -(w/2.0)+((j*1.0)*spacing);
        place_pose.pose.position.z += d;
        Eigen::Affine3d cur;
        planning_models::poseFromMsg(place_pose.pose, cur);
        Eigen::Affine3d trans(Eigen::AngleAxisd(angles[k], Eigen::Vector3d::UnitZ()));
        Eigen::Affine3d conv = cur*trans;
        planning_models::msgFromPose(conv, place_pose.pose);
        ROS_DEBUG_STREAM("Place location " << i << " " << j << " "
                         << place_pose.pose.position.x << " "
                         << place_pose.pose.position.y << " "
                         << place_pose.pose.position.z);
        place_locations[random_numbers[cur_ind]] = place_pose;
      }
    }
  }
  return true;
}

}
<|endoftext|>