<commit_before>
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.

For the latest info, see http://gimpact.sourceforge.net/

Copyright (c) 2006 Francisco Leon. C.C. 80087371.
email: projectileman@yahoo.com

 This library is free software; you can redistribute it and/or
 modify it under the terms of EITHER:
   (1) 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. The text of the GNU Lesser
       General Public License is included with this library in the
       file GIMPACT-LICENSE-LGPL.TXT.
   (2) The BSD-style license that is included with this library in
       the file GIMPACT-LICENSE-BSD.TXT.

 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 files
 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.

-----------------------------------------------------------------------------
*/

#include "GIMPACT/gim_trimesh.h"

//! Utility function for find the closest point between a segment and a triangle
/*!

\param triangle
\param s1
\param s2
\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance

\post The contacts array is not set to 0. It adds aditional contacts
*/
void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts)
{
    vec3f segment_points[4] = {{0}};
    vec3f closest_points[2] = {{0}};
    GUINT intersection_type, out_edge= 10;
    GREAL dis, dis_temp,perpend;
    vec4f sdiff;

    dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1);
    dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2);

    if(dis<=0.0f && dis_temp<=0.0f) return;

    VEC_DIFF(sdiff,s2,s1);
    perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]);

    if(!IS_ZERO(perpend)) // Not perpendicular
    {
        if(dis<dis_temp)
        {
            VEC_COPY(closest_points[0],s1);
        }
        else
        {
            dis = dis_temp;
            VEC_COPY(closest_points[0],s2);
        }

        //Testing segment vertices over triangle
        if(dis>=0.0f && dis_temp>=0.0f)
        {
            POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge);

            if(out_edge==0)//Point over face
            {
                GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
                return;
            }
        }
        else
        {

            PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]);

            POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge);

            if(out_edge==0)//Point over face
            {
                GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
                return;
            }
        }

    }
    else // Perpendicular Face
    {
        //out_edge=10
        //Clip segment by triangle
    //    Edge1
        PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type);
        if(intersection_type==0||intersection_type==1)
        {
            out_edge = 0;
            VEC_COPY(closest_points[0],segment_points[0]);
        }
        else
        {
            //Edge2
            PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type);
            if(intersection_type==0||intersection_type==1)
            {
                out_edge = 1;
                VEC_COPY(closest_points[0],segment_points[3]);
            }
            else
            {
                //Edge3
                PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type);
                if(intersection_type==0||intersection_type==1)
                {
                    out_edge = 2;
                }
            }
        }
        //POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2
        if(out_edge>2) // Over triangle
        {
            dis = VEC_DOT(closest_points[0],triangle->m_planes.m_planes[0]);
            GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
            GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
            return;
        }
    }

    //Find closest edges
    out_edge = 10;
    dis = G_REAL_INFINITY;
    GUINT i;
    for(i=0;i<3;i++)
    {
        SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]);
        VEC_DIFF(sdiff,segment_points[0],segment_points[1]);
        dis_temp = VEC_DOT(sdiff,sdiff);
        if(dis_temp< dis)
        {
            dis = dis_temp;
            out_edge = i;
            VEC_COPY(closest_points[0],segment_points[0]);
            VEC_COPY(closest_points[1],sdiff);//normal
        }
    }
    if(out_edge>2) return ;// ???? ASSERT this please

    if(IS_ZERO(dis))
    {
        //Set face plane
        GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0);

    }
    else
    {
        GIM_SQRT(dis,dis);
        VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal
        GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0);
    }
}

//! Utility function for find the closest point between a capsule and a triangle
/*!

\param triangle
\param capsule
\param contacts Contains the closest points on the capsule, and the normal points to triangle

\post The contacts array is not set to 0. It adds aditional contacts
*/
int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
    GUINT old_contact_size = contacts->m_size;
    gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts);
    GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts));
    pcontact+= old_contact_size;

    if(pcontact->m_depth > capsule->m_radius)
    {
        contacts->m_size = old_contact_size;
        return 0;
    }

    vec3f vec;
    while(old_contact_size<contacts->m_size)
    {
        //Scale the normal for pointing to triangle
        VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal);
        //Fix the contact point
        VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal);
        VEC_SUM(pcontact->m_point,vec,pcontact->m_point);
        //Fix the depth
        pcontact->m_depth = capsule->m_radius - pcontact->m_depth;

        pcontact++;
        old_contact_size++;
    }

    return 1;
}

//! Trimesh Capsule collision
/*!
Find the closest primitive collided by the ray
\param trimesh
\param capsule
\param contact
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
    contacts->m_size = 0;

    aabb3f test_aabb;
    CALC_CAPSULE_AABB((*capsule),test_aabb);

	GDYNAMIC_ARRAY collision_result;
	GIM_CREATE_BOXQUERY_LIST(collision_result);

	gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);

	if(collision_result.m_size==0)
	{
	    GIM_DYNARRAY_DESTROY(collision_result);
	}

	//collide triangles
	//Locks trimesh
	gim_trimesh_locks_work_data(trimesh);
	 //dummy contacts
    GDYNAMIC_ARRAY dummycontacts;
    GIM_CREATE_CONTACT_LIST(dummycontacts);

	int cresult;
	unsigned int i;
	GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
	GIM_TRIANGLE_DATA tri_data;
	GUINT old_contact_size;
	GIM_CONTACT * pcontact;

	for(i=0;i<collision_result.m_size;i++)
	{
	    old_contact_size = dummycontacts.m_size;
		gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
		cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts);
		if(cresult!=0)
		{
		    pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts);
            pcontact+= old_contact_size;
		    while(old_contact_size<dummycontacts.m_size)
            {
                pcontact->m_handle1 = trimesh;
                pcontact->m_handle2 = capsule;
                pcontact->m_feature1 = boxesresult[i];
                pcontact->m_feature2 = 0;
                pcontact++;
                old_contact_size++;
            }
		}
	}
	///unlocks
	gim_trimesh_unlocks_work_data(trimesh);
	///Destroy box result
	GIM_DYNARRAY_DESTROY(collision_result);

	 //merge contacts
    gim_merge_contacts(&dummycontacts,contacts);

    //Destroy dummy
    GIM_DYNARRAY_DESTROY(dummycontacts);
}
<commit_msg>Fixed: Access to inexistent contact item fixed<commit_after>
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.

For the latest info, see http://gimpact.sourceforge.net/

Copyright (c) 2006 Francisco Leon. C.C. 80087371.
email: projectileman@yahoo.com

 This library is free software; you can redistribute it and/or
 modify it under the terms of EITHER:
   (1) 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. The text of the GNU Lesser
       General Public License is included with this library in the
       file GIMPACT-LICENSE-LGPL.TXT.
   (2) The BSD-style license that is included with this library in
       the file GIMPACT-LICENSE-BSD.TXT.

 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 files
 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.

-----------------------------------------------------------------------------
*/

#include "GIMPACT/gim_trimesh.h"

