<commit_before>/*
 * conversationdelegate.cpp
 *
 * copyright (c) Aron Bostrom <Aron.Bostrom at gmail.com>, 2006
 *
 * this library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QPainter>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QStyle>
#include <QBrush>
#include <QSize>
#include <QDateTime>
#include <QtDebug>

#include "conversationdelegate.h"

ConversationDelegate::ConversationDelegate(DummyKonadiAdapter &adapter, QObject *parent) : QAbstractItemDelegate(parent)
{
  backend = adapter;
  lineWidth = 510;
  authorBaseWidth = 175;
  margin = 5;
}

ConversationDelegate::~ConversationDelegate()
{
}

void ConversationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
  int lineHeight = option.fontMetrics.height() + 2;
  painter->setRenderHint(QPainter::Antialiasing);
  painter->setPen(Qt::NoPen);

  if (option.state & QStyle::State_Selected)
    painter->setBrush(option.palette.highlight());
  else
    painter->setBrush(Qt::white);
  painter->drawRect(option.rect);

  if (option.state & QStyle::State_Selected) {
    painter->setBrush(option.palette.highlightedText());
    painter->setPen(QPen(option.palette.highlightedText().color()));
  } else {
    painter->setBrush(Qt::black);
    painter->setPen(Qt::black);
  }
  painter->setFont(option.font);
  DummyKonadiConversation c = backend.conversation(index.row());
  QString ctitle = c.conversationTitle();
  QString ctime = c.arrivalTimeInText();
  QString cauthors = c.author(0);
  int messageCount = c.count();
  for (int count = 1; count < messageCount; ++count) {
    cauthors.append(", ");
    cauthors.append(c.author(count));
  }

  QString messageCountText = QString("(%L1)").arg(messageCount);
  int messageCountWidth = option.fontMetrics.width(messageCountText);

  int linePos = index.row() * lineHeight;
  int authorWidth = qMin(authorBaseWidth - (messageCount > 1 ? messageCountWidth + margin : 0),
                         lineWidth - (messageCount > 1 ? messageCountWidth + 2*margin : 0) - margin);
  int authorPos = margin;
  painter->drawText(authorPos, linePos, authorWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, cauthors);
// Add ...'s

  if (messageCount > 1) {
    int messageCountPos = qMin(2*margin + authorWidth, lineWidth - messageCountWidth - margin);
    painter->drawText(messageCountPos, linePos, messageCountWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, messageCountText);
  }

  int subjectPos = authorBaseWidth + 2*margin;
  int timeWidth = option.fontMetrics.width(ctime);
  int subjectWidth = lineWidth - subjectPos - timeWidth - 2*margin;
  painter->drawText(subjectPos, linePos, subjectWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextSingleLine, ctitle);
// Add ...'s

  int timePos = qMax(lineWidth - margin - timeWidth, authorBaseWidth + 2*margin);
  timeWidth = qMax(lineWidth - (timePos + margin), 0);
  painter->drawText(timePos, linePos, timeWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextSingleLine, ctime);
// Add ...'s
}

QSize ConversationDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
  int lineHeight = option.fontMetrics.height() + 2;
  return QSize(lineWidth, lineHeight);
}

void ConversationDelegate::updateWidth(int pos, int /*nouse*/)
{
  lineWidth = pos;
}
<commit_msg>SoC<commit_after>/*
 * conversationdelegate.cpp
 *
 * copyright (c) Aron Bostrom <Aron.Bostrom at gmail.com>, 2006
 *
 * this library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QPainter>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QStyle>
#include <QBrush>
#include <QSize>
#include <QDateTime>
#include <QtDebug>

#include "conversationdelegate.h"

ConversationDelegate::ConversationDelegate(DummyKonadiAdapter &adapter, QObject *parent) : QAbstractItemDelegate(parent)
{
  backend = adapter;
  lineWidth = 510;
  authorBaseWidth = 175;
  margin = 5;
}

ConversationDelegate::~ConversationDelegate()
{
}

void ConversationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
  int lineHeight = option.fontMetrics.height() + 2;
  painter->setRenderHint(QPainter::Antialiasing);
  painter->setPen(Qt::NoPen);

  if (option.state & QStyle::State_Selected)
    painter->setBrush(option.palette.highlight());
  else
    painter->setBrush(Qt::white);
  painter->drawRect(option.rect);

  if (option.state & QStyle::State_Selected) {
    painter->setBrush(option.palette.highlightedText());
    painter->setPen(QPen(option.palette.highlightedText().color()));
  } else {
    painter->setBrush(Qt::black);
    painter->setPen(Qt::black);
  }
  painter->setFont(option.font);
  DummyKonadiConversation c = backend.conversation(index.row());
  QString ctitle = c.conversationTitle();
  QString ctime = c.arrivalTimeInText();
  QString cauthors = c.author(0);
  int messageCount = c.count();
  for (int count = 1; count < messageCount; ++count) {
    cauthors.append(", ");
    cauthors.append(c.author(count));
  }

  int dotsWidth = option.fontMetrics.width("...");

  QString messageCountText = QString("(%L1)").arg(messageCount);
  int messageCountWidth = option.fontMetrics.width(messageCountText);

  int linePos = index.row() * lineHeight;
  int authorWidth = qMin(authorBaseWidth - (messageCount > 1 ? messageCountWidth + margin : 0),
                         lineWidth - (messageCount > 1 ? messageCountWidth + 2*margin : 0) - margin);
  int authorPos = margin;
  int tmpAuthorWidth = authorWidth;
  if (option.fontMetrics.width(cauthors) > authorWidth && authorWidth > dotsWidth) {
    tmpAuthorWidth = authorWidth - dotsWidth;
    painter->drawText(authorPos+tmpAuthorWidth, linePos, dotsWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, "...");
  }
  painter->drawText(authorPos, linePos, tmpAuthorWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, cauthors);

  if (messageCount > 1) {
    int messageCountPos = qMin(2*margin + authorWidth, lineWidth - messageCountWidth - margin);
    painter->drawText(messageCountPos, linePos, messageCountWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, messageCountText);
  }

  int subjectPos = authorBaseWidth + 2*margin;
  int timeWidth = option.fontMetrics.width(ctime);
  int subjectWidth = lineWidth - subjectPos - timeWidth - 2*margin;
  int tmpSubjectWidth = subjectWidth;
  if (option.fontMetrics.width(ctitle) > subjectWidth && subjectWidth > dotsWidth) {
    tmpSubjectWidth = subjectWidth - dotsWidth;
    painter->drawText(subjectPos+tmpSubjectWidth, linePos, dotsWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, "...");
  }
  painter->drawText(subjectPos, linePos, tmpSubjectWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextSingleLine, ctitle);

  int timePos = qMax(lineWidth - margin - timeWidth, authorBaseWidth + 2*margin);
  timeWidth = qMax(lineWidth - (timePos + margin), 0);
  int tmpTimeWidth = timeWidth;
  if (option.fontMetrics.width(ctime) > timeWidth && timeWidth > dotsWidth) {
    tmpTimeWidth = timeWidth - dotsWidth;
    painter->drawText(timePos+tmpTimeWidth, linePos, dotsWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignTop|Qt::TextSingleLine, "...");
  }
  painter->drawText(timePos, linePos, tmpTimeWidth, option.fontMetrics.height(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextSingleLine, ctime);
}

QSize ConversationDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
  int lineHeight = option.fontMetrics.height() + 2;
  return QSize(lineWidth, lineHeight);
}

void ConversationDelegate::updateWidth(int pos, int /*nouse*/)
{
  lineWidth = pos;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <XalanDOM/XalanDOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
	flush();
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(length(s) == 0 || theOffset < length(s));

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	write(c_wstr(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(XALAN_STATIC_UCODE_STRING("true"));
	}
	else
	{
		print(XALAN_STATIC_UCODE_STRING("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write(XMLCh('\n'));

	flush();
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<commit_msg>Fixed newline problem on Linux.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <XalanDOM/XalanDOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
	flush();
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(length(s) == 0 || theOffset < length(s));

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	write(c_wstr(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(XALAN_STATIC_UCODE_STRING("true"));
	}
	else
	{
		print(XALAN_STATIC_UCODE_STRING("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write(c_wstr(XALAN_STATIC_UCODE_STRING("\n")));

	flush();
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<|endoftext|>


<commit_before>#include <iostream>

#include "DrakeCollision.h"
#include "BulletModel.h"

using namespace std;
using namespace Eigen;

namespace DrakeCollision
{
  BulletElement::BulletElement(const Matrix4d& T_elem_to_link, Shape shape,
                                const vector<double>& params,
                                const string& group_name)
    : T_elem_to_link(T_elem_to_link),shape(shape)
  {
    setGroupName(group_name);
    //DEBUG
    //std::cout << "BulletElement::BulletElement: START" << std::endl;
    //END_DEBUG
    btCollisionShape* bt_shape;
    switch (shape) {
      case BOX:
        {
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create BOX ..." << std::endl;
        //END_DEBUG
        btBoxShape bt_box( btVector3(params[0]/2,params[1]/2,params[2]/2) );
        /* Strange things happen to the collision-normals when we use the
         * convex interface to the btBoxShape. Instead, we'll explicitly create
         * a btConvexHullShape.
         */
        bt_shape = new btConvexHullShape();
        bt_shape->setMargin(0.05);
        for (int i=0; i<8; ++i){
          btVector3 vtx;
          bt_box.getVertex(i,vtx);
          dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(vtx);
        }
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created BOX" << std::endl;
        //END_DEBUG
        }
        break;
      case SPHERE:
        if (true || params[0] != 0) {
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Create SPHERE ..." << std::endl;
          //END_DEBUG
          bt_shape = new btSphereShape(params[0]) ;
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Created SPHERE" << std::endl;
          //END_DEBUG
        } else {
          //DEBUG
          //std::cout << "BulletElement::BulletElement: THROW" << std::endl;
          //END_DEBUG
          throw zeroRadiusSphereException();
        }
        break;
      case CYLINDER:
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create CYLINDER ..." << std::endl;
        //END_DEBUG
        bt_shape = new btCylinderShapeZ( btVector3(params[0],params[0],params[1]/2) );
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created CYLINDER ..." << std::endl;
        //END_DEBUG
        break;
      case MESH:
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create MESH ..." << std::endl;
        //END_DEBUG
        //bt_shape = new btConvexHullShape( (btScalar*) params.data(),
                                          //params.size()/3,
                                          //(int) 3*sizeof(double) );
        bt_shape = new btConvexHullShape();
        bt_shape->setMargin(0.05);
        for (int i=0; i<params.size(); i+=3){
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Adding point " << i/3 + 1 << std::endl;
          //END_DEBUG
          dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(params[i],params[i+1],params[i+2]));
        }
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created MESH ..." << std::endl;
        //END_DEBUG
        break;
      case CAPSULE:
        bt_shape = new btConvexHullShape();
        dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,-params[1]/2));
        dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,params[1]/2));
        bt_shape->setMargin(params[0]);
        break;
      default:
        cerr << "Warning: Collision element has an unknown type " << shape << endl;
        //DEBUG
        //std::cout << "BulletElement::BulletElement: THROW" << std::endl;
        //END_DEBUG
        throw unknownShapeException(shape);
        break;
    }
    //DEBUG
    //cout << "BulletElement::BulletElement: Creating btCollisionObject" << endl;
    //END_DEBUG
    bt_obj = make_shared<btCollisionObject>();
    //DEBUG
    //cout << "BulletElement::BulletElement: Setting bt_shape for bt_ob" << endl;
    //END_DEBUG
    bt_obj->setCollisionShape(bt_shape);
    //DEBUG
    //cout << "BulletElement::BulletElement: Setting world transform for bt_ob" << endl;
    //END_DEBUG
    setWorldTransform(Matrix4d::Identity());
    //DEBUG
    //cout << "BulletElement::BulletElement: END" << std::endl;
    //END_DEBUG
  }

  const Matrix4d& BulletElement::getWorldTransform() const
  {
    return T_elem_to_world;
  }

  const Matrix4d& BulletElement::getLinkTransform() const
  {
    return T_elem_to_link;
  }

  const Shape& BulletElement::getShape() const
  {
    return shape;
  }

  void BulletElement::updateWorldTransform(const Matrix4d& T_link_to_world)
  {
    setWorldTransform(T_link_to_world*(this->T_elem_to_link));
  }

  void BulletElement::setWorldTransform(const Matrix4d& T)
  {
    this->T_elem_to_world = T_elem_to_world;

    btMatrix3x3 rot;
    btVector3 pos;
    btTransform btT;

    rot.setValue( T(0,0), T(0,1), T(0,2),
        T(1,0), T(1,1), T(1,2),
        T(2,0), T(2,1), T(2,2) );
    btT.setBasis(rot);
    pos.setValue( T(0,3), T(1,3), T(2,3) );
    btT.setOrigin(pos);

    bt_obj->setWorldTransform(btT);
  }

  const string& BulletElement::getGroupName() const
  {
    return group_name;
  }

  void BulletElement::setGroupName(const string& group_name)
  {
    this->group_name = group_name;
  }
}
<commit_msg>Taking away margins entirely<commit_after>#include <iostream>

#include "DrakeCollision.h"
#include "BulletModel.h"

using namespace std;
using namespace Eigen;

namespace DrakeCollision
{
  BulletElement::BulletElement(const Matrix4d& T_elem_to_link, Shape shape,
                                const vector<double>& params,
                                const string& group_name)
    : T_elem_to_link(T_elem_to_link),shape(shape)
  {
    setGroupName(group_name);
    //DEBUG
    //std::cout << "BulletElement::BulletElement: START" << std::endl;
    //END_DEBUG
    btCollisionShape* bt_shape;
    switch (shape) {
      case BOX:
        {
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create BOX ..." << std::endl;
        //END_DEBUG
        btBoxShape bt_box( btVector3(params[0]/2,params[1]/2,params[2]/2) );
        /* Strange things happen to the collision-normals when we use the
         * convex interface to the btBoxShape. Instead, we'll explicitly create
         * a btConvexHullShape.
         */
        bt_shape = new btConvexHullShape();
        bt_shape->setMargin(0.00);
        for (int i=0; i<8; ++i){
          btVector3 vtx;
          bt_box.getVertex(i,vtx);
          dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(vtx);
        }
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created BOX" << std::endl;
        //END_DEBUG
        }
        break;
      case SPHERE:
        if (true || params[0] != 0) {
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Create SPHERE ..." << std::endl;
          //END_DEBUG
          bt_shape = new btSphereShape(params[0]) ;
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Created SPHERE" << std::endl;
          //END_DEBUG
        } else {
          //DEBUG
          //std::cout << "BulletElement::BulletElement: THROW" << std::endl;
          //END_DEBUG
          throw zeroRadiusSphereException();
        }
        break;
      case CYLINDER:
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create CYLINDER ..." << std::endl;
        //END_DEBUG
        bt_shape = new btCylinderShapeZ( btVector3(params[0],params[0],params[1]/2) );
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created CYLINDER ..." << std::endl;
        //END_DEBUG
        break;
      case MESH:
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Create MESH ..." << std::endl;
        //END_DEBUG
        //bt_shape = new btConvexHullShape( (btScalar*) params.data(),
                                          //params.size()/3,
                                          //(int) 3*sizeof(double) );
        bt_shape = new btConvexHullShape();
        bt_shape->setMargin(0.00);
        for (int i=0; i<params.size(); i+=3){
          //DEBUG
          //std::cout << "BulletElement::BulletElement: Adding point " << i/3 + 1 << std::endl;
          //END_DEBUG
          dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(params[i],params[i+1],params[i+2]));
        }
        //DEBUG
        //std::cout << "BulletElement::BulletElement: Created MESH ..." << std::endl;
        //END_DEBUG
        break;
      case CAPSULE:
        bt_shape = new btConvexHullShape();
        dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,-params[1]/2));
        dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,params[1]/2));
        bt_shape->setMargin(params[0]);
        break;
      default:
        cerr << "Warning: Collision element has an unknown type " << shape << endl;
        //DEBUG
        //std::cout << "BulletElement::BulletElement: THROW" << std::endl;
        //END_DEBUG
        throw unknownShapeException(shape);
        break;
    }
    //DEBUG
    //cout << "BulletElement::BulletElement: Creating btCollisionObject" << endl;
    //END_DEBUG
    bt_obj = make_shared<btCollisionObject>();
    //DEBUG
    //cout << "BulletElement::BulletElement: Setting bt_shape for bt_ob" << endl;
    //END_DEBUG
    bt_obj->setCollisionShape(bt_shape);
    //DEBUG
    //cout << "BulletElement::BulletElement: Setting world transform for bt_ob" << endl;
    //END_DEBUG
    setWorldTransform(Matrix4d::Identity());
    //DEBUG
    //cout << "BulletElement::BulletElement: END" << std::endl;
    //END_DEBUG
  }

  const Matrix4d& BulletElement::getWorldTransform() const
  {
    return T_elem_to_world;
  }

  const Matrix4d& BulletElement::getLinkTransform() const
  {
    return T_elem_to_link;
  }

  const Shape& BulletElement::getShape() const
  {
    return shape;
  }

  void BulletElement::updateWorldTransform(const Matrix4d& T_link_to_world)
  {
    setWorldTransform(T_link_to_world*(this->T_elem_to_link));
  }

  void BulletElement::setWorldTransform(const Matrix4d& T)
  {
    this->T_elem_to_world = T_elem_to_world;

    btMatrix3x3 rot;
    btVector3 pos;
    btTransform btT;

    rot.setValue( T(0,0), T(0,1), T(0,2),
        T(1,0), T(1,1), T(1,2),
        T(2,0), T(2,1), T(2,2) );
    btT.setBasis(rot);
    pos.setValue( T(0,3), T(1,3), T(2,3) );
    btT.setOrigin(pos);

    bt_obj->setWorldTransform(btT);
  }

  const string& BulletElement::getGroupName() const
  {
    return group_name;
  }

  void BulletElement::setGroupName(const string& group_name)
  {
    this->group_name = group_name;
  }
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>

#include <GL/glew.h>
#include <SDL2/SDL.h>

#include "FileUtil.h"

#define WINDOW_SIZE 640

int
main(int argc, char** argv) {
    (void) argc;
    (void) argv;

    int retval = SDL_Init(SDL_INIT_VIDEO);
    if (retval != 0) {
        fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    SDL_ClearError();
    SDL_Window* mainWindow = SDL_CreateWindow("Compiling a Shader",
                                              SDL_WINDOWPOS_CENTERED,
                                              SDL_WINDOWPOS_CENTERED,
                                              WINDOW_SIZE,
                                              WINDOW_SIZE,
                                              SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (mainWindow == NULL) {
        fprintf(stderr, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    SDL_GLContext mainContext = SDL_GL_CreateContext(mainWindow);
    if (mainContext == NULL) {
        fprintf(stderr, "SDL_GL_CreateContext() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    GLenum err = glewInit();
    if (err != GLEW_OK) {
        fprintf(stderr, "Error Initializing GLEW: %s\n", glewGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
    if (vertShader == 0) {
        fprintf(stderr, "Error creating vertex shader.\n");
        exit(EXIT_FAILURE);
    }
    const GLchar* shaderCode = FileUtil::loadFileAsString("basic.vert");
    glShaderSource(vertShader, 1, &shaderCode, NULL);
    delete [] shaderCode;
    glCompileShader(vertShader);

    GLint result;
    glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE) {
        fprintf(stderr, "Vertex shader compilation failed!\n");

        GLint logLength;
        glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0) {
            char* logBuffer = new char[logLength];
            GLsizei bytesCopied;
            glGetShaderInfoLog(vertShader, logLength, &bytesCopied, logBuffer);
            fprintf(stderr, "Shader info log:\n%s\n", logBuffer);
            delete [] logBuffer;
            exit(EXIT_FAILURE);
        }
    }

    SDL_GL_DeleteContext(mainContext);
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();

    return 0;
}
<commit_msg>Finished recipe on 15.<commit_after>#include <cstdio>
#include <cstdlib>

#include <GL/glew.h>
#include <SDL2/SDL.h>

#include "FileUtil.h"

#define WINDOW_SIZE 640

void printShaderInfoLog(GLuint shaderHandle) {
    GLint logLength;
    glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &logLength);
    if (logLength > 0) {
        char* logBuffer = new char[logLength];
        GLsizei bytesCopied;
        glGetShaderInfoLog(shaderHandle, logLength, &bytesCopied, logBuffer);
        (void)fprintf(stderr, "Shader info log:\n%s\n", logBuffer);
        delete [] logBuffer;
        exit(EXIT_FAILURE);
    }
}

int
main(int argc, char** argv) {
    (void)argc;
    (void)argv;

    int retval = SDL_Init(SDL_INIT_VIDEO);
    if (retval != 0) {
        (void)fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    SDL_ClearError();
    SDL_Window* mainWindow = SDL_CreateWindow("Compiling a Shader",
                                              SDL_WINDOWPOS_CENTERED,
                                              SDL_WINDOWPOS_CENTERED,
                                              WINDOW_SIZE,
                                              WINDOW_SIZE,
                                              SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (mainWindow == NULL) {
        (void)fprintf(stderr, "SDL_CreateWindow() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    SDL_GLContext mainContext = SDL_GL_CreateContext(mainWindow);
    if (mainContext == NULL) {
        (void)fprintf(stderr, "SDL_GL_CreateContext() failed: %s\n", SDL_GetError());
        exit(EXIT_FAILURE);
    }

    GLenum err = glewInit();
    if (err != GLEW_OK) {
        (void)fprintf(stderr, "Error Initializing GLEW: %s\n", glewGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
    if (vertShader == 0) {
        (void)fprintf(stderr, "Error creating vertex shader.\n");
        exit(EXIT_FAILURE);
    }
    const GLchar* shaderCode = FileUtil::loadFileAsString("basic.vert");
    glShaderSource(vertShader, 1, &shaderCode, NULL);
    delete [] shaderCode;
    glCompileShader(vertShader);

    GLint result;
    glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE) {
        (void)fprintf(stderr, "Vertex shader compilation failed!\n");
        printShaderInfoLog(vertShader);
    } else {
        (void)printf("Shader compiled successfully!\n");
        // Print warnings, if available
        printShaderInfoLog(vertShader);
    }

    SDL_GL_DeleteContext(mainContext);
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();

    return 0;
}
<|endoftext|>


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

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/data/service/server_lib.h"

#include "tensorflow/core/data/service/credentials_factory.h"
#include "tensorflow/core/data/service/grpc_dispatcher_impl.h"
#include "tensorflow/core/data/service/grpc_util.h"
#include "tensorflow/core/data/service/grpc_worker_impl.h"
#include "tensorflow/core/platform/errors.h"

namespace tensorflow {
namespace data {

namespace {
constexpr char kPortPlaceholder[] = "%port%";
}

GrpcDataServerBase::GrpcDataServerBase(int port, const std::string& protocol,
                                       const std::string server_type)
    : requested_port_(port),
      protocol_(protocol),
      server_type_(server_type),
      bound_port_(port) {}

Status GrpcDataServerBase::Start() {
  if (stopped_) {
    return errors::FailedPrecondition(
        "Server cannot be started after it has been stopped.");
  }
  if (started_) {
    return Status::OK();
  }
  ::grpc::ServerBuilder builder;
  std::shared_ptr<::grpc::ServerCredentials> credentials;
  TF_RETURN_IF_ERROR(
      CredentialsFactory::CreateServerCredentials(protocol_, &credentials));
  builder.AddListeningPort(strings::StrCat("0.0.0.0:", requested_port_),
                           credentials, &bound_port_);
  builder.SetMaxReceiveMessageSize(-1);

  AddDataServiceToBuilder(builder);
  AddProfilerServiceToBuilder(builder);
  server_ = builder.BuildAndStart();
  if (!server_) {
    return errors::Internal("Could not start gRPC server");
  }

  TF_RETURN_IF_ERROR(StartServiceInternal());

  started_ = true;
  LOG(INFO) << "Started tf.data " << server_type_
            << " running at 0.0.0.0:" << BoundPort();
  return Status::OK();
}

void GrpcDataServerBase::Stop() {
  if (stopped_) {
    return;
  }
  if (server_) {
    StopServiceInternal();
    server_->Shutdown();
    LOG(INFO) << "Shut down " << server_type_ << " server running at port "
              << BoundPort();
  }
  stopped_ = true;
}

void GrpcDataServerBase::Join() { server_->Wait(); }

int GrpcDataServerBase::BoundPort() { return bound_port(); }

void GrpcDataServerBase::AddProfilerServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  profiler_service_ = profiler::CreateProfilerService();
  builder.RegisterService(profiler_service_.get());
}

DispatchGrpcDataServer::DispatchGrpcDataServer(
    const experimental::DispatcherConfig& config)
    : GrpcDataServerBase(config.port(), config.protocol(), "DispatchServer"),
      config_(config) {}

DispatchGrpcDataServer::~DispatchGrpcDataServer() { delete service_; }

void DispatchGrpcDataServer::AddDataServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  service_ = absl::make_unique<GrpcDispatcherImpl>(config_, builder).release();
}

Status DispatchGrpcDataServer::StartServiceInternal() {
  return service_->Start();
}

Status DispatchGrpcDataServer::NumWorkers(int* num_workers) {
  GetWorkersRequest req;
  GetWorkersResponse resp;
  ::grpc::ServerContext ctx;
  ::grpc::Status s = service_->GetWorkers(&ctx, &req, &resp);
  if (!s.ok()) {
    return grpc_util::WrapError("Failed to get workers", s);
  }
  *num_workers = resp.workers_size();
  return Status::OK();
}

size_t DispatchGrpcDataServer::NumActiveJobs() {
  return service_->NumActiveJobs();
}

WorkerGrpcDataServer::WorkerGrpcDataServer(
    const experimental::WorkerConfig& config)
    : GrpcDataServerBase(config.port(), config.protocol(), "WorkerServer"),
      config_(config) {}

WorkerGrpcDataServer::~WorkerGrpcDataServer() { delete service_; }

void WorkerGrpcDataServer::AddDataServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  service_ = absl::make_unique<GrpcWorkerImpl>(config_, builder).release();
}

Status WorkerGrpcDataServer::StartServiceInternal() {
  std::string base_address = config_.worker_address();
  if (base_address.empty()) {
    base_address = absl::StrCat("localhost:", kPortPlaceholder);
  }
  std::string worker_address = str_util::StringReplace(
      base_address, kPortPlaceholder, absl::StrCat(bound_port()),
      /*replace_all=*/false);
  std::string transfer_address = worker_address;
  std::string transfer_protocol = config_.data_transfer_protocol();
  if (!transfer_protocol.empty() && transfer_protocol != "grpc") {
    TF_RETURN_IF_ERROR(DataTransferServer::Build(
        transfer_protocol, service_->get_element_getter(), &transfer_server_));
    TF_RETURN_IF_ERROR(transfer_server_->Start());
    LOG(INFO) << "Data transfer server started at 0.0.0.0:"
              << transfer_server_->get_port();
    transfer_address = str_util::StringReplace(
        config_.data_transfer_address(), kPortPlaceholder,
        absl::StrCat(transfer_server_->get_port()),
        /*replace_all=*/false);
  }
  TF_RETURN_IF_ERROR(service_->Start(worker_address, transfer_address));
  return Status::OK();
}

void WorkerGrpcDataServer::StopServiceInternal() { service_->Stop(); }

Status WorkerGrpcDataServer::NumTasks(int* num_tasks) {
  GetWorkerTasksRequest req;
  GetWorkerTasksResponse resp;
  ::grpc::ServerContext ctx;
  ::grpc::Status s = service_->GetWorkerTasks(&ctx, &req, &resp);
  if (!s.ok()) {
    return grpc_util::WrapError("Failed to get tasks", s);
  }
  *num_tasks = resp.tasks_size();
  return Status::OK();
}

Status NewDispatchServer(const experimental::DispatcherConfig& config,
                         std::unique_ptr<DispatchGrpcDataServer>& out_server) {
  out_server = absl::make_unique<DispatchGrpcDataServer>(config);
  return Status::OK();
}

Status NewWorkerServer(const experimental::WorkerConfig& config,
                       std::unique_ptr<WorkerGrpcDataServer>& out_server) {
  out_server = absl::make_unique<WorkerGrpcDataServer>(config);
  return Status::OK();
}

}  // namespace data
}  // namespace tensorflow
<commit_msg>#tf-data-service #codehealth [22/25] Fix ClangTidy error.<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/data/service/server_lib.h"

#include <memory>
#include <string>

#include "tensorflow/core/data/service/credentials_factory.h"
#include "tensorflow/core/data/service/grpc_dispatcher_impl.h"
#include "tensorflow/core/data/service/grpc_util.h"
#include "tensorflow/core/data/service/grpc_worker_impl.h"
#include "tensorflow/core/platform/errors.h"

namespace tensorflow {
namespace data {

namespace {
constexpr char kPortPlaceholder[] = "%port%";
}

GrpcDataServerBase::GrpcDataServerBase(int port, const std::string& protocol,
                                       const std::string server_type)
    : requested_port_(port),
      protocol_(protocol),
      server_type_(server_type),
      bound_port_(port) {}

Status GrpcDataServerBase::Start() {
  if (stopped_) {
    return errors::FailedPrecondition(
        "Server cannot be started after it has been stopped.");
  }
  if (started_) {
    return Status::OK();
  }
  ::grpc::ServerBuilder builder;
  std::shared_ptr<::grpc::ServerCredentials> credentials;
  TF_RETURN_IF_ERROR(
      CredentialsFactory::CreateServerCredentials(protocol_, &credentials));
  builder.AddListeningPort(strings::StrCat("0.0.0.0:", requested_port_),
                           credentials, &bound_port_);
  builder.SetMaxReceiveMessageSize(-1);

  AddDataServiceToBuilder(builder);
  AddProfilerServiceToBuilder(builder);
  server_ = builder.BuildAndStart();
  if (!server_) {
    return errors::Internal("Could not start gRPC server");
  }

  TF_RETURN_IF_ERROR(StartServiceInternal());

  started_ = true;
  LOG(INFO) << "Started tf.data " << server_type_
            << " running at 0.0.0.0:" << BoundPort();
  return Status::OK();
}

void GrpcDataServerBase::Stop() {
  if (stopped_) {
    return;
  }
  if (server_) {
    StopServiceInternal();
    server_->Shutdown();
    LOG(INFO) << "Shut down " << server_type_ << " server running at port "
              << BoundPort();
  }
  stopped_ = true;
}

void GrpcDataServerBase::Join() { server_->Wait(); }

int GrpcDataServerBase::BoundPort() { return bound_port(); }

void GrpcDataServerBase::AddProfilerServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  profiler_service_ = profiler::CreateProfilerService();
  builder.RegisterService(profiler_service_.get());
}

DispatchGrpcDataServer::DispatchGrpcDataServer(
    const experimental::DispatcherConfig& config)
    : GrpcDataServerBase(config.port(), config.protocol(), "DispatchServer"),
      config_(config) {}

DispatchGrpcDataServer::~DispatchGrpcDataServer() { delete service_; }

void DispatchGrpcDataServer::AddDataServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  service_ = absl::make_unique<GrpcDispatcherImpl>(config_, builder).release();
}

Status DispatchGrpcDataServer::StartServiceInternal() {
  return service_->Start();
}

Status DispatchGrpcDataServer::NumWorkers(int* num_workers) {
  GetWorkersRequest req;
  GetWorkersResponse resp;
  ::grpc::ServerContext ctx;
  ::grpc::Status s = service_->GetWorkers(&ctx, &req, &resp);
  if (!s.ok()) {
    return grpc_util::WrapError("Failed to get workers", s);
  }
  *num_workers = resp.workers_size();
  return Status::OK();
}

size_t DispatchGrpcDataServer::NumActiveJobs() {
  return service_->NumActiveJobs();
}

WorkerGrpcDataServer::WorkerGrpcDataServer(
    const experimental::WorkerConfig& config)
    : GrpcDataServerBase(config.port(), config.protocol(), "WorkerServer"),
      config_(config) {}

WorkerGrpcDataServer::~WorkerGrpcDataServer() { delete service_; }

void WorkerGrpcDataServer::AddDataServiceToBuilder(
    ::grpc::ServerBuilder& builder) {
  service_ = absl::make_unique<GrpcWorkerImpl>(config_, builder).release();
}

Status WorkerGrpcDataServer::StartServiceInternal() {
  std::string base_address = config_.worker_address();
  if (base_address.empty()) {
    base_address = absl::StrCat("localhost:", kPortPlaceholder);
  }
  std::string worker_address = str_util::StringReplace(
      base_address, kPortPlaceholder, absl::StrCat(bound_port()),
      /*replace_all=*/false);
  std::string transfer_address = worker_address;
  std::string transfer_protocol = config_.data_transfer_protocol();
  if (!transfer_protocol.empty() && transfer_protocol != "grpc") {
    TF_RETURN_IF_ERROR(DataTransferServer::Build(
        transfer_protocol, service_->get_element_getter(), &transfer_server_));
    TF_RETURN_IF_ERROR(transfer_server_->Start());
    LOG(INFO) << "Data transfer server started at 0.0.0.0:"
              << transfer_server_->get_port();
    transfer_address = str_util::StringReplace(
        config_.data_transfer_address(), kPortPlaceholder,
        absl::StrCat(transfer_server_->get_port()),
        /*replace_all=*/false);
  }
  TF_RETURN_IF_ERROR(service_->Start(worker_address, transfer_address));
  return Status::OK();
}

void WorkerGrpcDataServer::StopServiceInternal() { service_->Stop(); }

Status WorkerGrpcDataServer::NumTasks(int* num_tasks) {
  GetWorkerTasksRequest req;
  GetWorkerTasksResponse resp;
  ::grpc::ServerContext ctx;
  ::grpc::Status s = service_->GetWorkerTasks(&ctx, &req, &resp);
  if (!s.ok()) {
    return grpc_util::WrapError("Failed to get tasks", s);
  }
  *num_tasks = resp.tasks_size();
  return Status::OK();
}

Status NewDispatchServer(const experimental::DispatcherConfig& config,
                         std::unique_ptr<DispatchGrpcDataServer>& out_server) {
  out_server = absl::make_unique<DispatchGrpcDataServer>(config);
  return Status::OK();
}

Status NewWorkerServer(const experimental::WorkerConfig& config,
                       std::unique_ptr<WorkerGrpcDataServer>& out_server) {
  out_server = absl::make_unique<WorkerGrpcDataServer>(config);
  return Status::OK();
}

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


<commit_before>/* Copyright 2015 Google Inc. All Rights Reserved.

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/util/events_writer.h"

#include <math.h>
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/io/record_reader.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/env.h"
#include "tensorflow/core/public/status.h"
#include "tensorflow/core/util/event.pb.h"

namespace tensorflow {
namespace {

// shorthand
Env* env() { return Env::Default(); }

void WriteSimpleValue(EventsWriter* writer, double wall_time, int64 step,
                      const string& tag, float simple_value) {
  Event event;
  event.set_wall_time(wall_time);
  event.set_step(step);
  Summary::Value* summ_val = event.mutable_summary()->add_value();
  summ_val->set_tag(tag);
  summ_val->set_simple_value(simple_value);
  writer->WriteEvent(event);
}

void WriteFile(EventsWriter* writer) {
  WriteSimpleValue(writer, 1234, 34, "foo", 3.14159);
  WriteSimpleValue(writer, 2345, 35, "bar", -42);
}

static bool ReadEventProto(io::RecordReader* reader, uint64* offset,
                           Event* proto) {
  string record;
  Status s = reader->ReadRecord(offset, &record);
  if (!s.ok()) {
    return false;
  }
  return ParseProtoUnlimited(proto, record);
}

void VerifyFile(const string& filename) {
  CHECK(env()->FileExists(filename));
  RandomAccessFile* event_file;
  TF_CHECK_OK(env()->NewRandomAccessFile(filename, &event_file));
  io::RecordReader* reader = new io::RecordReader(event_file);

  uint64 offset = 0;

  Event actual;
  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  // Wall time should be within 5s of now.

  double current_time = env()->NowMicros() / 1000000.0;
  EXPECT_LT(fabs(actual.wall_time() - current_time), 5);
  // Should have the current version number.
  EXPECT_EQ(actual.file_version(),
            strings::StrCat(EventsWriter::kVersionPrefix,
                            EventsWriter::kCurrentVersion));

  Event expected;
  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  ASSERT_TRUE(protobuf::TextFormat::ParseFromString(
      "wall_time: 1234 step: 34 "
      "summary { value { tag: 'foo' simple_value: 3.14159 } }",
      &expected));
  // TODO(keveman): Enable this check
  // EXPECT_THAT(expected, EqualsProto(actual));

  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  ASSERT_TRUE(protobuf::TextFormat::ParseFromString(
      "wall_time: 2345 step: 35 "
      "summary { value { tag: 'bar' simple_value: -42 } }",
      &expected));
  // TODO(keveman): Enable this check
  // EXPECT_THAT(expected, EqualsProto(actual));

  TF_CHECK_OK(env()->DeleteFile(filename));

  delete reader;
  delete event_file;
}

string GetDirName(const string& suffix) {
  return io::JoinPath(testing::TmpDir(), suffix);
}

TEST(EventWriter, WriteFlush) {
  string file_prefix = GetDirName("/writeflush_test");
  EventsWriter writer(file_prefix);
  WriteFile(&writer);
  EXPECT_TRUE(writer.Flush());
  string filename = writer.FileName();
  VerifyFile(filename);
}

TEST(EventWriter, WriteClose) {
  string file_prefix = GetDirName("/writeclose_test");
  EventsWriter writer(file_prefix);
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  string filename = writer.FileName();
  VerifyFile(filename);
}

TEST(EventWriter, WriteDelete) {
  string file_prefix = GetDirName("/writedelete_test");
  EventsWriter* writer = new EventsWriter(file_prefix);
  WriteFile(writer);
  string filename = writer->FileName();
  delete writer;
  VerifyFile(filename);
}

TEST(EventWriter, FailFlush) {
  string file_prefix = GetDirName("/failflush_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  WriteFile(&writer);
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
  EXPECT_FALSE(env()->FileExists(filename));
  EXPECT_FALSE(writer.Flush());
  EXPECT_FALSE(env()->FileExists(filename));
}

TEST(EventWriter, FailClose) {
  string file_prefix = GetDirName("/failclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  WriteFile(&writer);
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
  EXPECT_FALSE(env()->FileExists(filename));
  EXPECT_FALSE(writer.Close());
  EXPECT_FALSE(env()->FileExists(filename));
}

TEST(EventWriter, InitWriteClose) {
  string file_prefix = GetDirName("/initwriteclose_test");
  EventsWriter writer(file_prefix);
  EXPECT_TRUE(writer.Init());
  string filename0 = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename0));
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  string filename1 = writer.FileName();
  EXPECT_EQ(filename0, filename1);
  VerifyFile(filename1);
}

TEST(EventWriter, NameWriteClose) {
  string file_prefix = GetDirName("/namewriteclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename));
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  VerifyFile(filename);
}

TEST(EventWriter, NameClose) {
  string file_prefix = GetDirName("/nameclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  EXPECT_TRUE(writer.Close());
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
}

TEST(EventWriter, FileDeletionBeforeWriting) {
  string file_prefix = GetDirName("/fdbw_test");
  EventsWriter writer(file_prefix);
  string filename0 = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename0));
  env()->SleepForMicroseconds(
      2000000);  // To make sure timestamp part of filename will differ.
  env()->DeleteFile(filename0);
  EXPECT_TRUE(writer.Init());  // Init should reopen file.
  WriteFile(&writer);
  EXPECT_TRUE(writer.Flush());
  string filename1 = writer.FileName();
  EXPECT_NE(filename0, filename1);
  VerifyFile(filename1);
}

}  // namespace
}  // namespace tensorflow
<commit_msg>Delete duplicate #include. Change: 112846648<commit_after>/* Copyright 2015 Google Inc. All Rights Reserved.

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

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/util/events_writer.h"

#include <math.h>
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/io/record_reader.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/protobuf.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/env.h"
#include "tensorflow/core/public/status.h"
#include "tensorflow/core/util/event.pb.h"

namespace tensorflow {
namespace {

// shorthand
Env* env() { return Env::Default(); }

void WriteSimpleValue(EventsWriter* writer, double wall_time, int64 step,
                      const string& tag, float simple_value) {
  Event event;
  event.set_wall_time(wall_time);
  event.set_step(step);
  Summary::Value* summ_val = event.mutable_summary()->add_value();
  summ_val->set_tag(tag);
  summ_val->set_simple_value(simple_value);
  writer->WriteEvent(event);
}

void WriteFile(EventsWriter* writer) {
  WriteSimpleValue(writer, 1234, 34, "foo", 3.14159);
  WriteSimpleValue(writer, 2345, 35, "bar", -42);
}

static bool ReadEventProto(io::RecordReader* reader, uint64* offset,
                           Event* proto) {
  string record;
  Status s = reader->ReadRecord(offset, &record);
  if (!s.ok()) {
    return false;
  }
  return ParseProtoUnlimited(proto, record);
}

void VerifyFile(const string& filename) {
  CHECK(env()->FileExists(filename));
  RandomAccessFile* event_file;
  TF_CHECK_OK(env()->NewRandomAccessFile(filename, &event_file));
  io::RecordReader* reader = new io::RecordReader(event_file);

  uint64 offset = 0;

  Event actual;
  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  // Wall time should be within 5s of now.

  double current_time = env()->NowMicros() / 1000000.0;
  EXPECT_LT(fabs(actual.wall_time() - current_time), 5);
  // Should have the current version number.
  EXPECT_EQ(actual.file_version(),
            strings::StrCat(EventsWriter::kVersionPrefix,
                            EventsWriter::kCurrentVersion));

  Event expected;
  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  ASSERT_TRUE(protobuf::TextFormat::ParseFromString(
      "wall_time: 1234 step: 34 "
      "summary { value { tag: 'foo' simple_value: 3.14159 } }",
      &expected));
  // TODO(keveman): Enable this check
  // EXPECT_THAT(expected, EqualsProto(actual));

  CHECK(ReadEventProto(reader, &offset, &actual));
  VLOG(1) << actual.ShortDebugString();
  ASSERT_TRUE(protobuf::TextFormat::ParseFromString(
      "wall_time: 2345 step: 35 "
      "summary { value { tag: 'bar' simple_value: -42 } }",
      &expected));
  // TODO(keveman): Enable this check
  // EXPECT_THAT(expected, EqualsProto(actual));

  TF_CHECK_OK(env()->DeleteFile(filename));

  delete reader;
  delete event_file;
}

string GetDirName(const string& suffix) {
  return io::JoinPath(testing::TmpDir(), suffix);
}

TEST(EventWriter, WriteFlush) {
  string file_prefix = GetDirName("/writeflush_test");
  EventsWriter writer(file_prefix);
  WriteFile(&writer);
  EXPECT_TRUE(writer.Flush());
  string filename = writer.FileName();
  VerifyFile(filename);
}

TEST(EventWriter, WriteClose) {
  string file_prefix = GetDirName("/writeclose_test");
  EventsWriter writer(file_prefix);
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  string filename = writer.FileName();
  VerifyFile(filename);
}

TEST(EventWriter, WriteDelete) {
  string file_prefix = GetDirName("/writedelete_test");
  EventsWriter* writer = new EventsWriter(file_prefix);
  WriteFile(writer);
  string filename = writer->FileName();
  delete writer;
  VerifyFile(filename);
}

TEST(EventWriter, FailFlush) {
  string file_prefix = GetDirName("/failflush_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  WriteFile(&writer);
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
  EXPECT_FALSE(env()->FileExists(filename));
  EXPECT_FALSE(writer.Flush());
  EXPECT_FALSE(env()->FileExists(filename));
}

TEST(EventWriter, FailClose) {
  string file_prefix = GetDirName("/failclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  WriteFile(&writer);
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
  EXPECT_FALSE(env()->FileExists(filename));
  EXPECT_FALSE(writer.Close());
  EXPECT_FALSE(env()->FileExists(filename));
}

TEST(EventWriter, InitWriteClose) {
  string file_prefix = GetDirName("/initwriteclose_test");
  EventsWriter writer(file_prefix);
  EXPECT_TRUE(writer.Init());
  string filename0 = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename0));
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  string filename1 = writer.FileName();
  EXPECT_EQ(filename0, filename1);
  VerifyFile(filename1);
}

TEST(EventWriter, NameWriteClose) {
  string file_prefix = GetDirName("/namewriteclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename));
  WriteFile(&writer);
  EXPECT_TRUE(writer.Close());
  VerifyFile(filename);
}

TEST(EventWriter, NameClose) {
  string file_prefix = GetDirName("/nameclose_test");
  EventsWriter writer(file_prefix);
  string filename = writer.FileName();
  EXPECT_TRUE(writer.Close());
  EXPECT_TRUE(env()->FileExists(filename));
  env()->DeleteFile(filename);
}

TEST(EventWriter, FileDeletionBeforeWriting) {
  string file_prefix = GetDirName("/fdbw_test");
  EventsWriter writer(file_prefix);
  string filename0 = writer.FileName();
  EXPECT_TRUE(env()->FileExists(filename0));
  env()->SleepForMicroseconds(
      2000000);  // To make sure timestamp part of filename will differ.
  env()->DeleteFile(filename0);
  EXPECT_TRUE(writer.Init());  // Init should reopen file.
  WriteFile(&writer);
  EXPECT_TRUE(writer.Flush());
  string filename1 = writer.FileName();
  EXPECT_NE(filename0, filename1);
  VerifyFile(filename1);
}

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


<commit_before>/*
 * Copyright (c) 2008-2014 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of coinpp.
 *
 * coinpp is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>

#include <boost/algorithm/string.hpp>

#include <database/entry.hpp>
#include <database/logger.hpp>
#include <database/query.hpp>
#include <database/storage.hpp>
#include <database/utility.hpp>

using namespace database;

storage::storage(boost::asio::io_service & ios)
    : io_service_(ios)
    , strand_(ios)
    , timer_(ios)
{
    // ...
}

void storage::start()
{
    /**
     * Start the expire timer.
     */
    timer_.expires_from_now(std::chrono::seconds(5));
    timer_.async_wait(
        strand_.wrap(std::bind(&storage::tick, this, std::placeholders::_1))
    );
}

void storage::stop()
{
    /**
     * Cancel the timer.
     */
    timer_.cancel();

    std::lock_guard<std::recursive_mutex> l(mutex_);

    auto it = m_entries.begin();

    while (it != m_entries.end())
    {
        if (*it)
        {
            (*it)->stop();
        }
        else
        {
            // ...
        }

        it = m_entries.erase(it);
    }
}

void storage::store(const std::shared_ptr<entry> e)
{
    /**
     * Allocate the query.
     */
    query q(e->query_string());

    for (auto & i : q.pairs())
    {
        if (utility::string::starts_with(i.first, "_"))
        {
            continue;
        }

        e->pairs().insert(std::make_pair(i.first, i.second));
    }

    std::lock_guard<std::recursive_mutex> l(mutex_);

    auto it = m_entries.begin();

    for (; it != m_entries.end();)
    {
        auto index1 = 0, index2 = 0;

        std::string qs1, qs2;

        auto it1 = e->pairs().begin();

        for (; it1 != e->pairs().end(); ++it1)
        {
            if (utility::string::starts_with(it1->first, "_"))
            {
                index1++;

                continue;
            }

            qs1 += it1->first + "=" + it1->second;

            if (index1++ < (e->pairs().size() - 1))
            {
                qs1.append("&", strlen("&"));
            }
        }

        auto it2 = (*it)->pairs().begin();

        for (; it2 != (*it)->pairs().end(); ++it2)
        {
            if (utility::string::starts_with(it2->first, "_"))
            {
                index2++;

                continue;
            }

            qs2 += it2->first + "=" + it2->second;

            if (index2++ < ((*it)->pairs().size() - 1))
            {
                qs2.append("&", strlen("&"));
            }
        }

        if (boost::iequals(qs1, qs2))
        {
            /**
             * Copy the timestamp from the older entry.
             */
            e->set_timestamp((*it)->timestamp());

            /**
             * Stop the older entry.
             */
            (*it)->stop();

            /**
             * Erase the older entry.
             */
            it = m_entries.erase(it);

            /**
             * Because of this logic there shouldn't be any more matches.
             */
            break;
        }
        else
        {
            ++it;
        }
    }

    /**
     * Insert the entry.
     */
    m_entries.push_back(e);

    /**
     * Start the entry.
     */
    e->start();
}

const std::vector< std::shared_ptr<entry> > storage::find(
    const std::string & query_string
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    std::vector< std::shared_ptr<entry> > ret;

    /**
     * Allocate the query.
     */
    query q(query_string);

    for (auto & i : m_entries)
    {
        bool matches = true;

        for (auto & j : q.pairs())
        {
            if (utility::string::starts_with(j.first, "_"))
            {
                continue;
            }

            /**
             * Make sure the each key from the query is found in the entry,
             * otherwise it is a record mismatch.
             */
            bool found = false;

            for (auto & k : i->pairs())
            {
                if (boost::iequals(j.first, k.first))
                {
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                matches = false;
                break;
            }

            for (auto & k : i->pairs())
            {
                //log_debug(j.first << ":" << k.first);

                if (utility::string::starts_with(k.first, "_"))
                {
                    continue;
                }

                // key == key
                if (boost::iequals(j.first, k.first))
                {
                    log_debug(j.second << ":" << k.second);

                    //matches |= boost::iequals(j.second, k.second);

                    // value == value
                    if (boost::iequals(j.second, k.second))
                    {
                        //matches = true;
                    }
                    else
                    {
                        matches = false;
                    }

                    log_debug("matches = " << matches);
                }

                if (!matches)
                {
                    break;
                }
            }
        }

        if (matches/* && !mismatch*/)
        {
            log_debug("Insert result= " << i->query_string());

            ret.push_back(i);
        }
    }

    return ret;
}

void storage::tick(const boost::system::error_code & ec)
{
    if (ec)
    {
        // ...
    }
    else
    {
        std::lock_guard<std::recursive_mutex> l(mutex_);

        auto it = m_entries.begin();

        while (it != m_entries.end())
        {
            if (*it && (*it)->expired())
            {
                log_debug("Entry " << (*it)->query_string() << " expired.");

                (*it)->stop();

                it = m_entries.erase(it);
            }
            else if (*it)
            {
                ++it;
            }
            else
            {
                it = m_entries.erase(it);
            }
        }

        /**
         * Start the expire timer.
         */
        timer_.expires_from_now(std::chrono::seconds(5));
        timer_.async_wait(
            strand_.wrap(std::bind(&storage::tick, this,
            std::placeholders::_1))
        );
    }
}

const std::vector< std::shared_ptr<entry> > & storage::entries() const
{
    return m_entries;
}

int storage::run_test()
{
    std::vector<std::string> pairs1;

    boost::split(pairs1, "fruit=apple&color=red", boost::is_any_of("&"));

    std::cerr << pairs1.size() << std::endl;

    assert(pairs1.size() == 2);

    std::map<std::string, std::string> pairs3;

    for (auto & i : pairs1)
    {
        std::vector<std::string> pairs2;

        boost::split(pairs2, i, boost::is_any_of("="));

        pairs3[pairs2[0]] = pairs2[1];
    }

    std::cerr << pairs3.size() << std::endl;

    assert(pairs3.size() == 2);

    for (auto & i : pairs3)
    {
        std::cerr << i.first << std::endl;
        std::cerr << i.second << std::endl;
    }

    return 0;
}
<commit_msg>Cleanup old code.<commit_after>/*
 * Copyright (c) 2008-2014 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of coinpp.
 *
 * coinpp is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>

#include <boost/algorithm/string.hpp>

#include <database/entry.hpp>
#include <database/logger.hpp>
#include <database/query.hpp>
#include <database/storage.hpp>
#include <database/utility.hpp>

using namespace database;

storage::storage(boost::asio::io_service & ios)
    : io_service_(ios)
    , strand_(ios)
    , timer_(ios)
{
    // ...
}

void storage::start()
{
    /**
     * Start the expire timer.
     */
    timer_.expires_from_now(std::chrono::seconds(5));
    timer_.async_wait(
        strand_.wrap(std::bind(&storage::tick, this, std::placeholders::_1))
    );
}

void storage::stop()
{
    /**
     * Cancel the timer.
     */
    timer_.cancel();

    std::lock_guard<std::recursive_mutex> l(mutex_);

    auto it = m_entries.begin();

    while (it != m_entries.end())
    {
        if (*it)
        {
            (*it)->stop();
        }
        else
        {
            // ...
        }

        it = m_entries.erase(it);
    }
}

void storage::store(const std::shared_ptr<entry> e)
{
    /**
     * Allocate the query.
     */
    query q(e->query_string());

    for (auto & i : q.pairs())
    {
        if (utility::string::starts_with(i.first, "_"))
        {
            continue;
        }

        e->pairs().insert(std::make_pair(i.first, i.second));
    }

    std::lock_guard<std::recursive_mutex> l(mutex_);

    auto it = m_entries.begin();

    for (; it != m_entries.end();)
    {
        auto index1 = 0, index2 = 0;

        std::string qs1, qs2;

        auto it1 = e->pairs().begin();

        for (; it1 != e->pairs().end(); ++it1)
        {
            if (utility::string::starts_with(it1->first, "_"))
            {
                index1++;

                continue;
            }

            qs1 += it1->first + "=" + it1->second;

            if (index1++ < (e->pairs().size() - 1))
            {
                qs1.append("&", strlen("&"));
            }
        }

        auto it2 = (*it)->pairs().begin();

        for (; it2 != (*it)->pairs().end(); ++it2)
        {
            if (utility::string::starts_with(it2->first, "_"))
            {
                index2++;

                continue;
            }

            qs2 += it2->first + "=" + it2->second;

            if (index2++ < ((*it)->pairs().size() - 1))
            {
                qs2.append("&", strlen("&"));
            }
        }

        if (boost::iequals(qs1, qs2))
        {
            /**
             * Copy the timestamp from the older entry.
             */
            e->set_timestamp((*it)->timestamp());

            /**
             * Stop the older entry.
             */
            (*it)->stop();

            /**
             * Erase the older entry.
             */
            it = m_entries.erase(it);

            /**
             * Because of this logic there shouldn't be any more matches.
             */
            break;
        }
        else
        {
            ++it;
        }
    }

    /**
     * Insert the entry.
     */
    m_entries.push_back(e);

    /**
     * Start the entry.
     */
    e->start();
}

const std::vector< std::shared_ptr<entry> > storage::find(
    const std::string & query_string
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    std::vector< std::shared_ptr<entry> > ret;

    /**
     * Allocate the query.
     */
    query q(query_string);

    for (auto & i : m_entries)
    {
        bool matches = true;

        for (auto & j : q.pairs())
        {
            if (utility::string::starts_with(j.first, "_"))
            {
                continue;
            }

            /**
             * Make sure the each key from the query is found in the entry,
             * otherwise it is a record mismatch.
             */
            bool found = false;

            for (auto & k : i->pairs())
            {
                if (boost::iequals(j.first, k.first))
                {
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                matches = false;
                break;
            }

            for (auto & k : i->pairs())
            {
                //log_debug(j.first << ":" << k.first);

                if (utility::string::starts_with(k.first, "_"))
                {
                    continue;
                }

                if (boost::iequals(j.first, k.first))
                {
                    log_debug(j.second << ":" << k.second);

                    if (boost::iequals(j.second, k.second))
                    {

                    }
                    else
                    {
                        matches = false;
                    }

                    log_debug("matches = " << matches);
                }

                if (!matches)
                {
                    break;
                }
            }
        }

        if (matches)
        {
            log_debug("Insert result= " << i->query_string());

            ret.push_back(i);
        }
    }

    return ret;
}

void storage::tick(const boost::system::error_code & ec)
{
    if (ec)
    {
        // ...
    }
    else
    {
        std::lock_guard<std::recursive_mutex> l(mutex_);

        auto it = m_entries.begin();

        while (it != m_entries.end())
        {
            if (*it && (*it)->expired())
            {
                log_debug("Entry " << (*it)->query_string() << " expired.");

                (*it)->stop();

                it = m_entries.erase(it);
            }
            else if (*it)
            {
                ++it;
            }
            else
            {
                it = m_entries.erase(it);
            }
        }

        /**
         * Start the expire timer.
         */
        timer_.expires_from_now(std::chrono::seconds(5));
        timer_.async_wait(
            strand_.wrap(std::bind(&storage::tick, this,
            std::placeholders::_1))
        );
    }
}

const std::vector< std::shared_ptr<entry> > & storage::entries() const
{
    return m_entries;
}

int storage::run_test()
{
    std::vector<std::string> pairs1;

    boost::split(pairs1, "fruit=apple&color=red", boost::is_any_of("&"));

    std::cerr << pairs1.size() << std::endl;

    assert(pairs1.size() == 2);

    std::map<std::string, std::string> pairs3;

    for (auto & i : pairs1)
    {
        std::vector<std::string> pairs2;

        boost::split(pairs2, i, boost::is_any_of("="));

        pairs3[pairs2[0]] = pairs2[1];
    }

    std::cerr << pairs3.size() << std::endl;

    assert(pairs3.size() == 2);

    for (auto & i : pairs3)
    {
        std::cerr << i.first << std::endl;
        std::cerr << i.second << std::endl;
    }

    return 0;
}
<|endoftext|>


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

#include "webkit/glue/plugins/pepper_device_context_2d.h"

#include "base/logging.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "third_party/ppapi/c/ppb_device_context_2d.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"

#if defined(OS_MACOSX)
#include "base/mac_util.h"
#include "base/scoped_cftyperef.h"
#endif

namespace pepper {

namespace {

PP_Resource Create(PP_Module module_id, int32_t width, int32_t height) {
  PluginModule* module = PluginModule::FromPPModule(module_id);
  if (!module)
    return NullPPResource();

  scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module));
  if (!context->Init(width, height))
    return NullPPResource();
  context->AddRef();  // AddRef for the caller.
  return context->GetResource();
}

void PaintImageData(PP_Resource device_context,
                    PP_Resource image,
                    int32_t x, int32_t y,
                    const PP_Rect* dirty,
                    uint32_t dirty_rect_count,
                    PPB_DeviceContext2D_PaintCallback callback,
                    void* callback_data) {
  scoped_refptr<Resource> device_resource =
      ResourceTracker::Get()->GetResource(device_context);
  if (!device_resource.get())
    return;
  DeviceContext2D* context = device_resource->AsDeviceContext2D();
  if (!context)
    return;
  context->PaintImageData(image, x, y, dirty, dirty_rect_count,
                          callback, callback_data);
}

const PPB_DeviceContext2D ppb_devicecontext2d = {
  &Create,
  &PaintImageData,
};

}  // namespace

DeviceContext2D::DeviceContext2D(PluginModule* module) : Resource(module) {
}

DeviceContext2D::~DeviceContext2D() {
}

// static
const PPB_DeviceContext2D* DeviceContext2D::GetInterface() {
  return &ppb_devicecontext2d;
}

bool DeviceContext2D::Init(int width, int height) {
  image_data_.reset(new ImageData(module()));
  if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height) ||
      !image_data_->Map()) {
    image_data_.reset();
    return false;
  }

  return true;
}

void DeviceContext2D::PaintImageData(PP_Resource image,
                                     int32_t x, int32_t y,
                                     const PP_Rect* dirty,
                                     uint32_t dirty_rect_count,
                                     PPB_DeviceContext2D_PaintCallback callback,
                                     void* callback_data) {
  scoped_refptr<Resource> image_resource =
      ResourceTracker::Get()->GetResource(image);
  if (!image_resource.get())
    return;
  ImageData* new_image_data = image_resource->AsImageData();
  if (!new_image_data)
    return;

  const SkBitmap& new_image_bitmap = new_image_data->GetMappedBitmap();

  // TODO(brettw) handle multiple dirty rects.
  DCHECK(dirty_rect_count == 1);

  // Draw the bitmap to the backing store.
  SkIRect src_rect;
  if (dirty->point.x == 0 && dirty->point.y == 0 &&
      dirty->size.width == 0 && dirty->size.height == 0) {
    // Default to the entire bitmap.
    src_rect.fLeft = 0;
    src_rect.fTop = 0;
    src_rect.fRight = new_image_bitmap.width();
    src_rect.fBottom = new_image_bitmap.height();
  } else {
    src_rect.fLeft = dirty->point.x;
    src_rect.fTop = dirty->point.y;
    src_rect.fRight = dirty->point.x + dirty->size.width;
    src_rect.fBottom = dirty->point.y + dirty->size.height;
  }
  SkRect dest_rect = { SkIntToScalar(src_rect.fLeft),
                       SkIntToScalar(src_rect.fTop),
                       SkIntToScalar(src_rect.fRight),
                       SkIntToScalar(src_rect.fBottom) };

  // We're guaranteed to have a mapped canvas since we mapped it in Init().
  skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas();

  // We want to replace the contents of the bitmap rather than blend.
  SkPaint paint;
  paint.setXfermodeMode(SkXfermode::kSrc_Mode);
  backing_canvas->drawBitmapRect(new_image_bitmap,
                                 &src_rect, dest_rect, &paint);

  // TODO(brettw) implement invalidate and callbacks!

  // Cause the updated part of the screen to be repainted. This will happen
  // asynchronously.
  /*
  gfx::Rect dest_gfx_rect(dirty->left, dirty->top,
                          dirty->right - dirty->left,
                          dirty->bottom - dirty->top);

  plugin_delegate_->instance()->webplugin()->InvalidateRect(dest_gfx_rect);

  // Save the callback to execute later. See |unpainted_flush_callbacks_| in
  // the header file.
  if (callback) {
    unpainted_flush_callbacks_.push_back(
        FlushCallbackData(callback, id, context, user_data));
  }
*/
}

void DeviceContext2D::Paint(WebKit::WebCanvas* canvas,
                            const gfx::Rect& plugin_rect,
                            const gfx::Rect& paint_rect) {
  // We're guaranteed to have a mapped canvas since we mapped it in Init().
  const SkBitmap& backing_bitmap = image_data_->GetMappedBitmap();

#if defined(OS_MACOSX)
  SkAutoLockPixels lock(backing_bitmap);

  scoped_cftyperef<CGDataProviderRef> data_provider(
      CGDataProviderCreateWithData(
          NULL, backing_bitmap.getAddr32(0, 0),
          backing_bitmap.rowBytes() * backing_bitmap.height(), NULL));
  scoped_cftyperef<CGImageRef> image(
      CGImageCreate(
          backing_bitmap.width(), backing_bitmap.height(),
          8, 32, backing_bitmap.rowBytes(),
          mac_util::GetSystemColorSpace(),
          kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
          data_provider, NULL, false, kCGRenderingIntentDefault));

  // Flip the transform
  CGContextSaveGState(canvas);
  float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas));
  CGContextTranslateCTM(canvas, 0, window_height);
  CGContextScaleCTM(canvas, 1.0, -1.0);

  CGRect bounds;
  bounds.origin.x = plugin_rect.origin().x();
  bounds.origin.y = window_height - plugin_rect.origin().y() -
      backing_bitmap.height();
  bounds.size.width = backing_bitmap.width();
  bounds.size.height = backing_bitmap.height();

  CGContextDrawImage(canvas, bounds, image);
  CGContextRestoreGState(canvas);
#else
  gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
  canvas->drawBitmap(backing_bitmap,
                     SkIntToScalar(plugin_rect.origin().x()),
                     SkIntToScalar(plugin_rect.origin().y()));
#endif
}

}  // namespace pepper
<commit_msg>Update NULL rect handling. I updated the API but forgot to change the Chrome side, resulting in a crash when you try to paint the entire plugin.<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 "webkit/glue/plugins/pepper_device_context_2d.h"

#include "base/logging.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "third_party/ppapi/c/ppb_device_context_2d.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"

#if defined(OS_MACOSX)
#include "base/mac_util.h"
#include "base/scoped_cftyperef.h"
#endif

namespace pepper {

namespace {

PP_Resource Create(PP_Module module_id, int32_t width, int32_t height) {
  PluginModule* module = PluginModule::FromPPModule(module_id);
  if (!module)
    return NullPPResource();

  scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module));
  if (!context->Init(width, height))
    return NullPPResource();
  context->AddRef();  // AddRef for the caller.
  return context->GetResource();
}

void PaintImageData(PP_Resource device_context,
                    PP_Resource image,
                    int32_t x, int32_t y,
                    const PP_Rect* dirty,
                    uint32_t dirty_rect_count,
                    PPB_DeviceContext2D_PaintCallback callback,
                    void* callback_data) {
  scoped_refptr<Resource> device_resource =
      ResourceTracker::Get()->GetResource(device_context);
  if (!device_resource.get())
    return;
  DeviceContext2D* context = device_resource->AsDeviceContext2D();
  if (!context)
    return;
  context->PaintImageData(image, x, y, dirty, dirty_rect_count,
                          callback, callback_data);
}

const PPB_DeviceContext2D ppb_devicecontext2d = {
  &Create,
  &PaintImageData,
};

}  // namespace