//! Utility function for find the closest point between a segment and a triangle
/*!

\param triangle
\param s1
\param s2
\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance

\post The contacts array is not set to 0. It adds aditional contacts
*/
void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts)
{
    vec3f segment_points[4] = {{0}};
    vec3f closest_points[2] = {{0}};
    GUINT intersection_type, out_edge= 10;
    GREAL dis, dis_temp,perpend;
    vec4f sdiff;

    dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1);
    dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2);

    if(dis<=0.0f && dis_temp<=0.0f) return;

    VEC_DIFF(sdiff,s2,s1);
    perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]);

    if(!IS_ZERO(perpend)) // Not perpendicular
    {
        if(dis<dis_temp)
        {
            VEC_COPY(closest_points[0],s1);
        }
        else
        {
            dis = dis_temp;
            VEC_COPY(closest_points[0],s2);
        }

        //Testing segment vertices over triangle
        if(dis>=0.0f && dis_temp>=0.0f)
        {
            POINT_IN_HULL(closest_points[0],(&triangle->m_planes.m_planes[1]),3,out_edge);

            if(out_edge==0)//Point over face
            {
                GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
                return;
            }
        }
        else
        {

            PLANE_CLIP_SEGMENT(s1,s2,triangle->m_planes.m_planes[0],closest_points[1]);

            POINT_IN_HULL(closest_points[1],(&triangle->m_planes.m_planes[1]),3,out_edge);

            if(out_edge==0)//Point over face
            {
                GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
                return;
            }
        }

    }
    else // Perpendicular Face
    {
        //out_edge=10
        //Clip segment by triangle
    //    Edge1
        PLANE_CLIP_SEGMENT_CLOSEST(s1,s2,triangle->m_planes.m_planes[1],segment_points[0],segment_points[1],intersection_type);
        if(intersection_type==0||intersection_type==1)
        {
            out_edge = 0;
            VEC_COPY(closest_points[0],segment_points[0]);
        }
        else
        {
            //Edge2
            PLANE_CLIP_SEGMENT_CLOSEST(segment_points[0],segment_points[1],triangle->m_planes.m_planes[2],segment_points[2],segment_points[3],intersection_type);
            if(intersection_type==0||intersection_type==1)
            {
                out_edge = 1;
                VEC_COPY(closest_points[0],segment_points[3]);
            }
            else
            {
                //Edge3
                PLANE_CLIP_SEGMENT_CLOSEST(segment_points[2],segment_points[3],triangle->m_planes.m_planes[3],closest_points[0],closest_points[1],intersection_type);
                if(intersection_type==0||intersection_type==1)
                {
                    out_edge = 2;
                }
            }
        }
        //POST closest_points[0] and closest_points[1] are inside the triangle, if out_edge>2
        if(out_edge>2) // Over triangle
        {
            dis = VEC_DOT(closest_points[0],triangle->m_planes.m_planes[0]);
            GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
            GIM_PUSH_CONTACT((*contacts),closest_points[1] ,triangle->m_planes.m_planes[0] ,dis,0, 0, 0,0);
            return;
        }
    }

    //Find closest edges
    out_edge = 10;
    dis = G_REAL_INFINITY;
    GUINT i;
    for(i=0;i<3;i++)
    {
        SEGMENT_COLLISION(s1,s2,triangle->m_vertices[i],triangle->m_vertices[(i+1)%3],segment_points[0],segment_points[1]);
        VEC_DIFF(sdiff,segment_points[0],segment_points[1]);
        dis_temp = VEC_DOT(sdiff,sdiff);
        if(dis_temp< dis)
        {
            dis = dis_temp;
            out_edge = i;
            VEC_COPY(closest_points[0],segment_points[0]);
            VEC_COPY(closest_points[1],sdiff);//normal
        }
    }
    if(out_edge>2) return ;// ???? ASSERT this please

    if(IS_ZERO(dis))
    {
        //Set face plane
        GIM_PUSH_CONTACT((*contacts),closest_points[0] ,triangle->m_planes.m_planes[0] ,0.0f,0, 0, 0,0);

    }
    else
    {
        GIM_SQRT(dis,dis);
        VEC_SCALE(closest_points[1],(1.0f/dis),closest_points[1]);//normal
        GIM_PUSH_CONTACT((*contacts),closest_points[0] ,closest_points[1],dis,0, 0, 0,0);
    }
}

//! Utility function for find the closest point between a capsule and a triangle
/*!

\param triangle
\param capsule
\param contacts Contains the closest points on the capsule, and the normal points to triangle

\post The contacts array is not set to 0. It adds aditional contacts
*/
int gim_triangle_capsule_collision(GIM_TRIANGLE_DATA * triangle, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
    GUINT old_contact_size = contacts->m_size;
    gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts);

    if (contacts->m_size == old_contact_size)
    {
        return 0;
    }

	GIM_CONTACT * pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,(*contacts));
    pcontact+= old_contact_size;

    if(pcontact->m_depth > capsule->m_radius)
    {
        contacts->m_size = old_contact_size;
        return 0;
    }

    vec3f vec;
    while(old_contact_size<contacts->m_size)
    {
        //Scale the normal for pointing to triangle
        VEC_SCALE(pcontact->m_normal,-1.0f,pcontact->m_normal);
        //Fix the contact point
        VEC_SCALE(vec,capsule->m_radius,pcontact->m_normal);
        VEC_SUM(pcontact->m_point,vec,pcontact->m_point);
        //Fix the depth
        pcontact->m_depth = capsule->m_radius - pcontact->m_depth;

        pcontact++;
        old_contact_size++;
    }

    return 1;
}

//! Trimesh Capsule collision
/*!
Find the closest primitive collided by the ray
\param trimesh
\param capsule
\param contact
\param contacts A GIM_CONTACT array. Must be initialized
*/
void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts)
{
    contacts->m_size = 0;

    aabb3f test_aabb;
    CALC_CAPSULE_AABB((*capsule),test_aabb);

	GDYNAMIC_ARRAY collision_result;
	GIM_CREATE_BOXQUERY_LIST(collision_result);

	gim_aabbset_box_collision(&test_aabb, &trimesh->m_aabbset , &collision_result);

	if(collision_result.m_size==0)
	{
	    GIM_DYNARRAY_DESTROY(collision_result);
	}

	//collide triangles
	//Locks trimesh
	gim_trimesh_locks_work_data(trimesh);
	 //dummy contacts
    GDYNAMIC_ARRAY dummycontacts;
    GIM_CREATE_CONTACT_LIST(dummycontacts);

	int cresult;
	unsigned int i;
	GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result);
	GIM_TRIANGLE_DATA tri_data;
	GUINT old_contact_size;
	GIM_CONTACT * pcontact;

	for(i=0;i<collision_result.m_size;i++)
	{
	    old_contact_size = dummycontacts.m_size;
		gim_trimesh_get_triangle_data(trimesh,boxesresult[i],&tri_data);
		cresult = gim_triangle_capsule_collision(&tri_data, capsule, &dummycontacts);
		if(cresult!=0)
		{
		    pcontact = GIM_DYNARRAY_POINTER(GIM_CONTACT ,dummycontacts);
            pcontact+= old_contact_size;
		    while(old_contact_size<dummycontacts.m_size)
            {
                pcontact->m_handle1 = trimesh;
                pcontact->m_handle2 = capsule;
                pcontact->m_feature1 = boxesresult[i];
                pcontact->m_feature2 = 0;
                pcontact++;
                old_contact_size++;
            }
		}
	}
	///unlocks
	gim_trimesh_unlocks_work_data(trimesh);
	///Destroy box result
	GIM_DYNARRAY_DESTROY(collision_result);

	 //merge contacts
    gim_merge_contacts(&dummycontacts,contacts);

    //Destroy dummy
    GIM_DYNARRAY_DESTROY(dummycontacts);
}
<|endoftext|>


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

#include "chrome/browser/bookmarks/bookmark_drag_data.h"

#include "app/clipboard/scoped_clipboard_writer.h"
#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/browser/browser_process.h"
#include "net/base/escape.h"

const char* BookmarkDragData::kClipboardFormatString =
    "chromium/x-bookmark-entries";