DeviceContext2D::DeviceContext2D(PluginModule* module) : Resource(module) {
}

DeviceContext2D::~DeviceContext2D() {
}

// static
const PPB_DeviceContext2D* DeviceContext2D::GetInterface() {
  return &ppb_devicecontext2d;
}

bool DeviceContext2D::Init(int width, int height) {
  image_data_.reset(new ImageData(module()));
  if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height) ||
      !image_data_->Map()) {
    image_data_.reset();
    return false;
  }

  return true;
}

void DeviceContext2D::PaintImageData(PP_Resource image,
                                     int32_t x, int32_t y,
                                     const PP_Rect* dirty,
                                     uint32_t dirty_rect_count,
                                     PPB_DeviceContext2D_PaintCallback callback,
                                     void* callback_data) {
  scoped_refptr<Resource> image_resource =
      ResourceTracker::Get()->GetResource(image);
  if (!image_resource.get())
    return;
  ImageData* new_image_data = image_resource->AsImageData();
  if (!new_image_data)
    return;

  const SkBitmap& new_image_bitmap = new_image_data->GetMappedBitmap();

  // TODO(brettw) handle multiple dirty rects.
  DCHECK(dirty_rect_count <= 1);

  // Draw the bitmap to the backing store.
  SkIRect src_rect;
  if (dirty_rect_count == 0 || !dirty) {
    // Default to the entire bitmap.
    src_rect.fLeft = 0;
    src_rect.fTop = 0;
    src_rect.fRight = new_image_bitmap.width();
    src_rect.fBottom = new_image_bitmap.height();
  } else {
    src_rect.fLeft = dirty->point.x;
    src_rect.fTop = dirty->point.y;
    src_rect.fRight = dirty->point.x + dirty->size.width;
    src_rect.fBottom = dirty->point.y + dirty->size.height;
  }
  SkRect dest_rect = { SkIntToScalar(src_rect.fLeft),
                       SkIntToScalar(src_rect.fTop),
                       SkIntToScalar(src_rect.fRight),
                       SkIntToScalar(src_rect.fBottom) };

  // We're guaranteed to have a mapped canvas since we mapped it in Init().
  skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas();

  // We want to replace the contents of the bitmap rather than blend.
  SkPaint paint;
  paint.setXfermodeMode(SkXfermode::kSrc_Mode);
  backing_canvas->drawBitmapRect(new_image_bitmap,
                                 &src_rect, dest_rect, &paint);

  // TODO(brettw) implement invalidate and callbacks!

  // Cause the updated part of the screen to be repainted. This will happen
  // asynchronously.
  /*
  gfx::Rect dest_gfx_rect(dirty->left, dirty->top,
                          dirty->right - dirty->left,
                          dirty->bottom - dirty->top);

  plugin_delegate_->instance()->webplugin()->InvalidateRect(dest_gfx_rect);

  // Save the callback to execute later. See |unpainted_flush_callbacks_| in
  // the header file.
  if (callback) {
    unpainted_flush_callbacks_.push_back(
        FlushCallbackData(callback, id, context, user_data));
  }
*/
}

void DeviceContext2D::Paint(WebKit::WebCanvas* canvas,
                            const gfx::Rect& plugin_rect,
                            const gfx::Rect& paint_rect) {
  // We're guaranteed to have a mapped canvas since we mapped it in Init().
  const SkBitmap& backing_bitmap = image_data_->GetMappedBitmap();

#if defined(OS_MACOSX)
  SkAutoLockPixels lock(backing_bitmap);

  scoped_cftyperef<CGDataProviderRef> data_provider(
      CGDataProviderCreateWithData(
          NULL, backing_bitmap.getAddr32(0, 0),
          backing_bitmap.rowBytes() * backing_bitmap.height(), NULL));
  scoped_cftyperef<CGImageRef> image(
      CGImageCreate(
          backing_bitmap.width(), backing_bitmap.height(),
          8, 32, backing_bitmap.rowBytes(),
          mac_util::GetSystemColorSpace(),
          kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
          data_provider, NULL, false, kCGRenderingIntentDefault));

  // Flip the transform
  CGContextSaveGState(canvas);
  float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas));
  CGContextTranslateCTM(canvas, 0, window_height);
  CGContextScaleCTM(canvas, 1.0, -1.0);

  CGRect bounds;
  bounds.origin.x = plugin_rect.origin().x();
  bounds.origin.y = window_height - plugin_rect.origin().y() -
      backing_bitmap.height();
  bounds.size.width = backing_bitmap.width();
  bounds.size.height = backing_bitmap.height();

  CGContextDrawImage(canvas, bounds, image);
  CGContextRestoreGState(canvas);
#else
  gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
  canvas->drawBitmap(backing_bitmap,
                     SkIntToScalar(plugin_rect.origin().x()),
                     SkIntToScalar(plugin_rect.origin().y()));
#endif
}

}  // namespace pepper
<|endoftext|>