BookmarkDragData::Element::Element(const BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->GetURL()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->GetChildCount(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

void BookmarkDragData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteWString(title);
  pickle->WriteInt64(id_);
  if (!is_url) {
    pickle->WriteSize(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkDragData::Element::ReadFromPickle(Pickle* pickle,
                                               void** iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadWString(iterator, &title) ||
      !pickle->ReadInt64(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    size_t children_count;
    if (!pickle->ReadSize(iterator, &children_count))
      return false;
    children.resize(children_count);
    for (std::vector<Element>::iterator i = children.begin();
         i != children.end(); ++i) {
      if (!i->ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

#if defined(TOOLKIT_VIEWS)
// static
OSExchangeData::CustomFormat BookmarkDragData::GetBookmarkCustomFormat() {
  static OSExchangeData::CustomFormat format;
  static bool format_valid = false;

  if (!format_valid) {
    format_valid = true;
    format = OSExchangeData::RegisterCustomFormat(
        BookmarkDragData::kClipboardFormatString);
  }
  return format;
}
#endif

BookmarkDragData::BookmarkDragData(const BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkDragData::BookmarkDragData(
    const std::vector<const BookmarkNode*>& nodes) {
  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));
}

#if !defined(OS_MACOSX)
void BookmarkDragData::WriteToClipboard(Profile* profile) const {
  ScopedClipboardWriter scw(g_browser_process->clipboard());

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    string16 title = WideToUTF16Hack(elements[0].title);
    std::string url = elements[0].url.spec();

    scw.WriteBookmark(title, url);
    scw.WriteHyperlink(EscapeForHTML(UTF16ToUTF8(title)), url);
  }

  Pickle pickle;
  WriteToPickle(profile, &pickle);
  scw.WritePickledData(pickle, kClipboardFormatString);
}

bool BookmarkDragData::ReadFromClipboard() {
  std::string data;
  Clipboard* clipboard = g_browser_process->clipboard();
  clipboard->ReadData(kClipboardFormatString, &data);

  if (!data.empty()) {
    Pickle pickle(data.data(), data.size());
    if (ReadFromPickle(&pickle))
      return true;
  }

  string16 title;
  std::string url;
  clipboard->ReadBookmark(&title, &url);
  if (!url.empty()) {
    Element element;
    element.is_url = true;
    element.url = GURL(url);
    element.title = UTF16ToWideHack(title);

    elements.clear();
    elements.push_back(element);
    return true;
  }

  return false;
}
#endif  // !defined(OS_MACOSX)

#if defined(TOOLKIT_VIEWS)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(ASCIIToWide(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(GetBookmarkCustomFormat(), data_pickle);
}

bool BookmarkDragData::Read(const OSExchangeData& data) {
  elements.clear();

  profile_path_.clear();

  if (data.HasCustomFormat(GetBookmarkCustomFormat())) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(GetBookmarkCustomFormat(), &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    if (data.GetURLAndTitle(&element.url, &element.title) &&
        element.url.is_valid()) {
      element.is_url = true;
      elements.push_back(element);
    }
  }

  return is_valid();
}
#endif

void BookmarkDragData::WriteToPickle(Profile* profile, Pickle* pickle) const {
#if defined(WCHAR_T_IS_UTF16)
  pickle->WriteWString(
      profile ? profile->GetPath().ToWStringHack() : std::wstring());
#elif defined(WCHAR_T_IS_UTF32)
  pickle->WriteString(
      profile ? profile->GetPath().value() : std::string());
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
#endif

  pickle->WriteSize(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkDragData::ReadFromPickle(Pickle* pickle) {
  void* data_iterator = NULL;
  size_t element_count;
#if defined(WCHAR_T_IS_UTF16)
  if (pickle->ReadWString(&data_iterator, &profile_path_) &&
#elif defined(WCHAR_T_IS_UTF32)
  if (pickle->ReadString(&data_iterator, &profile_path_) &&
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
  if (false &&
#endif
      pickle->ReadSize(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (size_t i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<const BookmarkNode*> BookmarkDragData::GetNodes(
    Profile* profile) const {
  std::vector<const BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    const BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

const BookmarkNode* BookmarkDragData::GetFirstNode(Profile* profile) const {
  std::vector<const BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

bool BookmarkDragData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return (!profile_path_.empty() &&
#if defined(WCHAR_T_IS_UTF16)
      profile->GetPath().ToWStringHack() == profile_path_);
#elif defined(WCHAR_T_IS_UTF32)
      profile->GetPath().value() == profile_path_);
#endif
}
<commit_msg>Lands http://codereview.chromium.org/527033 for bryenug:<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/bookmarks/bookmark_drag_data.h"

#include "app/clipboard/scoped_clipboard_writer.h"
#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/browser/browser_process.h"
#include "net/base/escape.h"

const char* BookmarkDragData::kClipboardFormatString =
    "chromium/x-bookmark-entries";

BookmarkDragData::Element::Element(const BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->GetURL()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->GetChildCount(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

void BookmarkDragData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteWString(title);
  pickle->WriteInt64(id_);
  if (!is_url) {
    pickle->WriteSize(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkDragData::Element::ReadFromPickle(Pickle* pickle,
                                               void** iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadWString(iterator, &title) ||
      !pickle->ReadInt64(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    size_t children_count;
    if (!pickle->ReadSize(iterator, &children_count))
      return false;
    children.resize(children_count);
    for (std::vector<Element>::iterator i = children.begin();
         i != children.end(); ++i) {
      if (!i->ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

#if defined(TOOLKIT_VIEWS)
// static
OSExchangeData::CustomFormat BookmarkDragData::GetBookmarkCustomFormat() {
  static OSExchangeData::CustomFormat format;
  static bool format_valid = false;

  if (!format_valid) {
    format_valid = true;
    format = OSExchangeData::RegisterCustomFormat(
        BookmarkDragData::kClipboardFormatString);
  }
  return format;
}
#endif

BookmarkDragData::BookmarkDragData(const BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkDragData::BookmarkDragData(
    const std::vector<const BookmarkNode*>& nodes) {
  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));
}

#if !defined(OS_MACOSX)
void BookmarkDragData::WriteToClipboard(Profile* profile) const {
  ScopedClipboardWriter scw(g_browser_process->clipboard());

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    string16 title = WideToUTF16Hack(elements[0].title);
    std::string url = elements[0].url.spec();

    scw.WriteBookmark(title, url);
    scw.WriteHyperlink(EscapeForHTML(UTF16ToUTF8(title)), url);

    // Also write the URL to the clipboard as text so that it can be pasted
    // into text fields
    scw.WriteURL(UTF8ToUTF16(url));
  }

  Pickle pickle;
  WriteToPickle(profile, &pickle);
  scw.WritePickledData(pickle, kClipboardFormatString);
}

bool BookmarkDragData::ReadFromClipboard() {
  std::string data;
  Clipboard* clipboard = g_browser_process->clipboard();
  clipboard->ReadData(kClipboardFormatString, &data);

  if (!data.empty()) {
    Pickle pickle(data.data(), data.size());
    if (ReadFromPickle(&pickle))
      return true;
  }

  string16 title;
  std::string url;
  clipboard->ReadBookmark(&title, &url);
  if (!url.empty()) {
    Element element;
    element.is_url = true;
    element.url = GURL(url);
    element.title = UTF16ToWideHack(title);

    elements.clear();
    elements.push_back(element);
    return true;
  }

  return false;
}
#endif  // !defined(OS_MACOSX)

#if defined(TOOLKIT_VIEWS)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(ASCIIToWide(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(GetBookmarkCustomFormat(), data_pickle);
}

bool BookmarkDragData::Read(const OSExchangeData& data) {
  elements.clear();

  profile_path_.clear();

  if (data.HasCustomFormat(GetBookmarkCustomFormat())) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(GetBookmarkCustomFormat(), &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    if (data.GetURLAndTitle(&element.url, &element.title) &&
        element.url.is_valid()) {
      element.is_url = true;
      elements.push_back(element);
    }
  }

  return is_valid();
}
#endif

void BookmarkDragData::WriteToPickle(Profile* profile, Pickle* pickle) const {
#if defined(WCHAR_T_IS_UTF16)
  pickle->WriteWString(
      profile ? profile->GetPath().ToWStringHack() : std::wstring());
#elif defined(WCHAR_T_IS_UTF32)
  pickle->WriteString(
      profile ? profile->GetPath().value() : std::string());
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
#endif

  pickle->WriteSize(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkDragData::ReadFromPickle(Pickle* pickle) {
  void* data_iterator = NULL;
  size_t element_count;
#if defined(WCHAR_T_IS_UTF16)
  if (pickle->ReadWString(&data_iterator, &profile_path_) &&
#elif defined(WCHAR_T_IS_UTF32)
  if (pickle->ReadString(&data_iterator, &profile_path_) &&
#else
  NOTIMPLEMENTED() << "Impossible encoding situation!";
  if (false &&
#endif
      pickle->ReadSize(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (size_t i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<const BookmarkNode*> BookmarkDragData::GetNodes(
    Profile* profile) const {
  std::vector<const BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    const BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

const BookmarkNode* BookmarkDragData::GetFirstNode(Profile* profile) const {
  std::vector<const BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

bool BookmarkDragData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return (!profile_path_.empty() &&
#if defined(WCHAR_T_IS_UTF16)
      profile->GetPath().ToWStringHack() == profile_path_);
#elif defined(WCHAR_T_IS_UTF32)
      profile->GetPath().value() == profile_path_);
#endif
}
<|endoftext|>


<commit_before>#pragma once

#include "Geometry2D.hpp"

class Shader;
class ShaderProgram;

namespace Geometry {
    /// A renderable 2D rectangle.
    class Rectangle : public Geometry2D {
        public:
            /// Constructor.
            Rectangle();

            /// Destructor.
            ~Rectangle() override;

            /// Get all the vertices.
            /**
             * @return Array of vertices
             */
            Vertex* GetVertices() const override;

            /// Get the number of vertices.
            /**
             * @return The number of vertices
             */
            unsigned int GetVertexCount() const override;

            /// Get all the vertex indices.
            /**
             * @return Array of vertex indices
             */
            unsigned int* GetIndices() const override;

            /// Get the number of indicies.
            /**
             * @return The number of vertex indices.
             */
            unsigned int GetIndexCount() const override;

            /// Render the rectangle with a solid color.
            /**
             * @param position Position on the screen in pixels.
             * @param size Size in pixels.
             * @param color Color.
             * @param screenSize Size of the screen in pixels.
             */
            void Render(const glm::vec2& position, const glm::vec2& size, const glm::vec3& color, const glm::vec2& screenSize) const;

        private:
            Vertex *vertexData = nullptr;
            unsigned int vertexNr = 0;

            unsigned int* indexData = nullptr;
            unsigned int indexNr = 0;

            // Shaders
            Shader* vertexShader;
            Shader* fragmentShader;
            ShaderProgram* shaderProgram;

    };
}
<commit_msg>Change Rectangle from override to final.<commit_after>#pragma once

#include "Geometry2D.hpp"

class Shader;
class ShaderProgram;

namespace Geometry {
    /// A renderable 2D rectangle.
    class Rectangle : public Geometry2D {
        public:
            /// Constructor.
            Rectangle();

            /// Destructor.
            ~Rectangle() final;

            /// Get all the vertices.
            /**
             * @return Array of vertices
             */
            Vertex* GetVertices() const final;

            /// Get the number of vertices.
            /**
             * @return The number of vertices
             */
            unsigned int GetVertexCount() const final;

            /// Get all the vertex indices.
            /**
             * @return Array of vertex indices
             */
            unsigned int* GetIndices() const final;

            /// Get the number of indicies.
            /**
             * @return The number of vertex indices.
             */
            unsigned int GetIndexCount() const final;

            /// Render the rectangle with a solid color.
            /**
             * @param position Position on the screen in pixels.
             * @param size Size in pixels.
             * @param color Color.
             * @param screenSize Size of the screen in pixels.
             */
            void Render(const glm::vec2& position, const glm::vec2& size, const glm::vec3& color, const glm::vec2& screenSize) const;

        private:
            Vertex *vertexData = nullptr;
            unsigned int vertexNr = 0;

            unsigned int* indexData = nullptr;
            unsigned int indexNr = 0;

            // Shaders
            Shader* vertexShader;
            Shader* fragmentShader;
            ShaderProgram* shaderProgram;

    };
}
<|endoftext|>


<commit_before>/**
 * @file    Backup_test.cpp
 * @ingroup tests
 * @brief   Test of a SQLite Backup.
 *
 * Copyright (c) 2015-2015 Shibao HONG (shibaohong@outlook.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <SQLiteCpp/Backup.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>

#include <gtest/gtest.h>

#include <cstdio>

TEST(Backup, executeStep) {
    remove("backup_test.db3");
    remove("backup_test.db3.backup");
    SQLite::Database srcDB("backup_test.db3", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
    SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    SQLite::Backup backup(destDB, srcDB);
    const int res = backup.executeStep();
    ASSERT_EQ(res, SQLITE_DONE);
    SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
    ASSERT_TRUE(query.executeStep());
    EXPECT_EQ(1, query.getColumn(0).getInt());
    EXPECT_STREQ("first", query.getColumn(1));
    ASSERT_TRUE(query.executeStep());
    EXPECT_EQ(2, query.getColumn(0).getInt());
    EXPECT_STREQ("second", query.getColumn(1));
}
<commit_msg>Add executeStepException testcase<commit_after>/**
 * @file    Backup_test.cpp
 * @ingroup tests
 * @brief   Test of a SQLite Backup.
 *
 * Copyright (c) 2015-2015 Shibao HONG (shibaohong@outlook.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <SQLiteCpp/Backup.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Exception.h>

#include <gtest/gtest.h>

#include <cstdio>

TEST(Backup, executeStep) {
    remove("backup_test.db3");
    remove("backup_test.db3.backup");
    SQLite::Database srcDB("backup_test.db3", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));

    SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    SQLite::Backup backup(destDB, srcDB);
    const int res = backup.executeStep();
    ASSERT_EQ(res, SQLITE_DONE);

    SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
    ASSERT_TRUE(query.executeStep());
    EXPECT_EQ(1, query.getColumn(0).getInt());
    EXPECT_STREQ("first", query.getColumn(1));
    ASSERT_TRUE(query.executeStep());
    EXPECT_EQ(2, query.getColumn(0).getInt());
    EXPECT_STREQ("second", query.getColumn(1));
    remove("backup_test.db3");
    remove("backup_test.db3.backup");
}

TEST(Backup, executeStepException) {
    remove("backup_test.db3");
    remove("backup_test.db3.backup");
    SQLite::Database srcDB("backup_test.db3", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
    ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
    {
        SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
        (void)destDB;
    }
    {
        SQLite::Database destDB("backup_test.db3.backup", SQLITE_OPEN_READONLY);
        SQLite::Backup backup(destDB, srcDB);
        EXPECT_THROW(backup.executeStep(), SQLite::Exception);
    }
    remove("backup_test.db3");
    remove("backup_test.db3.backup");
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Visualization Toolkit
Module:    vtkMultiGroupDataExtractDataSets.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMultiGroupDataExtractDataSets.h"

#include "vtkCompositeDataPipeline.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataSet.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkMultiGroupDataInformation.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkUniformGrid.h"

#include <vtkstd/list>

vtkCxxRevisionMacro(vtkMultiGroupDataExtractDataSets, "1.4");
vtkStandardNewMacro(vtkMultiGroupDataExtractDataSets);

struct vtkMultiGroupDataExtractDataSetsInternals
{
  typedef
  vtkstd::list<vtkMultiGroupDataExtractDataSets::DataSetNode> DataSetsTypes;
  DataSetsTypes DataSets;
};

//----------------------------------------------------------------------------
vtkMultiGroupDataExtractDataSets::vtkMultiGroupDataExtractDataSets()
{
  this->Internal = new vtkMultiGroupDataExtractDataSetsInternals;
  this->MinGroup = VTK_UNSIGNED_INT_MAX;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataExtractDataSets::~vtkMultiGroupDataExtractDataSets()
{
  delete this->Internal;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::AddDataSet(
  unsigned int group, unsigned int idx)
{
  this->Internal->DataSets.push_back(DataSetNode(group, idx));
  this->MinGroup = (group < this->MinGroup) ? group : this->MinGroup;

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::ClearDataSetList()
{
  this->Internal->DataSets.clear();
  this->MinGroup = VTK_UNSIGNED_INT_MAX;
  this->Modified();
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataExtractDataSets::ComputeOutputGroups(
  unsigned int inputNumGroups)
{
  unsigned int numGroups = 0;
  vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
    this->Internal->DataSets.begin();
  for (; it != this->Internal->DataSets.end(); it++)
    {
    DataSetNode& node = *it;
    unsigned int curNumGroups = node.Group - this->MinGroup + 1;
    if (curNumGroups > numGroups && curNumGroups <= inputNumGroups)
      {
      numGroups = curNumGroups;
      }
    }
  return numGroups;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestDataObject(
  vtkInformation*,
  vtkInformationVector** inputVector ,
  vtkInformationVector* outputVector)
{
  vtkCompositeDataSet* input = vtkCompositeDataSet::GetData(inputVector[0], 0);
  vtkCompositeDataSet *output = vtkCompositeDataSet::GetData(outputVector, 0);

  if (!output || !output->IsA(input->GetClassName()))
    {
    output = input->NewInstance();
    output->SetPipelineInformation(outputVector->GetInformationObject(0));
    output->Delete();
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestInformation(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkMultiGroupDataInformation* inCompInfo =
    vtkMultiGroupDataInformation::SafeDownCast(
      inInfo->Get(vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION()));
  if (!inCompInfo)
    {
    vtkDebugMacro("Expected information not found. "
                  "Cannot provide information.");
    return 1;
    }

  unsigned int numInputGroups = inCompInfo->GetNumberOfGroups();
  unsigned int numOutputGroups = this->ComputeOutputGroups(numInputGroups);

  vtkMultiGroupDataInformation* compInfo =
    vtkMultiGroupDataInformation::New();
  if (numOutputGroups > 0)
    {
    compInfo->SetNumberOfGroups(numOutputGroups);
    vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
      this->Internal->DataSets.begin();
    for (; it != this->Internal->DataSets.end(); it++)
      {
      DataSetNode& node = *it;
      unsigned int numInputDataSets =
        inCompInfo->GetNumberOfDataSets(node.Group);
      if (node.DataSetId <= numInputDataSets)
        {
        if (node.DataSetId >= compInfo->GetNumberOfDataSets(
              node.Group - this->MinGroup))
          {
          compInfo->SetNumberOfDataSets(
            node.Group - this->MinGroup, node.DataSetId+1);

          if (inCompInfo->HasInformation(node.Group, node.DataSetId))
            {
            vtkInformation* outdInfo =
              compInfo->GetInformation(node.Group - this->MinGroup,
                                       node.DataSetId);
            vtkInformation* indInfo =
              inCompInfo->GetInformation(node.Group, node.DataSetId);
            outdInfo->Copy(indInfo);
            }
          }
        }
      }
    }

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  outInfo->Set(
    vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION(), compInfo);
  compInfo->Delete();

  return 1;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkMultiGroupDataSet *input = vtkMultiGroupDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  if (!input) {return 0;}

  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkMultiGroupDataSet *output = vtkMultiGroupDataSet::SafeDownCast(
    info->Get(vtkDataObject::DATA_OBJECT()));
  if (!output) {return 0;}

  unsigned int numInputGroups = input->GetNumberOfGroups();
  unsigned int numOutputGroups = this->ComputeOutputGroups(numInputGroups);

  if (numOutputGroups > 0)
    {
    output->SetNumberOfGroups(numOutputGroups);

    vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
      this->Internal->DataSets.begin();
    for (; it != this->Internal->DataSets.end(); it++)
      {
      DataSetNode& node = *it;
      unsigned int numInputDataSets = input->GetNumberOfDataSets(node.Group);
      if (node.DataSetId <= numInputDataSets)
        {
        if (node.DataSetId >= output->GetNumberOfDataSets(
              node.Group - this->MinGroup))
          {
          output->SetNumberOfDataSets(node.Group - this->MinGroup,
                                      node.DataSetId+1);
          }
        vtkDataObject* dObj =
          input->GetDataSet(node.Group, node.DataSetId);
        if (dObj)
          {
          vtkDataObject* copy = dObj->NewInstance();
          copy->ShallowCopy(dObj);

          // Remove blanking from output datasets.
          vtkUniformGrid* ug = vtkUniformGrid::SafeDownCast(copy);
          if (ug)
            {
            ug->SetCellVisibilityArray(0);
            }
          output->SetDataSet(node.Group - this->MinGroup, node.DataSetId, copy);
          copy->Delete();
          }
        }
      }

    vtkMultiGroupDataInformation* compInfo =
      vtkMultiGroupDataInformation::SafeDownCast(
        info->Get(vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION()));

    if (compInfo)
      {
      output->SetMultiGroupDataInformation(compInfo);
      }
    unsigned int numGroups = output->GetNumberOfGroups();

    vtkHierarchicalBoxDataSet* hbds =
      vtkHierarchicalBoxDataSet::SafeDownCast(output);
    if (hbds)
      {
      vtkHierarchicalBoxDataSet* ihbds =
        vtkHierarchicalBoxDataSet::SafeDownCast(input);
      for (unsigned int group=0; group<numGroups-1; group++)
        {
        hbds->SetRefinementRatio(
          group, ihbds->GetRefinementRatio(group + this->MinGroup));
        }
      hbds->GenerateVisibilityArrays();
      }

    }

  return 1;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>BUG: Method should check for no input<commit_after>/*=========================================================================

Program:   Visualization Toolkit
Module:    vtkMultiGroupDataExtractDataSets.cxx

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMultiGroupDataExtractDataSets.h"

#include "vtkCompositeDataPipeline.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataSet.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkMultiGroupDataInformation.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkUniformGrid.h"

#include <vtkstd/list>

vtkCxxRevisionMacro(vtkMultiGroupDataExtractDataSets, "1.5");
vtkStandardNewMacro(vtkMultiGroupDataExtractDataSets);

struct vtkMultiGroupDataExtractDataSetsInternals
{
  typedef
  vtkstd::list<vtkMultiGroupDataExtractDataSets::DataSetNode> DataSetsTypes;
  DataSetsTypes DataSets;
};

//----------------------------------------------------------------------------
vtkMultiGroupDataExtractDataSets::vtkMultiGroupDataExtractDataSets()
{
  this->Internal = new vtkMultiGroupDataExtractDataSetsInternals;
  this->MinGroup = VTK_UNSIGNED_INT_MAX;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataExtractDataSets::~vtkMultiGroupDataExtractDataSets()
{
  delete this->Internal;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::AddDataSet(
  unsigned int group, unsigned int idx)
{
  this->Internal->DataSets.push_back(DataSetNode(group, idx));
  this->MinGroup = (group < this->MinGroup) ? group : this->MinGroup;

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::ClearDataSetList()
{
  this->Internal->DataSets.clear();
  this->MinGroup = VTK_UNSIGNED_INT_MAX;
  this->Modified();
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataExtractDataSets::ComputeOutputGroups(
  unsigned int inputNumGroups)
{
  unsigned int numGroups = 0;
  vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
    this->Internal->DataSets.begin();
  for (; it != this->Internal->DataSets.end(); it++)
    {
    DataSetNode& node = *it;
    unsigned int curNumGroups = node.Group - this->MinGroup + 1;
    if (curNumGroups > numGroups && curNumGroups <= inputNumGroups)
      {
      numGroups = curNumGroups;
      }
    }
  return numGroups;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestDataObject(
  vtkInformation*,
  vtkInformationVector** inputVector ,
  vtkInformationVector* outputVector)
{
  vtkCompositeDataSet* input = vtkCompositeDataSet::GetData(inputVector[0], 0);
  vtkCompositeDataSet *output = vtkCompositeDataSet::GetData(outputVector, 0);

  if (!input)
    {
    return 0;
    }

  if (!output || !output->IsA(input->GetClassName()))
    {
    output = input->NewInstance();
    output->SetPipelineInformation(outputVector->GetInformationObject(0));
    output->Delete();
    }

  return 1;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestInformation(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkMultiGroupDataInformation* inCompInfo =
    vtkMultiGroupDataInformation::SafeDownCast(
      inInfo->Get(vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION()));
  if (!inCompInfo)
    {
    vtkDebugMacro("Expected information not found. "
                  "Cannot provide information.");
    return 1;
    }

  unsigned int numInputGroups = inCompInfo->GetNumberOfGroups();
  unsigned int numOutputGroups = this->ComputeOutputGroups(numInputGroups);

  vtkMultiGroupDataInformation* compInfo =
    vtkMultiGroupDataInformation::New();
  if (numOutputGroups > 0)
    {
    compInfo->SetNumberOfGroups(numOutputGroups);
    vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
      this->Internal->DataSets.begin();
    for (; it != this->Internal->DataSets.end(); it++)
      {
      DataSetNode& node = *it;
      unsigned int numInputDataSets =
        inCompInfo->GetNumberOfDataSets(node.Group);
      if (node.DataSetId <= numInputDataSets)
        {
        if (node.DataSetId >= compInfo->GetNumberOfDataSets(
              node.Group - this->MinGroup))
          {
          compInfo->SetNumberOfDataSets(
            node.Group - this->MinGroup, node.DataSetId+1);

          if (inCompInfo->HasInformation(node.Group, node.DataSetId))
            {
            vtkInformation* outdInfo =
              compInfo->GetInformation(node.Group - this->MinGroup,
                                       node.DataSetId);
            vtkInformation* indInfo =
              inCompInfo->GetInformation(node.Group, node.DataSetId);
            outdInfo->Copy(indInfo);
            }
          }
        }
      }
    }

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  outInfo->Set(
    vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION(), compInfo);
  compInfo->Delete();

  return 1;
}

//----------------------------------------------------------------------------
int vtkMultiGroupDataExtractDataSets::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkMultiGroupDataSet *input = vtkMultiGroupDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  if (!input) {return 0;}

  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkMultiGroupDataSet *output = vtkMultiGroupDataSet::SafeDownCast(
    info->Get(vtkDataObject::DATA_OBJECT()));
  if (!output) {return 0;}

  unsigned int numInputGroups = input->GetNumberOfGroups();
  unsigned int numOutputGroups = this->ComputeOutputGroups(numInputGroups);

  if (numOutputGroups > 0)
    {
    output->SetNumberOfGroups(numOutputGroups);

    vtkMultiGroupDataExtractDataSetsInternals::DataSetsTypes::iterator it =
      this->Internal->DataSets.begin();
    for (; it != this->Internal->DataSets.end(); it++)
      {
      DataSetNode& node = *it;
      unsigned int numInputDataSets = input->GetNumberOfDataSets(node.Group);
      if (node.DataSetId <= numInputDataSets)
        {
        if (node.DataSetId >= output->GetNumberOfDataSets(
              node.Group - this->MinGroup))
          {
          output->SetNumberOfDataSets(node.Group - this->MinGroup,
                                      node.DataSetId+1);
          }
        vtkDataObject* dObj =
          input->GetDataSet(node.Group, node.DataSetId);
        if (dObj)
          {
          vtkDataObject* copy = dObj->NewInstance();
          copy->ShallowCopy(dObj);

          // Remove blanking from output datasets.
          vtkUniformGrid* ug = vtkUniformGrid::SafeDownCast(copy);
          if (ug)
            {
            ug->SetCellVisibilityArray(0);
            }
          output->SetDataSet(node.Group - this->MinGroup, node.DataSetId, copy);
          copy->Delete();
          }
        }
      }

    vtkMultiGroupDataInformation* compInfo =
      vtkMultiGroupDataInformation::SafeDownCast(
        info->Get(vtkCompositeDataPipeline::COMPOSITE_DATA_INFORMATION()));

    if (compInfo)
      {
      output->SetMultiGroupDataInformation(compInfo);
      }
    unsigned int numGroups = output->GetNumberOfGroups();

    vtkHierarchicalBoxDataSet* hbds =
      vtkHierarchicalBoxDataSet::SafeDownCast(output);
    if (hbds)
      {
      vtkHierarchicalBoxDataSet* ihbds =
        vtkHierarchicalBoxDataSet::SafeDownCast(input);
      for (unsigned int group=0; group<numGroups-1; group++)
        {
        hbds->SetRefinementRatio(
          group, ihbds->GetRefinementRatio(group + this->MinGroup));
        }
      hbds->GenerateVisibilityArrays();
      }

    }

  return 1;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataExtractDataSets::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


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

#include "chrome/browser/bookmarks/bookmark_node_data.h"

#include <string>

#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "net/base/escape.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"

#if defined(OS_MACOSX)
#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
#else
#include "chrome/browser/browser_process.h"
#endif

const char* BookmarkNodeData::kClipboardFormatString =
    "chromium/x-bookmark-entries";

BookmarkNodeData::Element::Element() : is_url(false), id_(0) {
}

BookmarkNodeData::Element::Element(const BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->url()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->child_count(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

BookmarkNodeData::Element::~Element() {
}

void BookmarkNodeData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteString16(title);
  pickle->WriteInt64(id_);
  if (!is_url) {
    pickle->WriteSize(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkNodeData::Element::ReadFromPickle(Pickle* pickle,
                                               PickleIterator* iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadString16(iterator, &title) ||
      !pickle->ReadInt64(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    size_t children_count;
    if (!pickle->ReadSize(iterator, &children_count))
      return false;
    children.resize(children_count);
    for (std::vector<Element>::iterator i = children.begin();
         i != children.end(); ++i) {
      if (!i->ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

#if defined(TOOLKIT_VIEWS)
// static
ui::OSExchangeData::CustomFormat BookmarkNodeData::GetBookmarkCustomFormat() {
  static ui::OSExchangeData::CustomFormat format;
  static bool format_valid = false;

  if (!format_valid) {
    format_valid = true;
    format = ui::OSExchangeData::RegisterCustomFormat(
        BookmarkNodeData::kClipboardFormatString);
  }
  return format;
}
#endif

BookmarkNodeData::BookmarkNodeData() {
}

BookmarkNodeData::BookmarkNodeData(const BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkNodeData::BookmarkNodeData(
    const std::vector<const BookmarkNode*>& nodes) {
  ReadFromVector(nodes);
}

BookmarkNodeData::~BookmarkNodeData() {
}

bool BookmarkNodeData::ReadFromVector(
    const std::vector<const BookmarkNode*>& nodes) {
  Clear();

  if (nodes.empty())
    return false;

  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));

  return true;
}

bool BookmarkNodeData::ReadFromTuple(const GURL& url, const string16& title) {
  Clear();

  if (!url.is_valid())
    return false;

  Element element;
  element.title = title;
  element.url = url;
  element.is_url = true;

  elements.push_back(element);

  return true;
}

#if !defined(OS_MACOSX)
void BookmarkNodeData::WriteToClipboard(Profile* profile) const {
  ui::ScopedClipboardWriter scw(g_browser_process->clipboard(),
                                ui::Clipboard::BUFFER_STANDARD);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    const string16& title = elements[0].title;
    const std::string url = elements[0].url.spec();

    scw.WriteBookmark(title, url);
    scw.WriteHyperlink(net::EscapeForHTML(title), url);

    // Also write the URL to the clipboard as text so that it can be pasted
    // into text fields. We use WriteText instead of WriteURL because we don't
    // want to clobber the X clipboard when the user copies out of the omnibox
    // on Linux (on Windows and Mac, there is no difference between these
    // functions).
    scw.WriteText(UTF8ToUTF16(url));
  }

  Pickle pickle;
  WriteToPickle(profile, &pickle);
  scw.WritePickledData(
      pickle, ui::Clipboard::GetFormatType(kClipboardFormatString));
}

bool BookmarkNodeData::ReadFromClipboard() {
  std::string data;
  ui::Clipboard* clipboard = g_browser_process->clipboard();
  clipboard->ReadData(ui::Clipboard::GetFormatType(kClipboardFormatString),
                      &data);

  if (!data.empty()) {
    Pickle pickle(data.data(), data.size());
    if (ReadFromPickle(&pickle))
      return true;
  }

  string16 title;
  std::string url;
  clipboard->ReadBookmark(&title, &url);
  if (!url.empty()) {
    Element element;
    element.is_url = true;
    element.url = GURL(url);
    element.title = title;

    elements.clear();
    elements.push_back(element);
    return true;
  }

  return false;
}

bool BookmarkNodeData::ClipboardContainsBookmarks() {
  return g_browser_process->clipboard()->IsFormatAvailable(
      ui::Clipboard::GetFormatType(kClipboardFormatString),
      ui::Clipboard::BUFFER_STANDARD);
}
#else
void BookmarkNodeData::WriteToClipboard(Profile* profile) const {
  bookmark_pasteboard_helper_mac::WriteToPasteboard(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard,
      elements,
      profile_path_.value());
}

bool BookmarkNodeData::ReadFromClipboard() {
  FilePath file_path;
  if (!bookmark_pasteboard_helper_mac::ReadFromPasteboard(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard,
      elements,
      &file_path)) {
    return false;
  }

  profile_path_ = file_path;
  return true;
}

bool BookmarkNodeData::ReadFromDragClipboard() {
  FilePath file_path;
  if (!bookmark_pasteboard_helper_mac::ReadFromPasteboard(
      bookmark_pasteboard_helper_mac::kDragPasteboard,
      elements,
      &file_path)) {
    return false;
  }

  profile_path_ = file_path;
  return true;
}

bool BookmarkNodeData::ClipboardContainsBookmarks() {
  return bookmark_pasteboard_helper_mac::PasteboardContainsBookmarks(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard);
}
#endif  // !defined(OS_MACOSX)

#if defined(TOOLKIT_VIEWS)
void BookmarkNodeData::Write(Profile* profile, ui::OSExchangeData* data) const {
  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(UTF8ToUTF16(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(GetBookmarkCustomFormat(), data_pickle);
}

bool BookmarkNodeData::Read(const ui::OSExchangeData& data) {
  elements.clear();

  profile_path_.clear();

  if (data.HasCustomFormat(GetBookmarkCustomFormat())) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(GetBookmarkCustomFormat(), &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    GURL url;
    string16 title;
    if (data.GetURLAndTitle(&url, &title))
      ReadFromTuple(url, title);
  }

  return is_valid();
}
#endif

void BookmarkNodeData::WriteToPickle(Profile* profile, Pickle* pickle) const {
  FilePath path = profile ? profile->GetPath() : FilePath();
  path.WriteToPickle(pickle);
  pickle->WriteSize(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkNodeData::ReadFromPickle(Pickle* pickle) {
  PickleIterator data_iterator(*pickle);
  size_t element_count;
  if (profile_path_.ReadFromPickle(&data_iterator) &&
      pickle->ReadSize(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (size_t i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<const BookmarkNode*> BookmarkNodeData::GetNodes(
    Profile* profile) const {
  std::vector<const BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    const BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

const BookmarkNode* BookmarkNodeData::GetFirstNode(Profile* profile) const {
  std::vector<const BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

void BookmarkNodeData::Clear() {
  profile_path_.clear();
  elements.clear();
}

void BookmarkNodeData::SetOriginatingProfile(Profile* profile) {
  DCHECK(profile_path_.empty());

  if (profile)
    profile_path_ = profile->GetPath();
}

bool BookmarkNodeData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return !profile_path_.empty() && profile_path_ == profile->GetPath();
}
<commit_msg>Avoid using Pickle::WriteSize(), which writes an architecture-dependent amount of data, in bookmark pickles. (The goal is to remove that method entirely. Uses that never persist or send pickles over the network are [probably] safe, but having the method around is waiting for accidental misuses.) Review URL: https://chromiumcodereview.appspot.com/9669056<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/bookmarks/bookmark_node_data.h"

#include <string>

#include "base/basictypes.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "net/base/escape.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"

#if defined(OS_MACOSX)
#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
#else
#include "chrome/browser/browser_process.h"
#endif

const char* BookmarkNodeData::kClipboardFormatString =
    "chromium/x-bookmark-entries";

BookmarkNodeData::Element::Element() : is_url(false), id_(0) {
}

BookmarkNodeData::Element::Element(const BookmarkNode* node)
    : is_url(node->is_url()),
      url(node->url()),
      title(node->GetTitle()),
      id_(node->id()) {
  for (int i = 0; i < node->child_count(); ++i)
    children.push_back(Element(node->GetChild(i)));
}

BookmarkNodeData::Element::~Element() {
}

void BookmarkNodeData::Element::WriteToPickle(Pickle* pickle) const {
  pickle->WriteBool(is_url);
  pickle->WriteString(url.spec());
  pickle->WriteString16(title);
  pickle->WriteInt64(id_);
  if (!is_url) {
    pickle->WriteUInt64(children.size());
    for (std::vector<Element>::const_iterator i = children.begin();
         i != children.end(); ++i) {
      i->WriteToPickle(pickle);
    }
  }
}

bool BookmarkNodeData::Element::ReadFromPickle(Pickle* pickle,
                                               PickleIterator* iterator) {
  std::string url_spec;
  if (!pickle->ReadBool(iterator, &is_url) ||
      !pickle->ReadString(iterator, &url_spec) ||
      !pickle->ReadString16(iterator, &title) ||
      !pickle->ReadInt64(iterator, &id_)) {
    return false;
  }
  url = GURL(url_spec);
  children.clear();
  if (!is_url) {
    uint64 children_count;
    if (!pickle->ReadUInt64(iterator, &children_count))
      return false;
    children.reserve(children_count);
    for (uint64 i = 0; i < children_count; ++i) {
      children.push_back(Element());
      if (!children.back().ReadFromPickle(pickle, iterator))
        return false;
    }
  }
  return true;
}

#if defined(TOOLKIT_VIEWS)
// static
ui::OSExchangeData::CustomFormat BookmarkNodeData::GetBookmarkCustomFormat() {
  static ui::OSExchangeData::CustomFormat format;
  static bool format_valid = false;

  if (!format_valid) {
    format_valid = true;
    format = ui::OSExchangeData::RegisterCustomFormat(
        BookmarkNodeData::kClipboardFormatString);
  }
  return format;
}
#endif

BookmarkNodeData::BookmarkNodeData() {
}

BookmarkNodeData::BookmarkNodeData(const BookmarkNode* node) {
  elements.push_back(Element(node));
}

BookmarkNodeData::BookmarkNodeData(
    const std::vector<const BookmarkNode*>& nodes) {
  ReadFromVector(nodes);
}

BookmarkNodeData::~BookmarkNodeData() {
}

bool BookmarkNodeData::ReadFromVector(
    const std::vector<const BookmarkNode*>& nodes) {
  Clear();

  if (nodes.empty())
    return false;

  for (size_t i = 0; i < nodes.size(); ++i)
    elements.push_back(Element(nodes[i]));

  return true;
}

bool BookmarkNodeData::ReadFromTuple(const GURL& url, const string16& title) {
  Clear();

  if (!url.is_valid())
    return false;

  Element element;
  element.title = title;
  element.url = url;
  element.is_url = true;

  elements.push_back(element);

  return true;
}

#if !defined(OS_MACOSX)
void BookmarkNodeData::WriteToClipboard(Profile* profile) const {
  ui::ScopedClipboardWriter scw(g_browser_process->clipboard(),
                                ui::Clipboard::BUFFER_STANDARD);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    const string16& title = elements[0].title;
    const std::string url = elements[0].url.spec();

    scw.WriteBookmark(title, url);
    scw.WriteHyperlink(net::EscapeForHTML(title), url);

    // Also write the URL to the clipboard as text so that it can be pasted
    // into text fields. We use WriteText instead of WriteURL because we don't
    // want to clobber the X clipboard when the user copies out of the omnibox
    // on Linux (on Windows and Mac, there is no difference between these
    // functions).
    scw.WriteText(UTF8ToUTF16(url));
  }

  Pickle pickle;
  WriteToPickle(profile, &pickle);
  scw.WritePickledData(
      pickle, ui::Clipboard::GetFormatType(kClipboardFormatString));
}

bool BookmarkNodeData::ReadFromClipboard() {
  std::string data;
  ui::Clipboard* clipboard = g_browser_process->clipboard();
  clipboard->ReadData(ui::Clipboard::GetFormatType(kClipboardFormatString),
                      &data);

  if (!data.empty()) {
    Pickle pickle(data.data(), data.size());
    if (ReadFromPickle(&pickle))
      return true;
  }

  string16 title;
  std::string url;
  clipboard->ReadBookmark(&title, &url);
  if (!url.empty()) {
    Element element;
    element.is_url = true;
    element.url = GURL(url);
    element.title = title;

    elements.clear();
    elements.push_back(element);
    return true;
  }

  return false;
}

bool BookmarkNodeData::ClipboardContainsBookmarks() {
  return g_browser_process->clipboard()->IsFormatAvailable(
      ui::Clipboard::GetFormatType(kClipboardFormatString),
      ui::Clipboard::BUFFER_STANDARD);
}
#else
void BookmarkNodeData::WriteToClipboard(Profile* profile) const {
  bookmark_pasteboard_helper_mac::WriteToPasteboard(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard,
      elements,
      profile_path_.value());
}

bool BookmarkNodeData::ReadFromClipboard() {
  FilePath file_path;
  if (!bookmark_pasteboard_helper_mac::ReadFromPasteboard(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard,
      elements,
      &file_path)) {
    return false;
  }

  profile_path_ = file_path;
  return true;
}

bool BookmarkNodeData::ReadFromDragClipboard() {
  FilePath file_path;
  if (!bookmark_pasteboard_helper_mac::ReadFromPasteboard(
      bookmark_pasteboard_helper_mac::kDragPasteboard,
      elements,
      &file_path)) {
    return false;
  }

  profile_path_ = file_path;
  return true;
}

bool BookmarkNodeData::ClipboardContainsBookmarks() {
  return bookmark_pasteboard_helper_mac::PasteboardContainsBookmarks(
      bookmark_pasteboard_helper_mac::kCopyPastePasteboard);
}
#endif  // !defined(OS_MACOSX)

#if defined(TOOLKIT_VIEWS)
void BookmarkNodeData::Write(Profile* profile, ui::OSExchangeData* data) const {
  DCHECK(data);

  // If there is only one element and it is a URL, write the URL to the
  // clipboard.
  if (elements.size() == 1 && elements[0].is_url) {
    if (elements[0].url.SchemeIs(chrome::kJavaScriptScheme)) {
      data->SetString(UTF8ToUTF16(elements[0].url.spec()));
    } else {
      data->SetURL(elements[0].url, elements[0].title);
    }
  }

  Pickle data_pickle;
  WriteToPickle(profile, &data_pickle);

  data->SetPickledData(GetBookmarkCustomFormat(), data_pickle);
}

bool BookmarkNodeData::Read(const ui::OSExchangeData& data) {
  elements.clear();

  profile_path_.clear();

  if (data.HasCustomFormat(GetBookmarkCustomFormat())) {
    Pickle drag_data_pickle;
    if (data.GetPickledData(GetBookmarkCustomFormat(), &drag_data_pickle)) {
      if (!ReadFromPickle(&drag_data_pickle))
        return false;
    }
  } else {
    // See if there is a URL on the clipboard.
    Element element;
    GURL url;
    string16 title;
    if (data.GetURLAndTitle(&url, &title))
      ReadFromTuple(url, title);
  }

  return is_valid();
}
#endif

void BookmarkNodeData::WriteToPickle(Profile* profile, Pickle* pickle) const {
  FilePath path = profile ? profile->GetPath() : FilePath();
  path.WriteToPickle(pickle);
  pickle->WriteUInt64(elements.size());

  for (size_t i = 0; i < elements.size(); ++i)
    elements[i].WriteToPickle(pickle);
}

bool BookmarkNodeData::ReadFromPickle(Pickle* pickle) {
  PickleIterator data_iterator(*pickle);
  uint64 element_count;
  if (profile_path_.ReadFromPickle(&data_iterator) &&
      pickle->ReadUInt64(&data_iterator, &element_count)) {
    std::vector<Element> tmp_elements;
    tmp_elements.resize(element_count);
    for (uint64 i = 0; i < element_count; ++i) {
      if (!tmp_elements[i].ReadFromPickle(pickle, &data_iterator)) {
        return false;
      }
    }
    elements.swap(tmp_elements);
  }

  return true;
}

std::vector<const BookmarkNode*> BookmarkNodeData::GetNodes(
    Profile* profile) const {
  std::vector<const BookmarkNode*> nodes;

  if (!IsFromProfile(profile))
    return nodes;

  for (size_t i = 0; i < elements.size(); ++i) {
    const BookmarkNode* node =
        profile->GetBookmarkModel()->GetNodeByID(elements[i].id_);
    if (!node) {
      nodes.clear();
      return nodes;
    }
    nodes.push_back(node);
  }
  return nodes;
}

const BookmarkNode* BookmarkNodeData::GetFirstNode(Profile* profile) const {
  std::vector<const BookmarkNode*> nodes = GetNodes(profile);
  return nodes.size() == 1 ? nodes[0] : NULL;
}

void BookmarkNodeData::Clear() {
  profile_path_.clear();
  elements.clear();
}

void BookmarkNodeData::SetOriginatingProfile(Profile* profile) {
  DCHECK(profile_path_.empty());

  if (profile)
    profile_path_ = profile->GetPath();
}

bool BookmarkNodeData::IsFromProfile(Profile* profile) const {
  // An empty path means the data is not associated with any profile.
  return !profile_path_.empty() && profile_path_ == profile->GetPath();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file runner/runner.hxx
 ** \brief Inline implementation of runner::Runner.
 */

#ifndef RUNNER_RUNNER_HXX
# define RUNNER_RUNNER_HXX

# include <libport/compilation.hh>

# include <urbi/object/event.hh>
# include <urbi/object/job.hh> // To destroy Runner::job_.
# include <urbi/object/lobby.hh>
# include <urbi/object/tag.hh>

namespace runner
{

  LIBPORT_SPEED_INLINE
  Runner::Runner(rLobby lobby, sched::Scheduler& sched,
		 libport::Symbol name)
    : sched::Job(sched, name)
    , redefinition_mode_(false)
    , void_error_(true)
    , lobby_(lobby)
    , prio_(sched::UPRIO_DEFAULT)
    , frozen_(false)
    , dependencies_log_(false)
    , dependencies_()
  {
  }

  LIBPORT_SPEED_INLINE
  Runner::Runner(const Runner& model, libport::Symbol name)
    : sched::Job(model, name)
    , redefinition_mode_(model.redefinition_mode_)
    , void_error_(true)
    , lobby_(model.lobby_)
    , prio_(sched::UPRIO_DEFAULT)
    , frozen_(false)
    , dependencies_log_(false)
    , dependencies_()
  {
  }

  LIBPORT_SPEED_INLINE
  Runner::~Runner()
  {
  }

  LIBPORT_SPEED_INLINE
  const object::rLobby&
  Runner::lobby_get() const
  {
    return lobby_;
  }

  LIBPORT_SPEED_INLINE
  object::rLobby
  Runner::lobby_get()
  {
    return lobby_;
  }

  LIBPORT_SPEED_INLINE
  void
  Runner::lobby_set(rLobby lobby)
  {
    lobby_ = lobby;
  }

  LIBPORT_SPEED_INLINE sched::prio_type
  Runner::prio_get() const
  {
    return prio_;
  }

  LIBPORT_SPEED_INLINE void
  Runner::apply_tag(const object::rTag& tag, libport::Finally* finally)
  {
    tag_stack_.push_back(tag);
    if (finally)
      *finally << boost::bind(&tag_stack_type::pop_back, boost::ref(tag_stack_))
	       << boost::bind(&Runner::recompute_prio, this,
			      tag->value_get()->prio_get());
    recompute_prio(tag);
  }

  LIBPORT_SPEED_INLINE bool
  Runner::has_tag(const object::rTag& tag) const
  {
    return has_tag(*tag->value_get());
  }

  LIBPORT_SPEED_INLINE void
  Runner::tag_stack_clear()
  {
    tag_stack_.clear();
  }

  LIBPORT_SPEED_INLINE const tag_stack_type&
  Runner::tag_stack_get_all() const
  {
    return tag_stack_;
  }

  LIBPORT_SPEED_INLINE void
  Runner::tag_stack_set(const tag_stack_type& tag_stack)
  {
    tag_stack_ = tag_stack;
  }

  LIBPORT_SPEED_INLINE size_t
  Runner::tag_stack_size() const
  {
    return tag_stack_.size();
  }

} // namespace runner

#endif // RUNNER_RUNNER_HXX
<commit_msg>Fix mean implicit conversion bug.<commit_after>/*
 * Copyright (C) 2007-2011, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

/**
 ** \file runner/runner.hxx
 ** \brief Inline implementation of runner::Runner.
 */

#ifndef RUNNER_RUNNER_HXX
# define RUNNER_RUNNER_HXX

# include <libport/compilation.hh>

# include <urbi/object/event.hh>
# include <urbi/object/job.hh> // To destroy Runner::job_.
# include <urbi/object/lobby.hh>
# include <urbi/object/tag.hh>

namespace runner
{

  LIBPORT_SPEED_INLINE
  Runner::Runner(rLobby lobby, sched::Scheduler& sched,
		 libport::Symbol name)
    : sched::Job(sched, name)
    , redefinition_mode_(false)
    , void_error_(true)
    , lobby_(lobby)
    , prio_(sched::UPRIO_DEFAULT)
    , frozen_(false)
    , dependencies_log_(false)
    , dependencies_()
  {
  }

  LIBPORT_SPEED_INLINE
  Runner::Runner(const Runner& model, libport::Symbol name)
    : sched::Job(model, name)
    , redefinition_mode_(model.redefinition_mode_)
    , void_error_(true)
    , lobby_(model.lobby_)
    , prio_(sched::UPRIO_DEFAULT)
    , frozen_(false)
    , dependencies_log_(false)
    , dependencies_()
  {
  }

  LIBPORT_SPEED_INLINE
  Runner::~Runner()
  {
  }

  LIBPORT_SPEED_INLINE
  const object::rLobby&
  Runner::lobby_get() const
  {
    return lobby_;
  }

  LIBPORT_SPEED_INLINE
  object::rLobby
  Runner::lobby_get()
  {
    return lobby_;
  }

  LIBPORT_SPEED_INLINE
  void
  Runner::lobby_set(rLobby lobby)
  {
    lobby_ = lobby;
  }

  LIBPORT_SPEED_INLINE sched::prio_type
  Runner::prio_get() const
  {
    return prio_;
  }

  LIBPORT_SPEED_INLINE void
  Runner::apply_tag(const object::rTag& tag, libport::Finally* finally)
  {
    tag_stack_.push_back(tag);
    if (finally)
      *finally << boost::bind(&tag_stack_type::pop_back, boost::ref(tag_stack_))
	       << boost::bind(&Runner::recompute_prio, this,
			      tag->value_get()->prio_get());
    recompute_prio(tag->value_get()->prio_get());
  }

  LIBPORT_SPEED_INLINE bool
  Runner::has_tag(const object::rTag& tag) const
  {
    return has_tag(*tag->value_get());
  }

  LIBPORT_SPEED_INLINE void
  Runner::tag_stack_clear()
  {
    tag_stack_.clear();
  }

  LIBPORT_SPEED_INLINE const tag_stack_type&
  Runner::tag_stack_get_all() const
  {
    return tag_stack_;
  }

  LIBPORT_SPEED_INLINE void
  Runner::tag_stack_set(const tag_stack_type& tag_stack)
  {
    tag_stack_ = tag_stack;
  }

  LIBPORT_SPEED_INLINE size_t
  Runner::tag_stack_size() const
  {
    return tag_stack_.size();
  }

} // namespace runner

#endif // RUNNER_RUNNER_HXX
<|endoftext|>