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

#include "task_map/Point2Line.hpp"

REGISTER_TASKMAP_TYPE("Point2Line", exotica::Point2Line);

namespace exotica
{
Eigen::Vector3d Point2Line::direction(const Eigen::Vector3d &point)
{
    // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
    // let:
    //      s: start of line
    //      e: end of line
    //      p: point
    // then the point on vector v = e-s that is closest to p is vp = s + t*(e-s) with
    // t = -((s-p)*(e-s)) / (|e-s|^2)    (* denotes the dot product)
    if (debug_) HIGHLIGHT_NAMED("P2L", "\e[4m" << link_name << "\e[0m");
    if (debug_) HIGHLIGHT_NAMED("P2L", "p " << point.transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "ls " << line_start.transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "le " << line_end.transpose());
    double t = -(line_start - point).dot(line) / line.squaredNorm();
    std::stringstream ss;
    ss << "t " << t;
    if (!infinite)
    {
        // clip to to range [0,1]
        t = std::min(std::max(0.0, t), 1.0);
        ss << ", clipped |t| " << t;
    }
    if (debug_) HIGHLIGHT_NAMED("P2L", ss.str());

    // vector from point 'p' to point 'vp' on line
    // vp = line_start + t * (line_end-line_start)
    const Eigen::Vector3d dv = line_start + (t * line) - point;
    if (debug_) HIGHLIGHT_NAMED("P2L", "vp " << (line_start + (t * line)).transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "dv " << dv.transpose());
    return dv;
}

void Point2Line::update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi)
{
    if (phi.rows() != Kinematics[0].Phi.rows() * 3) throw_named("Wrong size of phi!");

    for (int i = 0; i < Kinematics[0].Phi.rows(); i++)
    {
        const Eigen::Vector3d p = line_start + Eigen::Map<const Eigen::Vector3d>(Kinematics[0].Phi(i).p.data);
        phi.segment<3>(i * 3) = -direction(p);
    }
}

void Point2Line::update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi, Eigen::MatrixXdRef J)
{
    if (phi.rows() != Kinematics[0].Phi.rows() * 3) throw_named("Wrong size of phi!");
    if (J.rows() != Kinematics[0].J.rows() * 3 || J.cols() != Kinematics[0].J(0).data.cols()) throw_named("Wrong size of J! " << Kinematics[0].J(0).data.cols());

    for (int i = 0; i < Kinematics[0].Phi.rows(); i++)
    {
        // point in base frame
        const Eigen::Vector3d p = line_start + Eigen::Map<const Eigen::Vector3d>(Kinematics[0].Phi(i).p.data);
        // direction from point to line
        const Eigen::Vector3d dv = direction(p);
        phi.segment<3>(i * 3) = dv;
        for (int j = 0; j < J.cols(); j++)
        {
            J.middleRows<3>(i * 3).col(j) = Kinematics[0].J[i].data.topRows<3>().col(j).dot(line/line.squaredNorm()) * line - Kinematics[0].J[i].data.topRows<3>().col(j);
        }

        // visualisation of point, line and their distance
        if (visualise && Server::isRos())
        {
            const ros::Time t = ros::Time::now();
            const std::string common_frame = "exotica/" + base_name;
            visualization_msgs::MarkerArray ma;
            {
                // line in base frame
                visualization_msgs::Marker mc;
                mc.header.stamp = t;
                mc.frame_locked = true;
                mc.header.frame_id = common_frame;
                mc.ns = "cam/line/" + object_name_;
                mc.type = visualization_msgs::Marker::ARROW;
                mc.scale.x = 0.01;
                mc.scale.y = 0.01;
                mc.scale.z = 0.01;
                // line start
                geometry_msgs::Point pp;
                pp.x = line_start.x();
                pp.y = line_start.y();
                pp.z = line_start.z();
                mc.points.push_back(pp);
                // line end
                const Eigen::Vector3d pe = p + dv;
                pp.x = pe.x();
                pp.y = pe.y();
                pp.z = pe.z();
                mc.points.push_back(pp);
                mc.color.r = 1;
                mc.color.g = 1;
                mc.color.b = 0;
                mc.color.a = 1;
                ma.markers.push_back(mc);
            }
            {
                // point in link frame
                visualization_msgs::Marker ml;
                ml.header.stamp = t;
                ml.frame_locked = true;
                ml.header.frame_id = common_frame;
                ml.ns = "lnk/point/" + object_name_;
                ml.type = visualization_msgs::Marker::SPHERE;
                ml.scale.x = 0.03;
                ml.scale.y = 0.03;
                ml.scale.z = 0.03;
                ml.color.r = 1;
                ml.color.g = 0;
                ml.color.b = 0;
                ml.color.a = 1;
                ml.pose.position.x = p.x();
                ml.pose.position.y = p.y();
                ml.pose.position.z = p.z();
                ma.markers.push_back(ml);
            }
            {
                // draw 'dv' starting at 'p' in base frame
                visualization_msgs::Marker mdv;
                mdv.header.stamp = t;
                mdv.frame_locked = true;
                mdv.header.frame_id = common_frame;
                mdv.ns = "dv/" + object_name_;
                mdv.type = visualization_msgs::Marker::ARROW;
                mdv.scale.x = 0.001;
                mdv.scale.y = 0.01;
                mdv.scale.z = 0.01;
                mdv.pose.position.x = p.x();
                mdv.pose.position.y = p.y();
                mdv.pose.position.z = p.z();
                mdv.points.push_back(geometry_msgs::Point());
                geometry_msgs::Point pdv;
                pdv.x = dv.x();
                pdv.y = dv.y();
                pdv.z = dv.z();
                mdv.points.push_back(pdv);
                mdv.color.r = 0;
                mdv.color.g = 1;
                mdv.color.b = 0;
                mdv.color.a = 0.5;
                ma.markers.push_back(mdv);
            }
            pub_marker.publish(ma);
            {
                visualization_msgs::MarkerArray ma;
                visualization_msgs::Marker mt;
                mt.header.stamp = t;
                mt.frame_locked = true;
                mt.header.frame_id = common_frame;
                mt.ns = "lnk/label/" + object_name_;
                mt.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
                mt.text = link_name;
                mt.pose.position.x = p.x();
                mt.pose.position.y = p.y();
                mt.pose.position.z = p.z();
                mt.scale.x = 0.05;
                mt.scale.y = 0.05;
                mt.scale.z = 0.05;
                mt.color.r = 1;
                mt.color.g = 1;
                mt.color.b = 1;
                mt.color.a = 1;
                ma.markers.push_back(mt);
                pub_marker_label.publish(ma);
            }
        }
    }
}

void Point2Line::Instantiate(Point2LineInitializer &init)
{
    link_name = Frames[0].FrameALinkName;
    base_name = Frames[0].FrameBLinkName;

    line_start = Eigen::Map<Eigen::Vector3d>(Frames[0].FrameBOffset.p.data);
    line_end = init.EndPoint;

    line = line_end - line_start;
    infinite = init.Infinite;

    visualise = init.Visualise;

    if (visualise && Server::isRos())
    {
        pub_marker = Server::advertise<visualization_msgs::MarkerArray>("p2l", 1, true);
        pub_marker_label = Server::advertise<visualization_msgs::MarkerArray>("p2l_label", 1, true);
        // delete previous markers
        visualization_msgs::Marker md;
        md.action = 3;  // DELETEALL
        visualization_msgs::MarkerArray ma;
        ma.markers.push_back(md);
        pub_marker.publish(ma);
        pub_marker_label.publish(ma);
    }
}

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

#include "task_map/Point2Line.hpp"

REGISTER_TASKMAP_TYPE("Point2Line", exotica::Point2Line);

namespace exotica
{
Eigen::Vector3d Point2Line::direction(const Eigen::Vector3d &point)
{
    // http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
    // let:
    //      s: start of line
    //      e: end of line
    //      p: point
    // then the point on vector v = e-s that is closest to p is vp = s + t*(e-s) with
    // t = -((s-p)*(e-s)) / (|e-s|^2)    (* denotes the dot product)
    if (debug_) HIGHLIGHT_NAMED("P2L", "\e[4m" << link_name << "\e[0m");
    if (debug_) HIGHLIGHT_NAMED("P2L", "p " << point.transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "ls " << line_start.transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "le " << line_end.transpose());
    double t = -(line_start - point).dot(line) / line.squaredNorm();
    std::stringstream ss;
    ss << "t " << t;
    if (!infinite)
    {
        // clip to to range [0,1]
        t = std::min(std::max(0.0, t), 1.0);
        ss << ", clipped |t| " << t;
    }
    if (debug_) HIGHLIGHT_NAMED("P2L", ss.str());

    // vector from point 'p' to point 'vp' on line
    // vp = line_start + t * (line_end-line_start)
    const Eigen::Vector3d dv = line_start + (t * line) - point;
    if (debug_) HIGHLIGHT_NAMED("P2L", "vp " << (line_start + (t * line)).transpose());
    if (debug_) HIGHLIGHT_NAMED("P2L", "dv " << dv.transpose());
    return dv;
}

void Point2Line::update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi)
{
    if (phi.rows() != Kinematics[0].Phi.rows() * 3) throw_named("Wrong size of phi!");

    for (int i = 0; i < Kinematics[0].Phi.rows(); i++)
    {
        const Eigen::Vector3d p = line_start + Eigen::Map<const Eigen::Vector3d>(Kinematics[0].Phi(i).p.data);
        phi.segment<3>(i * 3) = -direction(p);
    }
}

void Point2Line::update(Eigen::VectorXdRefConst x, Eigen::VectorXdRef phi, Eigen::MatrixXdRef J)
{
    if (phi.rows() != Kinematics[0].Phi.rows() * 3) throw_named("Wrong size of phi!");
    if (J.rows() != Kinematics[0].J.rows() * 3 || J.cols() != Kinematics[0].J(0).data.cols()) throw_named("Wrong size of J! " << Kinematics[0].J(0).data.cols());

    for (int i = 0; i < Kinematics[0].Phi.rows(); i++)
    {
        // point in base frame
        const Eigen::Vector3d p = line_start + Eigen::Map<const Eigen::Vector3d>(Kinematics[0].Phi(i).p.data);
        // direction from point to line
        const Eigen::Vector3d dv = direction(p);
        phi.segment<3>(i * 3) = dv;
        for (int j = 0; j < J.cols(); j++)
        {
            J.middleRows<3>(i * 3).col(j) = Kinematics[0].J[i].data.topRows<3>().col(j).dot(line / line.squaredNorm()) * line - Kinematics[0].J[i].data.topRows<3>().col(j);
        }

        // visualisation of point, line and their distance
        if (visualise && Server::isRos())
        {
            const ros::Time t = ros::Time::now();
            const std::string common_frame = "exotica/" + base_name;
            visualization_msgs::MarkerArray ma;
            {
                // line in base frame
                visualization_msgs::Marker mc;
                mc.header.stamp = t;
                mc.frame_locked = true;
                mc.header.frame_id = common_frame;
                mc.ns = "cam/line/" + object_name_;
                mc.type = visualization_msgs::Marker::ARROW;
                mc.scale.x = 0.01;
                mc.scale.y = 0.01;
                mc.scale.z = 0.01;
                // line start
                geometry_msgs::Point pp;
                pp.x = line_start.x();
                pp.y = line_start.y();
                pp.z = line_start.z();
                mc.points.push_back(pp);
                // line end
                const Eigen::Vector3d pe = p + dv;
                pp.x = pe.x();
                pp.y = pe.y();
                pp.z = pe.z();
                mc.points.push_back(pp);
                mc.color.r = 1;
                mc.color.g = 1;
                mc.color.b = 0;
                mc.color.a = 1;
                ma.markers.push_back(mc);
            }
            {
                // point in link frame
                visualization_msgs::Marker ml;
                ml.header.stamp = t;
                ml.frame_locked = true;
                ml.header.frame_id = common_frame;
                ml.ns = "lnk/point/" + object_name_;
                ml.type = visualization_msgs::Marker::SPHERE;
                ml.scale.x = 0.03;
                ml.scale.y = 0.03;
                ml.scale.z = 0.03;
                ml.color.r = 1;
                ml.color.g = 0;
                ml.color.b = 0;
                ml.color.a = 1;
                ml.pose.position.x = p.x();
                ml.pose.position.y = p.y();
                ml.pose.position.z = p.z();
                ma.markers.push_back(ml);
            }
            {
                // draw 'dv' starting at 'p' in base frame
                visualization_msgs::Marker mdv;
                mdv.header.stamp = t;
                mdv.frame_locked = true;
                mdv.header.frame_id = common_frame;
                mdv.ns = "dv/" + object_name_;
                mdv.type = visualization_msgs::Marker::ARROW;
                mdv.scale.x = 0.001;
                mdv.scale.y = 0.01;
                mdv.scale.z = 0.01;
                mdv.pose.position.x = p.x();
                mdv.pose.position.y = p.y();
                mdv.pose.position.z = p.z();
                mdv.points.push_back(geometry_msgs::Point());
                geometry_msgs::Point pdv;
                pdv.x = dv.x();
                pdv.y = dv.y();
                pdv.z = dv.z();
                mdv.points.push_back(pdv);
                mdv.color.r = 0;
                mdv.color.g = 1;
                mdv.color.b = 0;
                mdv.color.a = 0.5;
                ma.markers.push_back(mdv);
            }
            pub_marker.publish(ma);
            {
                visualization_msgs::MarkerArray ma;
                visualization_msgs::Marker mt;
                mt.header.stamp = t;
                mt.frame_locked = true;
                mt.header.frame_id = common_frame;
                mt.ns = "lnk/label/" + object_name_;
                mt.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
                mt.text = link_name;
                mt.pose.position.x = p.x();
                mt.pose.position.y = p.y();
                mt.pose.position.z = p.z();
                mt.scale.x = 0.05;
                mt.scale.y = 0.05;
                mt.scale.z = 0.05;
                mt.color.r = 1;
                mt.color.g = 1;
                mt.color.b = 1;
                mt.color.a = 1;
                ma.markers.push_back(mt);
                pub_marker_label.publish(ma);
            }
        }
    }
}

void Point2Line::Instantiate(Point2LineInitializer &init)
{
    link_name = Frames[0].FrameALinkName;
    base_name = Frames[0].FrameBLinkName;

    line_start = Eigen::Map<Eigen::Vector3d>(Frames[0].FrameBOffset.p.data);
    line_end = init.EndPoint;

    line = line_end - line_start;
    infinite = init.Infinite;

    visualise = init.Visualise;

    if (visualise && Server::isRos())
    {
        pub_marker = Server::advertise<visualization_msgs::MarkerArray>("p2l", 1, true);
        pub_marker_label = Server::advertise<visualization_msgs::MarkerArray>("p2l_label", 1, true);
        // delete previous markers
        visualization_msgs::Marker md;
        md.action = 3;  // DELETEALL
        visualization_msgs::MarkerArray ma;
        ma.markers.push_back(md);
        pub_marker.publish(ma);
        pub_marker_label.publish(ma);
    }
}

int Point2Line::taskSpaceDim()
{
    return Kinematics[0].Phi.rows() * 3;
}
}  // namespace exotica
<|endoftext|>


<commit_before>#include "exception_helper.h"
#include "lexical_internal.h"
#include <cstring>
#include "ptr_protect.h"
using namespace __internal;

template<EXCEPTION T> void lexicalOops()
{
	__mathlibra__raise<T,INTERPRETER>();
}

//Checks that in an given context if the character '-' should be intepreted as
//an binary subtraction operator or an unary negation operator.
bool isUnary(const char* str,  size_t i, tvec tokens)
{
	if (!tokens.empty())
	{
		token::baseToken * token = tokens.back();
		if (token->type == tree::PARENTHESES)
		{
			return  (i != 0) ? (str[i-1] == '(') : false ;
                }
		else if (token->type == tree::OPERATOR)
		{
		  return true;
		}
			else return false;
	}
        else return true;
}

std::string extract_alpha(const char* str,size_t offset, size_t len)
{
	size_t end = offset;
	while( end < len && isalpha(str[end]))
	{
		end++;
	};
	return std::string(str,offset,end-offset);
}

state lexical(const char * expr,
	      size_t expr_len,
	      memory::memory* mem,
	      math_func::function_interface* func,
	      operators::operators_interface* opr )
{
	tvec tokens;
	tokens.reserve(expr_len);

	pstack paran;

	size_t oper_w_extra=0;
	size_t oper_w_lowset=~0;
	size_t i=0;
	size_t start=0;
	i_state s = { &oper_w_extra, &i,&oper_w_lowset, &expr_len,&start};

	for (i=0; i< expr_len; i++)
	{
		if(expr[i] == '(')
		{
			if(i>0 && expr[i-1] ==  ')')
			{
				pushMulti(tokens,opr,s);
			}
			parse_parantheses1(tokens,s,paran,opr);
		}
		else if(expr[i] == ')')
		{
			parse_parantheses2(tokens,s,paran);
		}
		else if (isdigit(expr[i]))
		{
			parse_number(expr,tokens,s,opr);
		}
		else if(expr[i] == '-'  &&
			isUnary(expr,i,tokens) &&
			i+1<expr_len &&
			isdigit(expr[i+1]))
		{
			parse_number(expr,tokens,s,opr);
		}
		else if (opr!= nullptr && opr->inArray(expr[i]))
		{
			parse_opr(expr,tokens,s,opr);
		}
		else if( isalpha(expr[i]))
		{
			auto str = extract_alpha(expr,i,expr_len);
			i+=str.size()-1;
			if (tokens.size() > 0 && (tokens.back()->type == tree::VALUE || expr[i-1]==')'))
			{
				pushMulti(tokens,opr,s);
			}

			if (func != nullptr && func->isloaded(str).loaded)
			{
				parse_func(str,tokens,s,func);
			}
			else if (mem != nullptr)
			{
				parse_var(str,tokens,s,func,mem);
			}
			else
			{
				lexicalOops<VARIABLES_DISABLED_BUT_USED>();
			}
		}
		else
		{
			lexicalOops<UNKNOWN_CHAR_STR>();
		}
	}
#ifndef CT_PARANTHESES

	if(!paran.empty())
	{
		lexicalOops<SYNTAX_UNMATCHED_OPENING_PARANTHESES>();
	}
	else
	{
		tokens.shrink_to_fit();
	}
#else
	tokens.shrink_to_fit();
#endif //SRICT_PARATHESES
	return  {*(s.start) ,tokens};
}

namespace __internal
{
//****************************************************
//* Util
//***************************************************

void pushMulti(tvec& t,operators::operators_interface* opr, i_state& s)
{
	if (opr->inArray('*'))
	{
		ptr_protect<token::operatorToken*,false> tmp(new token::operatorToken(opr->getCurrent()));
		tmp->startPos=*s.i;
		tmp->endPos=*s.i;
		tmp->baseWheight +=*s.operWheight;
		updateStartPoint(t,s,tmp->baseWheight);
		t.push_back(tmp.ptr());
		tmp.release();

	}
}

void pushValue(tvec& tokens ,i_state& s, double value)
{
	ptr_protect<token::valueToken*, false> tmp_val(new token::valueToken(*(s.i),*(s.i)));
	tmp_val->value = value;
	tokens.push_back(tmp_val.ptr());
	tmp_val.release();
}

void updateStartPoint(tvec& t, i_state& s, size_t w)
{
	if(w <= *s.lowestWheight)
	{
		*s.lowestWheight = w;
		*(s.start)=t.size();
	}
}
//*****************************************************
//* Parantheses parsers
//*
//*****************************************************

void parse_parantheses1(tvec& tokens,
			i_state& s,
			pstack& stack,
			operators::operators_interface* opr)
{
	auto tmp_i=*(s.i);
	auto type = (tokens.size() > 0) ? tokens.back()->type : tree::UNKNOWN ;
	if( type == tree::VALUE || type ==tree::VARIABLE)
	{
		pushMulti(tokens,opr,s);
		tmp_i++;
	}
	tokens.push_back(new token::parenthesesToken(tmp_i,tmp_i));
	stack.push((token::parenthesesToken*) tokens.back());
	(*s.operWheight)+=5;
	return;

}

void parse_parantheses2(tvec& tokens ,i_state& s, pstack& p)
{
	if(p.empty())
	{
		lexicalOops<SYNTAX_UNMATCHED_CLOSING_PARANTHESES>();

	}
	else
	{
		token::parenthesesToken* tmp = p.top();
		p.pop();
		tmp->opposit=*(s.i);
		token::parenthesesToken * tmp2 = new token::parenthesesToken(*(s.i), *(s.i));
		tmp2->opposit = tmp->startPos;
		tokens.push_back(tmp2);
		*(s.operWheight)-=5;
		return;

	}
}
//**************************************************
//*	number parser
//*
//**************************************************

void parse_number(const char * expr, tvec& tokens, i_state& s,operators::operators_interface* opr)
{
	if(tokens.size() > 0)
	{
		auto tmp=tokens.back();
		if(tmp->type == tree::VARIABLE)
		{
			pushMulti(tokens,opr,s);
		}
		else if(expr[*(s.i)-1]==')')
		{
			pushMulti(tokens,opr,s);
		}
	}
	ptr_protect<token::valueToken*, false> tmp(new token::valueToken(*(s.i), 0));
	short valueLength=0;
	for(unsigned int i2 =*(s.i)+1; i2 < *(s.lenght) ; i2++)
	{
		if( !isdigit(expr[i2]) &&
			expr[i2] !='.' &&
			expr[i2] != 'e' &&
			expr[i2] != '-' )
		{
			break;
		}
		else if(expr[i2] == 'e')
		{
			if(i2+1 < *(s.lenght) &&
				( !isdigit(expr[i2+1]) && expr[i2+1] !='-')
				)
			{
				lexicalOops<SYNTAX_EXP_AFTER_E>();
			}
			else if(i2+1 >=*(s.lenght))
			{
				lexicalOops<SYNTAX_EXP_AFTER_E>();
			}

		}
		else if(expr[i2] == '-')
		{
			//If expression is > instead of >= it will fail for expressions as 0-x^2
			if(i2-1 < *(s.lenght)  && expr[i2-1] != 'e')
				break;

		}
			valueLength++;
	}
	tmp->endPos = *(s.i)+valueLength;
	short tmp_str_length = tmp->endPos+1 - tmp->startPos;
	//Create a temporary string from which we can convert the string to a double
	char* tmp_str = nullptr;
        tmp_str = new char[tmp_str_length+1];
	memcpy(tmp_str, &expr[*(s.i)], (tmp_str_length*sizeof(char)) );
	tmp_str[tmp_str_length] = '\0';
	tmp->value =  atof(tmp_str);
	delete[] tmp_str;
	tokens.push_back(tmp.ptr());
	tmp.release(); //Release ownership of pointer
	*(s.i)+=valueLength;
	return;

}

//**********************************************
//*	Operator parser
//*
//**********************************************
void parse_opr(const char* expr, tvec& tokens ,i_state& s,operators::operators_interface* opr)
{
	//Following test compensates for implicit -1 situations like -x or 2*-(2+x) which
	//will be extended to -1*x and 2*-1*(2+x) where the multiplication sign
	//between -1 and the other terme has an higher than usal weight
	if (expr[*(s.i)] == '-')
	{
		tree::tokenType test_type;
		if (tokens.size() > 0)
		{
			test_type = tokens.back()->type;
		}
		else
		{
			test_type = tree::UNKNOWN;
		}

		if ( (*(s.i) - 1 > 0 && (test_type == tree::OPERATOR || expr[*(s.i) - 1] == '(')) ||
				*(s.i) == 0)
		{
			if (opr->inArray('*'))
			{
				pushValue(tokens,s,-1);
				pushMulti(tokens,opr,s);
			}
		}
	}

	ptr_protect<token::operatorToken*, false> tmp(new token::operatorToken(opr->getCurrent()));
	tmp->startPos=*(s.i);
	tmp->endPos=*(s.i);
	tmp->baseWheight +=*(s.operWheight);
	updateStartPoint(tokens,s,tmp->baseWheight);
	if (tmp->operChar == '=')
	{
		if (tokens.back()->type != tokenType::VARIABLE)
		{
			lexicalOops<SYNTAX_ASSIGMENT_NEEDS_VAR>();
		}
		else
		{
			//token is going to be used in an assigment
			//and should thus not be pushed to the stack
			static_cast<token::variableToken*>(tokens.back())->_stack = false;
		}
	}
	tokens.push_back(tmp.ptr());
	tmp.release();
	return;
}

//*****************************************
//*	Function Parser
//*
//*****************************************

void parse_func(std::string str,
		tvec& tokens,
		i_state& s,
		math_func::function_interface* func)
{
	token::funcToken * tmp_ptr;
	math_func::func_type type = func->type();
	auto startPos=*(s.i);
	auto endPos = *(s.i)+str.size();
	if (type == math_func::func_type::GENERAL )
	{
		tmp_ptr = new token::funcToken(startPos, endPos, (token::funcToken::generalFuncPtr)func->get(str));
	}
	else if (type == math_func::func_type::FAST)
	{
		tmp_ptr = new token::funcToken(startPos, endPos, (token::funcToken::funcPtr)func->get(str));
	}
        else
        {
            tmp_ptr = new token::funcToken(startPos,endPos,func->getFunctor(str));
        }

	ptr_protect<token::funcToken *, false> tmp(tmp_ptr);

	tmp->baseWheight += *(s.operWheight);
	updateStartPoint(tokens,s,tmp->baseWheight);
	tokens.push_back(tmp.ptr());
	tmp.release();
}

void parse_var(std::string str,
		tvec& tokens,
		i_state& s,
		math_func::function_interface* func,
		memory::memory* mem)
{

	token::variableToken * tmp = new token::variableToken(*(s.i),*(s.i)+str.size() , mem,func);
	tmp->variableName = str;
	tokens.push_back(tmp);
}

}

<commit_msg>Hotfix, resolves #3<commit_after>#include "exception_helper.h"
#include "lexical_internal.h"
#include <cstring>
#include "ptr_protect.h"
using namespace __internal;

template<EXCEPTION T> void lexicalOops()
{
	__mathlibra__raise<T,INTERPRETER>();
}

//Checks that in an given context if the character '-' should be intepreted as
//an binary subtraction operator or an unary negation operator.
bool isUnary(const char* str,  size_t i, tvec tokens)
{
	if (!tokens.empty())
	{
		token::baseToken * token = tokens.back();
		if (token->type == tree::PARENTHESES)
		{
			return  (i != 0) ? (str[i-1] == '(') : false ;
                }
		else if (token->type == tree::OPERATOR)
		{
		  return true;
		}
			else return false;
	}
        else return true;
}

std::string extract_alpha(const char* str,size_t offset, size_t len)
{
	size_t end = offset;
	while( end < len && isalpha(str[end]))
	{
		end++;
	};
	return std::string(str,offset,end-offset);
}

state lexical(const char * expr,
	      size_t expr_len,
	      memory::memory* mem,
	      math_func::function_interface* func,
	      operators::operators_interface* opr )
{
	tvec tokens;
	tokens.reserve(expr_len);

	pstack paran;

	size_t oper_w_extra=0;
	size_t oper_w_lowset=~0;
	size_t i=0;
	size_t start=0;
	i_state s = { &oper_w_extra, &i,&oper_w_lowset, &expr_len,&start};

	for (i=0; i< expr_len; i++)
	{
		if(expr[i] == '(')
		{
			if(i>0 && expr[i-1] ==  ')')
			{
				pushMulti(tokens,opr,s);
			}
			parse_parantheses1(tokens,s,paran,opr);
		}
		else if(expr[i] == ')')
		{
			parse_parantheses2(tokens,s,paran);
		}
		else if (isdigit(expr[i]))
		{
			parse_number(expr,tokens,s,opr);
		}
		else if(expr[i] == '-'  &&
			isUnary(expr,i,tokens) &&
			i+1<expr_len &&
			isdigit(expr[i+1]))
		{
			parse_number(expr,tokens,s,opr);
		}
		else if (opr!= nullptr && opr->inArray(expr[i]))
		{
			parse_opr(expr,tokens,s,opr);
		}
		else if( isalpha(expr[i]))
		{
			auto str = extract_alpha(expr,i,expr_len);
			i+=str.size()-1;
			if (tokens.size() > 0 && (tokens.back()->type == tree::VALUE || expr[i-1]==')'))
			{
				pushMulti(tokens,opr,s);
			}

			if (func != nullptr && func->isloaded(str).loaded)
			{
				parse_func(str,tokens,s,func);
			}
			else if (mem != nullptr)
			{
				parse_var(str,tokens,s,func,mem);
			}
			else
			{
				lexicalOops<VARIABLES_DISABLED_BUT_USED>();
			}
		}
		else
		{
			lexicalOops<UNKNOWN_CHAR_STR>();
		}
	}
#ifndef CT_PARANTHESES

	if(!paran.empty())
	{
		lexicalOops<SYNTAX_UNMATCHED_OPENING_PARANTHESES>();
	}
	else
	{
		tokens.shrink_to_fit();
	}
#else
	tokens.shrink_to_fit();
#endif //SRICT_PARATHESES
	return  {*(s.start) ,tokens};
}

namespace __internal
{
//****************************************************
//* Util
//***************************************************

void pushMulti(tvec& t,operators::operators_interface* opr, i_state& s)
{
	if (opr->inArray('*'))
	{
		ptr_protect<token::operatorToken*,false> tmp(new token::operatorToken(opr->getCurrent()));
		tmp->startPos=*s.i;
		tmp->endPos=*s.i;
		tmp->baseWheight +=*s.operWheight;
		updateStartPoint(t,s,tmp->baseWheight);
		t.push_back(tmp.ptr());
		tmp.release();

	}
}

void pushValue(tvec& tokens ,i_state& s, double value)
{
	ptr_protect<token::valueToken*, false> tmp_val(new token::valueToken(*(s.i),*(s.i)));
	tmp_val->value = value;
	tokens.push_back(tmp_val.ptr());
	tmp_val.release();
}

void updateStartPoint(tvec& t, i_state& s, size_t w)
{
	if(w <= *s.lowestWheight)
	{
		*s.lowestWheight = w;
		*(s.start)=t.size();
	}
}
//*****************************************************
//* Parantheses parsers
//*
//*****************************************************

void parse_parantheses1(tvec& tokens,
			i_state& s,
			pstack& stack,
			operators::operators_interface* opr)
{
	auto tmp_i=*(s.i);
	auto type = (tokens.size() > 0) ? tokens.back()->type : tree::UNKNOWN ;
	if( type == tree::VALUE || type ==tree::VARIABLE)
	{
		pushMulti(tokens,opr,s);
		tmp_i++;
	}
	tokens.push_back(new token::parenthesesToken(tmp_i,tmp_i));
	stack.push((token::parenthesesToken*) tokens.back());
	(*s.operWheight)+=5;
	return;

}

void parse_parantheses2(tvec& tokens ,i_state& s, pstack& p)
{
	if(p.empty())
	{
		lexicalOops<SYNTAX_UNMATCHED_CLOSING_PARANTHESES>();

	}
	else
	{
		token::parenthesesToken* tmp = p.top();
		p.pop();
		tmp->opposit=*(s.i);
		token::parenthesesToken * tmp2 = new token::parenthesesToken(*(s.i), *(s.i));
		tmp2->opposit = tmp->startPos;
		tokens.push_back(tmp2);
		*(s.operWheight)-=5;
		return;

	}
}
//**************************************************
//*	number parser
//*
//**************************************************

void parse_number(const char * expr, tvec& tokens, i_state& s,operators::operators_interface* opr)
{
	if(tokens.size() > 0)
	{
		auto tmp=tokens.back();
		if(tmp->type == tree::VARIABLE)
		{
			pushMulti(tokens,opr,s);
		}
		else if(expr[*(s.i)-1]==')')
		{
			pushMulti(tokens,opr,s);
		}
	}
	ptr_protect<token::valueToken*, false> tmp(new token::valueToken(*(s.i), 0));
	short valueLength=0;
	for(unsigned int i2 =*(s.i)+1; i2 < *(s.lenght) ; i2++)
	{
		if( !isdigit(expr[i2]) &&
			expr[i2] !='.' &&
			expr[i2] != 'e' &&
			expr[i2] != '-' )
		{
			break;
		}
		else if(expr[i2] == 'e')
		{
			if(i2+1 < *(s.lenght) &&
				( !isdigit(expr[i2+1]) && expr[i2+1] !='-')
				)
			{
				lexicalOops<SYNTAX_EXP_AFTER_E>();
			}
			else if(i2+1 >=*(s.lenght))
			{
				lexicalOops<SYNTAX_EXP_AFTER_E>();
			}

		}
		else if(expr[i2] == '-')
		{
			//If expression is > instead of >= it will fail for expressions as 0-x^2
			if(i2-1 < *(s.lenght)  && expr[i2-1] != 'e')
				break;

		}
			valueLength++;
	}
	tmp->endPos = *(s.i)+valueLength;
	short tmp_str_length = tmp->endPos+1 - tmp->startPos;
	//Create a temporary string from which we can convert the string to a double
	char* tmp_str = nullptr;
        tmp_str = new char[tmp_str_length+1];
	memcpy(tmp_str, &expr[*(s.i)], (tmp_str_length*sizeof(char)) );
	tmp_str[tmp_str_length] = '\0';
	tmp->value =  atof(tmp_str);
	delete[] tmp_str;
	tokens.push_back(tmp.ptr());
	tmp.release(); //Release ownership of pointer
	*(s.i)+=valueLength;
	return;

}

//**********************************************
//*	Operator parser
//*
//**********************************************
void parse_opr(const char* expr, tvec& tokens ,i_state& s,operators::operators_interface* opr)
{
	//Following test compensates for implicit -1 situations like -x or 2*-(2+x) which
	//will be extended to -1*x and 2*-1*(2+x) where the multiplication sign
	//between -1 and the other terme has an higher than usal weight
	if (expr[*(s.i)] == '-')
	{
		tree::tokenType test_type;
		if (tokens.size() > 0)
		{
			test_type = tokens.back()->type;
		}
		else
		{
			test_type = tree::UNKNOWN;
		}

		if ( (*(s.i) - 1 > 0 && (test_type == tree::OPERATOR || expr[*(s.i) - 1] == '(')) ||
				*(s.i) == 0)
		{
			if (opr->inArray('*'))
			{
				pushValue(tokens,s,-1);
				pushMulti(tokens,opr,s);
			}
		}
	}

	ptr_protect<token::operatorToken*, false> tmp(new token::operatorToken(opr->getCurrent()));
	tmp->startPos=*(s.i);
	tmp->endPos=*(s.i);
	tmp->baseWheight +=*(s.operWheight);
	updateStartPoint(tokens,s,tmp->baseWheight);
	if (tmp->operChar == '=')
	{
		if (tokens.size() ==0 || tokens.back()->type != tokenType::VARIABLE)
		{
			lexicalOops<SYNTAX_ASSIGMENT_NEEDS_VAR>();
		}
		else
		{
			//token is going to be used in an assigment
			//and should thus not be pushed to the stack
			static_cast<token::variableToken*>(tokens.back())->_stack = false;
		}
	}
	tokens.push_back(tmp.ptr());
	tmp.release();
	return;
}

//*****************************************
//*	Function Parser
//*
//*****************************************

void parse_func(std::string str,
		tvec& tokens,
		i_state& s,
		math_func::function_interface* func)
{
	token::funcToken * tmp_ptr;
	math_func::func_type type = func->type();
	auto startPos=*(s.i);
	auto endPos = *(s.i)+str.size();
	if (type == math_func::func_type::GENERAL )
	{
		tmp_ptr = new token::funcToken(startPos, endPos, (token::funcToken::generalFuncPtr)func->get(str));
	}
	else if (type == math_func::func_type::FAST)
	{
		tmp_ptr = new token::funcToken(startPos, endPos, (token::funcToken::funcPtr)func->get(str));
	}
        else
        {
            tmp_ptr = new token::funcToken(startPos,endPos,func->getFunctor(str));
        }

	ptr_protect<token::funcToken *, false> tmp(tmp_ptr);

	tmp->baseWheight += *(s.operWheight);
	updateStartPoint(tokens,s,tmp->baseWheight);
	tokens.push_back(tmp.ptr());
	tmp.release();
}

void parse_var(std::string str,
		tvec& tokens,
		i_state& s,
		math_func::function_interface* func,
		memory::memory* mem)
{

	token::variableToken * tmp = new token::variableToken(*(s.i),*(s.i)+str.size() , mem,func);
	tmp->variableName = str;
	tokens.push_back(tmp);
}

}

<|endoftext|>


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

#include "printing/pdf_metafile_skia.h"

#include "base/eintr_wrapper.h"
#include "base/file_descriptor_posix.h"
#include "base/file_util.h"
#include "base/hash_tables.h"
#include "base/metrics/histogram.h"
#include "skia/ext/vector_platform_device_skia.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/pdf/SkPDFDevice.h"
#include "third_party/skia/include/pdf/SkPDFDocument.h"
#include "third_party/skia/include/pdf/SkPDFFont.h"
#include "third_party/skia/include/pdf/SkPDFPage.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"

namespace {
  typedef base::hash_map<SkFontID, SkAdvancedTypefaceMetrics::FontType>
      FontTypeMap;
};

namespace printing {

struct PdfMetafileSkiaData {
  SkRefPtr<SkPDFDevice> current_page_;
  SkPDFDocument pdf_doc_;
  SkDynamicMemoryWStream pdf_stream_;
  FontTypeMap font_type_stats_;
};

PdfMetafileSkia::~PdfMetafileSkia() {}

bool PdfMetafileSkia::Init() {
  return true;
}
bool PdfMetafileSkia::InitFromData(const void* src_buffer,
                                   uint32 src_buffer_size) {
  return data_->pdf_stream_.write(src_buffer, src_buffer_size);
}

SkDevice* PdfMetafileSkia::StartPageForVectorCanvas(
    const gfx::Size& page_size, const gfx::Rect& content_area,
    const float& scale_factor) {
  DCHECK(data_->current_page_.get() == NULL);

  // Adjust for the margins and apply the scale factor.
  SkMatrix transform;
  transform.setTranslate(SkIntToScalar(content_area.x()),
                         SkIntToScalar(content_area.y()));
  transform.preScale(SkFloatToScalar(scale_factor),
                     SkFloatToScalar(scale_factor));

  // TODO(ctguil): Refactor: don't create the PDF device explicitly here.
  SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
  SkISize pdf_content_size =
      SkISize::Make(content_area.width(), content_area.height());
  SkRefPtr<SkPDFDevice> pdf_device =
      new SkPDFDevice(pdf_page_size, pdf_content_size, transform);
  pdf_device->unref();  // SkRefPtr and new both took a reference.
  skia::VectorPlatformDeviceSkia* device =
      new skia::VectorPlatformDeviceSkia(pdf_device.get());
  data_->current_page_ = device->PdfDevice();
  return device;
}

bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
                                const gfx::Rect& content_area,
                                const float& scale_factor) {
  NOTREACHED();
  return NULL;
}

bool PdfMetafileSkia::FinishPage() {
  DCHECK(data_->current_page_.get());

  const SkTDArray<SkPDFFont*>& font_resources =
      data_->current_page_->getFontResources();
  for (int i = 0; i < font_resources.count(); i++) {
    SkFontID key = font_resources[i]->typeface()->uniqueID();
    data_->font_type_stats_[key] = font_resources[i]->getType();
  }

  data_->pdf_doc_.appendPage(data_->current_page_);
  data_->current_page_ = NULL;
  return true;
}

bool PdfMetafileSkia::FinishDocument() {
  // Don't do anything if we've already set the data in InitFromData.
  if (data_->pdf_stream_.getOffset())
    return true;

  if (data_->current_page_.get())
    FinishPage();

  for (FontTypeMap::const_iterator it = data_->font_type_stats_.begin();
       it != data_->font_type_stats_.end();
       it++) {
    UMA_HISTOGRAM_ENUMERATION(
        "PrintPreview.FontType",
        it->second,
        SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1);
  }

  return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
}

uint32 PdfMetafileSkia::GetDataSize() const {
  return data_->pdf_stream_.getOffset();
}

bool PdfMetafileSkia::GetData(void* dst_buffer,
                              uint32 dst_buffer_size) const {
  if (dst_buffer_size < GetDataSize())
    return false;

  memcpy(dst_buffer, data_->pdf_stream_.getStream(), dst_buffer_size);
  return true;
}

bool PdfMetafileSkia::SaveTo(const FilePath& file_path) const {
  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
  if (file_util::WriteFile(file_path, data_->pdf_stream_.getStream(),
                           GetDataSize()) != static_cast<int>(GetDataSize())) {
    DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
    return false;
  }
  return true;
}

gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
  // TODO(vandebo) add a method to get the page size for a given page to
  // SkPDFDocument.
  NOTIMPLEMENTED();
  return gfx::Rect();
}

unsigned int PdfMetafileSkia::GetPageCount() const {
  // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
  NOTIMPLEMENTED();
  return 0;
}

gfx::NativeDrawingContext PdfMetafileSkia::context() const {
  NOTREACHED();
  return NULL;
}

#if defined(OS_WIN)
bool PdfMetafileSkia::Playback(gfx::NativeDrawingContext hdc,
                               const RECT* rect) const {
  NOTREACHED();
  return false;
}

bool PdfMetafileSkia::SafePlayback(gfx::NativeDrawingContext hdc) const {
  NOTREACHED();
  return false;
}

HENHMETAFILE PdfMetafileSkia::emf() const {
  NOTREACHED();
  return NULL;
}
#endif  // if defined(OS_WIN)

#if defined(OS_CHROMEOS)
bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);

  if (fd.fd < 0) {
    DLOG(ERROR) << "Invalid file descriptor!";
    return false;
  }

  bool result = true;
  if (file_util::WriteFileDescriptor(fd.fd, data_->pdf_stream_.getStream(),
                                     GetDataSize()) !=
      static_cast<int>(GetDataSize())) {
    DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
    result = false;
  }

  if (fd.auto_close) {
    if (HANDLE_EINTR(close(fd.fd)) < 0) {
      DPLOG(WARNING) << "close";
      result = false;
    }
  }
  return result;
}
#endif

PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {}

}  // namespace printing
<commit_msg>Do all the font UMA work in PdfMetafileSkia::FinishDocument.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "printing/pdf_metafile_skia.h"

#include "base/eintr_wrapper.h"
#include "base/file_descriptor_posix.h"
#include "base/file_util.h"
#include "base/hash_tables.h"
#include "base/metrics/histogram.h"
#include "skia/ext/vector_platform_device_skia.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/pdf/SkPDFDevice.h"
#include "third_party/skia/include/pdf/SkPDFDocument.h"
#include "third_party/skia/include/pdf/SkPDFFont.h"
#include "third_party/skia/include/pdf/SkPDFPage.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"

namespace printing {

struct PdfMetafileSkiaData {
  SkRefPtr<SkPDFDevice> current_page_;
  SkPDFDocument pdf_doc_;
  SkDynamicMemoryWStream pdf_stream_;
};

PdfMetafileSkia::~PdfMetafileSkia() {}

bool PdfMetafileSkia::Init() {
  return true;
}
bool PdfMetafileSkia::InitFromData(const void* src_buffer,
                                   uint32 src_buffer_size) {
  return data_->pdf_stream_.write(src_buffer, src_buffer_size);
}

SkDevice* PdfMetafileSkia::StartPageForVectorCanvas(
    const gfx::Size& page_size, const gfx::Rect& content_area,
    const float& scale_factor) {
  DCHECK(data_->current_page_.get() == NULL);

  // Adjust for the margins and apply the scale factor.
  SkMatrix transform;
  transform.setTranslate(SkIntToScalar(content_area.x()),
                         SkIntToScalar(content_area.y()));
  transform.preScale(SkFloatToScalar(scale_factor),
                     SkFloatToScalar(scale_factor));

  // TODO(ctguil): Refactor: don't create the PDF device explicitly here.
  SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
  SkISize pdf_content_size =
      SkISize::Make(content_area.width(), content_area.height());
  SkRefPtr<SkPDFDevice> pdf_device =
      new SkPDFDevice(pdf_page_size, pdf_content_size, transform);
  pdf_device->unref();  // SkRefPtr and new both took a reference.
  skia::VectorPlatformDeviceSkia* device =
      new skia::VectorPlatformDeviceSkia(pdf_device.get());
  data_->current_page_ = device->PdfDevice();
  return device;
}

bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
                                const gfx::Rect& content_area,
                                const float& scale_factor) {
  NOTREACHED();
  return NULL;
}

bool PdfMetafileSkia::FinishPage() {
  DCHECK(data_->current_page_.get());

  data_->pdf_doc_.appendPage(data_->current_page_);
  data_->current_page_ = NULL;
  return true;
}

bool PdfMetafileSkia::FinishDocument() {
  // Don't do anything if we've already set the data in InitFromData.
  if (data_->pdf_stream_.getOffset())
    return true;

  if (data_->current_page_.get())
    FinishPage();

  base::hash_set<SkFontID> font_set;

  const SkTDArray<SkPDFPage*>& pages = data_->pdf_doc_.getPages();
  for (int page_number = 0; page_number < pages.count(); page_number++) {
    const SkTDArray<SkPDFFont*>& font_resources =
        pages[page_number]->getFontResources();
    for (int font = 0; font < font_resources.count(); font++) {
      SkFontID font_id = font_resources[font]->typeface()->uniqueID();
      if (font_set.find(font_id) == font_set.end()) {
        font_set.insert(font_id);
        UMA_HISTOGRAM_ENUMERATION(
            "PrintPreview.FontType",
            font_resources[font]->getType(),
            SkAdvancedTypefaceMetrics::kNotEmbeddable_Font + 1);
      }
    }
  }

  return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
}

uint32 PdfMetafileSkia::GetDataSize() const {
  return data_->pdf_stream_.getOffset();
}

bool PdfMetafileSkia::GetData(void* dst_buffer,
                              uint32 dst_buffer_size) const {
  if (dst_buffer_size < GetDataSize())
    return false;

  memcpy(dst_buffer, data_->pdf_stream_.getStream(), dst_buffer_size);
  return true;
}

bool PdfMetafileSkia::SaveTo(const FilePath& file_path) const {
  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
  if (file_util::WriteFile(file_path, data_->pdf_stream_.getStream(),
                           GetDataSize()) != static_cast<int>(GetDataSize())) {
    DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
    return false;
  }
  return true;
}

gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
  // TODO(vandebo) add a method to get the page size for a given page to
  // SkPDFDocument.
  NOTIMPLEMENTED();
  return gfx::Rect();
}

unsigned int PdfMetafileSkia::GetPageCount() const {
  // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
  NOTIMPLEMENTED();
  return 0;
}

gfx::NativeDrawingContext PdfMetafileSkia::context() const {
  NOTREACHED();
  return NULL;
}

#if defined(OS_WIN)
bool PdfMetafileSkia::Playback(gfx::NativeDrawingContext hdc,
                               const RECT* rect) const {
  NOTREACHED();
  return false;
}

bool PdfMetafileSkia::SafePlayback(gfx::NativeDrawingContext hdc) const {
  NOTREACHED();
  return false;
}

HENHMETAFILE PdfMetafileSkia::emf() const {
  NOTREACHED();
  return NULL;
}
#endif  // if defined(OS_WIN)

#if defined(OS_CHROMEOS)
bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);

  if (fd.fd < 0) {
    DLOG(ERROR) << "Invalid file descriptor!";
    return false;
  }

  bool result = true;
  if (file_util::WriteFileDescriptor(fd.fd, data_->pdf_stream_.getStream(),
                                     GetDataSize()) !=
      static_cast<int>(GetDataSize())) {
    DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
    result = false;
  }

  if (fd.auto_close) {
    if (HANDLE_EINTR(close(fd.fd)) < 0) {
      DPLOG(WARNING) << "close";
      result = false;
    }
  }
  return result;
}
#endif

PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {}

}  // namespace printing
<|endoftext|>


<commit_before>#include <stdlib.h>
#include "gason.h"

static unsigned char ctype[256];

static const struct ctype_init_t
{
	ctype_init_t()
	{
		ctype[(int)'\0'] |= 002;
		for (const char *s = "\t\n\v\f\r\x20"; *s; ++s) ctype[(int)*s] |= 001;
		for (const char *s = ",:]}"; *s; ++s) ctype[(int)*s] |= 002;
		for (const char *s = "+-"; *s; ++s) ctype[(int)*s] |= 004;
		for (const char *s = "0123456789"; *s; ++s) ctype[(int)*s] |= 010;
		for (const char *s = "ABCDEF" "abcdef"; *s; ++s) ctype[(int)*s] |= 020;
	}
} ctype_init;

inline bool is_space(char c) { return (ctype[(int)(unsigned char)c] & 001) != 0; }
inline bool is_delim(char c) { return (ctype[(int)(unsigned char)c] & 003) != 0; }
inline bool is_sign(char c) { return (ctype[(int)(unsigned char)c] & 004) != 0; }
inline bool is_dec(char c) { return (ctype[(int)(unsigned char)c] & 010) != 0; }
inline bool is_hex(char c) { return (ctype[(int)(unsigned char)c] & 030) != 0; }

inline int char2int(char c)
{
	if (c >= 'a') return c - 'a' + 10;
	if (c >= 'A') return c - 'A' + 10;
	return c - '0';
}

static double str2float(const char *str, char **endptr)
{
	double sign = is_sign(*str) && *str++ == '-' ? -1 : 1;
	double result = 0;
	while (is_dec(*str)) result = (result * 10) + (*str++ - '0');
	if (*str == '.')
	{
		++str;
		double fraction = 1;
		while (is_dec(*str)) fraction *= 0.1, result += (*str++ - '0') * fraction;
	}
	if (*str == 'e' || *str == 'E')
	{
		++str;
		double base = is_sign(*str) && *str++ == '-' ? 0.1 : 10;
		int exponent = 0;
		while (is_dec(*str)) exponent = (exponent * 10) + (*str++ - '0');
		double power = 1;
		for (; exponent; exponent >>= 1, base *= base) if (exponent & 1) power *= base;
		result *= power;
	}
	*endptr = (char *)str;
	return sign * result;
}

JsonAllocator::~JsonAllocator()
{
	while (head)
	{
		Zone *temp = head->next;
		free(head);
		head = temp;
	}
}

inline void *align_pointer(void *x, size_t align) { return (void *)(((uintptr_t)x + (align - 1)) & ~(align - 1)); }

void *JsonAllocator::allocate(size_t n, size_t align)
{
	if (head)
	{
		char *p = (char *)align_pointer(head->end, align);
		if (p + n <= (char *)head + JSON_ZONE_SIZE)
		{
			head->end = p + n;
			return p;
		}
	}
	size_t zone_size = sizeof(Zone) + n + align;
	Zone *z = (Zone *)malloc(zone_size <= JSON_ZONE_SIZE ? JSON_ZONE_SIZE : zone_size);
	char *p = (char *)align_pointer(z + 1, align);
	z->end = p + n;
	if (zone_size <= JSON_ZONE_SIZE || head == nullptr)
	{
		z->next = head;
		head = z;
	}
	else
	{
		z->next = head->next;
		head->next = z;
	}
	return p;
}

struct JsonList
{
	JsonTag tag;
	JsonValue node;
	char *key;

	void grow_the_tail(JsonNode *p)
	{
		JsonNode *tail = (JsonNode *)node.getPayload();
		if (tail)
		{
			p->next = tail->next;
			tail->next = p;
		}
		else
		{
			p->next = p;
		}
		node = JsonValue(tag, p);
	}

	JsonValue cut_the_head()
	{
		JsonNode *tail = (JsonNode *)node.getPayload();
		if (tail)
		{
			JsonNode *head = tail->next;
			tail->next = nullptr;
			return JsonValue(tag, head);
		}
		return node;
	}
};

JsonParseStatus json_parse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator)
{
	JsonList stack[JSON_STACK_SIZE];
	int top = -1;
	bool separator = true;
	while (*str)
	{
		JsonValue o;
		while (*str && is_space(*str)) ++str;
		*endptr = str++;
		switch (**endptr)
		{
			case '\0':
				continue;
			case '-':
				if (!is_dec(*str) && *str != '.') return *endptr = str, JSON_PARSE_BAD_NUMBER;
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				o = JsonValue(str2float(*endptr, &str));
				if (!is_delim(*str)) return *endptr = str, JSON_PARSE_BAD_NUMBER;
				break;
			case '"':
				o = JsonValue(JSON_TAG_STRING, str);
				for (char *s = str; *str; ++s, ++str)
				{
					int c = *s = *str;
					if (c == '\\')
					{
						c = *++str;
						switch (c)
						{
							case '\\':
							case '"':
							case '/': *s = c; break;
							case 'b': *s = '\b'; break;
							case 'f': *s = '\f'; break;
							case 'n': *s = '\n'; break;
							case 'r': *s = '\r'; break;
							case 't': *s = '\t'; break;
							case 'u':
								c = 0;
								for (int i = 0; i < 4; ++i)
								{
									if (!is_hex(*++str)) return *endptr = str, JSON_PARSE_BAD_STRING;
									c = c * 16 + char2int(*str);
								}
								if (c < 0x80)
								{
									*s = c;
								}
								else if (c < 0x800)
								{
									*s++ = 0xC0 | (c >> 6);
									*s = 0x80 | (c & 0x3F);
								}
								else
								{
									*s++ = 0xE0 | (c >> 12);
									*s++ = 0x80 | ((c >> 6) & 0x3F);
									*s = 0x80 | (c & 0x3F);
								}
								break;
							default:
								return *endptr = str, JSON_PARSE_BAD_STRING;
						}
					}
					else if (c == '"')
					{
						*s = 0;
						++str;
						break;
					}
				}
				if (!is_delim(*str)) return *endptr = str, JSON_PARSE_BAD_STRING;
				break;
			case 't':
				for (const char *s = "rue"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				o = JsonValue(JSON_TAG_BOOL, (void *)true);
				break;
			case 'f':
				for (const char *s = "alse"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				o = JsonValue(JSON_TAG_BOOL, (void *)false);
				break;
			case 'n':
				for (const char *s = "ull"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				break;
			case ']':
				if (top == -1) return JSON_PARSE_STACK_UNDERFLOW;
				if (stack[top].tag != JSON_TAG_ARRAY) return JSON_PARSE_MISMATCH_BRACKET;
				o = stack[top--].cut_the_head();
				break;
			case '}':
				if (top == -1) return JSON_PARSE_STACK_UNDERFLOW;
				if (stack[top].tag != JSON_TAG_OBJECT) return JSON_PARSE_MISMATCH_BRACKET;
				o = stack[top--].cut_the_head();
				break;
			case '[':
				if (++top == JSON_STACK_SIZE) return JSON_PARSE_STACK_OVERFLOW;
				stack[top] = {JSON_TAG_ARRAY, JsonValue(JSON_TAG_ARRAY, nullptr), nullptr};
				continue;
			case '{':
				if (++top == JSON_STACK_SIZE) return JSON_PARSE_STACK_OVERFLOW;
				stack[top] = {JSON_TAG_OBJECT, JsonValue(JSON_TAG_OBJECT, nullptr), nullptr};
				continue;
			case ':':
				if (separator || stack[top].key == nullptr) return JSON_PARSE_UNEXPECTED_CHARACTER;
				separator = true;
				continue;
			case ',':
				if (separator || stack[top].key != nullptr) return JSON_PARSE_UNEXPECTED_CHARACTER;
				separator = true;
				continue;
			default:
				return JSON_PARSE_UNEXPECTED_CHARACTER;
		}

		separator = false;

		if (top == -1)
		{
			*endptr = str;
			*value = o;
			return JSON_PARSE_OK;
		}

		if (stack[top].tag == JSON_TAG_OBJECT)
		{
			if (!stack[top].key)
			{
				if (o.getTag() != JSON_TAG_STRING) return JSON_PARSE_UNQUOTED_KEY;
				stack[top].key = o.toString();
				continue;
			}
			JsonNode *p = (JsonNode *)allocator.allocate(sizeof(JsonNode));
			p->value = o;
			p->key = stack[top].key;
			stack[top].key = nullptr;
			stack[top].grow_the_tail((JsonNode *)p);
			continue;
		}

		JsonNode *p = (JsonNode *)allocator.allocate(sizeof(JsonNode) - sizeof(char *));
		p->value = o;
		stack[top].grow_the_tail(p);
	}
	return JSON_PARSE_BREAKING_BAD;
}
<commit_msg>Remove custom ctype functions<commit_after>#include <stdlib.h>
#include <ctype.h>
#include "gason.h"

inline bool is_delim(char c) { return isspace(c) || c == ',' || c == ':' || c == ']' || c == '}' || c == '\0'; }
inline bool is_sign(char c) { return c == '-' || c == '+'; }

inline int char2int(char c)
{
	if (c >= 'a') return c - 'a' + 10;
	if (c >= 'A') return c - 'A' + 10;
	return c - '0';
}

static double str2float(const char *str, char **endptr)
{
	double sign = is_sign(*str) && *str++ == '-' ? -1 : 1;
	double result = 0;
	while (isdigit(*str)) result = (result * 10) + (*str++ - '0');
	if (*str == '.')
	{
		++str;
		double fraction = 1;
		while (isdigit(*str)) fraction *= 0.1, result += (*str++ - '0') * fraction;
	}
	if (*str == 'e' || *str == 'E')
	{
		++str;
		double base = is_sign(*str) && *str++ == '-' ? 0.1 : 10;
		int exponent = 0;
		while (isdigit(*str)) exponent = (exponent * 10) + (*str++ - '0');
		double power = 1;
		for (; exponent; exponent >>= 1, base *= base) if (exponent & 1) power *= base;
		result *= power;
	}
	*endptr = (char *)str;
	return sign * result;
}

JsonAllocator::~JsonAllocator()
{
	while (head)
	{
		Zone *temp = head->next;
		free(head);
		head = temp;
	}
}

inline void *align_pointer(void *x, size_t align) { return (void *)(((uintptr_t)x + (align - 1)) & ~(align - 1)); }

void *JsonAllocator::allocate(size_t n, size_t align)
{
	if (head)
	{
		char *p = (char *)align_pointer(head->end, align);
		if (p + n <= (char *)head + JSON_ZONE_SIZE)
		{
			head->end = p + n;
			return p;
		}
	}
	size_t zone_size = sizeof(Zone) + n + align;
	Zone *z = (Zone *)malloc(zone_size <= JSON_ZONE_SIZE ? JSON_ZONE_SIZE : zone_size);
	char *p = (char *)align_pointer(z + 1, align);
	z->end = p + n;
	if (zone_size <= JSON_ZONE_SIZE || head == nullptr)
	{
		z->next = head;
		head = z;
	}
	else
	{
		z->next = head->next;
		head->next = z;
	}
	return p;
}

struct JsonList
{
	JsonTag tag;
	JsonValue node;
	char *key;

	void grow_the_tail(JsonNode *p)
	{
		JsonNode *tail = (JsonNode *)node.getPayload();
		if (tail)
		{
			p->next = tail->next;
			tail->next = p;
		}
		else
		{
			p->next = p;
		}
		node = JsonValue(tag, p);
	}

	JsonValue cut_the_head()
	{
		JsonNode *tail = (JsonNode *)node.getPayload();
		if (tail)
		{
			JsonNode *head = tail->next;
			tail->next = nullptr;
			return JsonValue(tag, head);
		}
		return node;
	}
};

JsonParseStatus json_parse(char *str, char **endptr, JsonValue *value, JsonAllocator &allocator)
{
	JsonList stack[JSON_STACK_SIZE];
	int top = -1;
	bool separator = true;
	while (*str)
	{
		JsonValue o;
		while (*str && isspace(*str)) ++str;
		*endptr = str++;
		switch (**endptr)
		{
			case '\0':
				continue;
			case '-':
				if (!isdigit(*str) && *str != '.') return *endptr = str, JSON_PARSE_BAD_NUMBER;
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				o = JsonValue(str2float(*endptr, &str));
				if (!is_delim(*str)) return *endptr = str, JSON_PARSE_BAD_NUMBER;
				break;
			case '"':
				o = JsonValue(JSON_TAG_STRING, str);
				for (char *s = str; *str; ++s, ++str)
				{
					int c = *s = *str;
					if (c == '\\')
					{
						c = *++str;
						switch (c)
						{
							case '\\':
							case '"':
							case '/': *s = c; break;
							case 'b': *s = '\b'; break;
							case 'f': *s = '\f'; break;
							case 'n': *s = '\n'; break;
							case 'r': *s = '\r'; break;
							case 't': *s = '\t'; break;
							case 'u':
								c = 0;
								for (int i = 0; i < 4; ++i)
								{
									if (!isxdigit(*++str)) return *endptr = str, JSON_PARSE_BAD_STRING;
									c = c * 16 + char2int(*str);
								}
								if (c < 0x80)
								{
									*s = c;
								}
								else if (c < 0x800)
								{
									*s++ = 0xC0 | (c >> 6);
									*s = 0x80 | (c & 0x3F);
								}
								else
								{
									*s++ = 0xE0 | (c >> 12);
									*s++ = 0x80 | ((c >> 6) & 0x3F);
									*s = 0x80 | (c & 0x3F);
								}
								break;
							default:
								return *endptr = str, JSON_PARSE_BAD_STRING;
						}
					}
					else if (c == '"')
					{
						*s = 0;
						++str;
						break;
					}
				}
				if (!is_delim(*str)) return *endptr = str, JSON_PARSE_BAD_STRING;
				break;
			case 't':
				for (const char *s = "rue"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				o = JsonValue(JSON_TAG_BOOL, (void *)true);
				break;
			case 'f':
				for (const char *s = "alse"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				o = JsonValue(JSON_TAG_BOOL, (void *)false);
				break;
			case 'n':
				for (const char *s = "ull"; *s; ++s, ++str)
				{
					if (*s != *str) return JSON_PARSE_BAD_IDENTIFIER;
				}
				if (!is_delim(*str)) return JSON_PARSE_BAD_IDENTIFIER;
				break;
			case ']':
				if (top == -1) return JSON_PARSE_STACK_UNDERFLOW;
				if (stack[top].tag != JSON_TAG_ARRAY) return JSON_PARSE_MISMATCH_BRACKET;
				o = stack[top--].cut_the_head();
				break;
			case '}':
				if (top == -1) return JSON_PARSE_STACK_UNDERFLOW;
				if (stack[top].tag != JSON_TAG_OBJECT) return JSON_PARSE_MISMATCH_BRACKET;
				o = stack[top--].cut_the_head();
				break;
			case '[':
				if (++top == JSON_STACK_SIZE) return JSON_PARSE_STACK_OVERFLOW;
				stack[top] = {JSON_TAG_ARRAY, JsonValue(JSON_TAG_ARRAY, nullptr), nullptr};
				continue;
			case '{':
				if (++top == JSON_STACK_SIZE) return JSON_PARSE_STACK_OVERFLOW;
				stack[top] = {JSON_TAG_OBJECT, JsonValue(JSON_TAG_OBJECT, nullptr), nullptr};
				continue;
			case ':':
				if (separator || stack[top].key == nullptr) return JSON_PARSE_UNEXPECTED_CHARACTER;
				separator = true;
				continue;
			case ',':
				if (separator || stack[top].key != nullptr) return JSON_PARSE_UNEXPECTED_CHARACTER;
				separator = true;
				continue;
			default:
				return JSON_PARSE_UNEXPECTED_CHARACTER;
		}

		separator = false;

		if (top == -1)
		{
			*endptr = str;
			*value = o;
			return JSON_PARSE_OK;
		}

		if (stack[top].tag == JSON_TAG_OBJECT)
		{
			if (!stack[top].key)
			{
				if (o.getTag() != JSON_TAG_STRING) return JSON_PARSE_UNQUOTED_KEY;
				stack[top].key = o.toString();
				continue;
			}
			JsonNode *p = (JsonNode *)allocator.allocate(sizeof(JsonNode));
			p->value = o;
			p->key = stack[top].key;
			stack[top].key = nullptr;
			stack[top].grow_the_tail((JsonNode *)p);
			continue;
		}

		JsonNode *p = (JsonNode *)allocator.allocate(sizeof(JsonNode) - sizeof(char *));
		p->value = o;
		stack[top].grow_the_tail(p);
	}
	return JSON_PARSE_BREAKING_BAD;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include <votca/tools/getline.h>
#include <boost/algorithm/string.hpp>
#include "groreader.h"

namespace votca { namespace csg {

bool GROReader::ReadTopology(string file,  Topology &top)
{
   _topology = true;
   top.Cleanup();

   _fl.open(file.c_str());
    if(!_fl.is_open())
        throw std::ios_base::failure("Error on open topology file: " + file);

   NextFrame(top);

    _fl.close();

    return true;
}

bool GROReader::Open(const string &file)
{
    _fl.open(file.c_str());
    if(!_fl.is_open())
        throw std::ios_base::failure("Error on open trajectory file: " + file);
    return true;
}

void GROReader::Close()
{
    _fl.close();
}

bool GROReader::FirstFrame(Topology &top)
{
    _topology = false;
    NextFrame(top);
    return true;
}

bool GROReader::NextFrame(Topology &top)
{
    string tmp;
    getline(_fl, tmp);//title
    getline(_fl, tmp);//number atoms
    int natoms = atoi(tmp.c_str());
    if(!_topology && natoms != top.BeadCount())
      throw std::runtime_error("number of beads in topology and trajectory differ");

    for(int i=0;i<natoms; i++) {
        char c[6];
        _fl.read(c, 5);
        c[5] = 0; //fix trailing char

        int resnr = atoi(c);
        //residue name
        _fl.read(c, 5);
        if(resnr >= top.ResidueCount()) {
            if (top.ResidueCount()==0) //gro resnr start with 1 but VOTCA starts with 0
              top.CreateResidue("ZERO"); // create 0 res, to allow to keep gro numbering
            string withoutWhitespace;
            withoutWhitespace  = string(c);
            boost::algorithm::trim(withoutWhitespace);
            top.CreateResidue(withoutWhitespace);
        }
        //atom name
        char atomname[6];
        _fl.read(atomname, 5);
        atomname[5]=0; //fix trailing character
        string atomnameWoWs;
        atomnameWoWs  = string(atomname);
        boost::algorithm::trim(atomnameWoWs);
        Bead *b;
        if(_topology){
	  b = top.CreateBead(1, atomnameWoWs, top.GetOrCreateBeadType(atomnameWoWs), resnr, 1., 0.);
	} else {
          b = top.getBead(i);
	}
        //atom number, not needed
        char buf[5];
        _fl.read(buf, 5);
        //position
        getline(_fl, tmp); //rest of line
        string x=string(tmp,0,8); // float 8.3 ,x
        string y=string(tmp,9,8); // float 8.3 ,y
        string z=string(tmp,18,8); // float 8.3 ,z
        boost::algorithm::trim(x);
        boost::algorithm::trim(y);
        boost::algorithm::trim(z);
        b->setPos(vec(
          boost::lexical_cast<double>(x),
          boost::lexical_cast<double>(y),
          boost::lexical_cast<double>(z)
        ));
    }

    getline(_fl, tmp); //read box line
    if(_fl.eof())
      throw std::runtime_error("unexpected end of file in poly file, when boxline");
    Tokenizer tok(tmp, " ");
    vector<double> fields;
    tok.ConvertToVector<double>(fields);
    matrix box;
    if ( fields.size() == 3 ) {
      box.ZeroMatrix();
      for (int i=0;i<3;i++) box[i][i] = fields[i];
    } else if ( fields.size() == 9 ) {
      box[0][0]=  fields[0];
      box[1][1]=  fields[1];
      box[2][2]=  fields[2];
      box[1][0]=  fields[3];
      box[2][0]=  fields[4];
      box[0][1]=  fields[5];
      box[2][1]=  fields[6];
      box[0][2]=  fields[7];
      box[1][2]=  fields[8];
    } else {
      throw std::runtime_error("Error while reading box (last) line");
    }
    top.setBox(box);

    _fl.close();

    cout << "WARNING: topology created from .gro file, masses and charges are wrong!\n";

    return true;
}

}}
<commit_msg>groreader: read velocities, clean up<commit_after>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include <votca/tools/getline.h>
#include <boost/algorithm/string.hpp>
#include "groreader.h"

namespace votca { namespace csg {

bool GROReader::ReadTopology(string file,  Topology &top)
{
   _topology = true;
   top.Cleanup();

   _fl.open(file.c_str());
    if(!_fl.is_open())
        throw std::ios_base::failure("Error on open topology file: " + file);

   NextFrame(top);

    _fl.close();

    return true;
}

bool GROReader::Open(const string &file)
{
    _fl.open(file.c_str());
    if(!_fl.is_open())
        throw std::ios_base::failure("Error on open trajectory file: " + file);
    return true;
}

void GROReader::Close()
{
    _fl.close();
}

bool GROReader::FirstFrame(Topology &top)
{
    _topology = false;
    NextFrame(top);
    return true;
}

bool GROReader::NextFrame(Topology &top)
{
    string tmp;
    getline(_fl, tmp);//title
    getline(_fl, tmp);//number atoms
    int natoms = atoi(tmp.c_str());
    if(!_topology && natoms != top.BeadCount())
      throw std::runtime_error("number of beads in topology and trajectory differ");

    for(int i=0;i<natoms; i++) {
        string line;
        getline(_fl, line);
	string resNum,resName, atName, x,y,z;
	try {
          resNum= string(line,0,5); // %5i
          resName = string(line,5,5); //%5s
	  atName = string(line,10,5); // %5s
	  //atNum= string(line,15,5); // %5i not needed
	  x = string(line,20,8); // %8.3f
	  y = string(line,28,8); // %8.3f
	  z = string(line,36,8); // %8.3f
	} catch (std::out_of_range& err) {
	  throw std::runtime_error("Misformated gro file");
	}
        boost::algorithm::trim(atName);
        boost::algorithm::trim(resName);
        boost::algorithm::trim(resNum);
        boost::algorithm::trim(x);
        boost::algorithm::trim(y);
        boost::algorithm::trim(z);
	string vx,vy,vz;
	bool hasVel=true;
	try {
	  vx = string(line,44,8); // %8.4f
	  vy = string(line,52,8); // %8.4f
	  vz = string(line,60,8); // %8.4f
	} catch (std::out_of_range& err) {
	  hasVel=false;
	}

        Bead *b;
        if(_topology){
	  int resnr = boost::lexical_cast<int>(resNum);
          if(resnr >= top.ResidueCount()) {
              if (top.ResidueCount()==0) //gro resnr start with 1 but VOTCA starts with 0
                top.CreateResidue("ZERO"); // create 0 res, to allow to keep gro numbering
              top.CreateResidue(resName);
          }
          //this is not correct, but still better than no type at all!
	  BeadType *type = top.GetOrCreateBeadType(atName);

	  b = top.CreateBead(1, atName, type, resnr, 1., 0.);
	} else {
          b = top.getBead(i);
	}

        b->setPos(vec(
          boost::lexical_cast<double>(x),
          boost::lexical_cast<double>(y),
          boost::lexical_cast<double>(z)
        ));
	if (hasVel) {
          boost::algorithm::trim(vx);
          boost::algorithm::trim(vy);
          boost::algorithm::trim(vz);
          b->setVel(vec(
            boost::lexical_cast<double>(vx),
            boost::lexical_cast<double>(vy),
            boost::lexical_cast<double>(vz)
          ));
	}
    }

    getline(_fl, tmp); //read box line
    if(_fl.eof())
      throw std::runtime_error("unexpected end of file in poly file, when boxline");
    Tokenizer tok(tmp, " ");
    vector<double> fields;
    tok.ConvertToVector<double>(fields);
    matrix box;
    if ( fields.size() == 3 ) {
      box.ZeroMatrix();
      for (int i=0;i<3;i++) box[i][i] = fields[i];
    } else if ( fields.size() == 9 ) {
      box[0][0]=  fields[0];
      box[1][1]=  fields[1];
      box[2][2]=  fields[2];
      box[1][0]=  fields[3];
      box[2][0]=  fields[4];
      box[0][1]=  fields[5];
      box[2][1]=  fields[6];
      box[0][2]=  fields[7];
      box[1][2]=  fields[8];
    } else {
      throw std::runtime_error("Error while reading box (last) line");
    }
    top.setBox(box);

    _fl.close();

    cout << "WARNING: topology created from .gro file, masses and charges are wrong!\n";

    return true;
}

}}
<|endoftext|>


<commit_before>/*************************************************************************/
/*  vector3.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "vector3.h"

void Vector3::rotate(const Vector3& p_axis,float p_phi) {

	Vector3 axis1 = cross(p_axis);
	float l = axis1.length();
	if (l==0)
		return;
	axis1/=l;
	Vector3 axis2 = axis1.cross(p_axis).normalized();

	float _x = axis1.dot(*this);
	float _y = axis2.dot(*this);

	float ang = Math::atan2(_x,_y);

	ang+=p_phi;

	*this=((axis1 * Math::cos(ang)) + (axis2 * Math::sin(ang))) * length();

}

Vector3 Vector3::rotated(const Vector3& p_axis,float p_phi) const {

	Vector3 r = *this;
	r.rotate(p_axis,p_phi);
	return r;
}

void Vector3::set_axis(int p_axis,real_t p_value) {
	ERR_FAIL_INDEX(p_axis,3);
	coord[p_axis]=p_value;

}
real_t Vector3::get_axis(int p_axis) const {

        ERR_FAIL_INDEX_V(p_axis,3,0);
        return operator[](p_axis);
}

int Vector3::min_axis() const {

        return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
}
int Vector3::max_axis() const {

	return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
}

void Vector3::snap(float p_val) {

	x+=p_val/2.0;
	x-=Math::fmod(x,p_val);
	y+=p_val/2.0;
	y-=Math::fmod(y,p_val);
	z+=p_val/2.0;
	z-=Math::fmod(z,p_val);

}
Vector3 Vector3::snapped(float p_val) const {

        Vector3 v=*this;
        v.snap(p_val);
        return v;
}

Vector3 Vector3::cubic_interpolaten(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	{
		//normalize

		float ab = p0.distance_to(p1);
		float bc = p1.distance_to(p2);
		float cd = p2.distance_to(p3);

		if (ab>0)
			p0 = p1+(p0-p1)*(bc/ab);
		if (cd>0)
			p3 = p2+(p3-p2)*(bc/cd);
	}

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out = 0.5f * ( ( p1 * 2.0f) +
	( -p0 + p2 ) * t +
	( 2.0f * p0 - 5.0f * p1 + 4 * p2 - p3 ) * t2 +
	( -p0 + 3.0f * p1 - 3.0f * p2 + p3 ) * t3 );
	return out;

}

Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out = 0.5f * ( ( p1 * 2.0f) +
	( -p0 + p2 ) * t +
	( 2.0f * p0 - 5.0f * p1 + 4 * p2 - p3 ) * t2 +
	( -p0 + 3.0f * p1 - 3.0f * p2 + p3 ) * t3 );
	return out;

}

#if 0
Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	if (true) {

		float ab = p0.distance_to(p1);
		float bc = p1.distance_to(p2);
		float cd = p2.distance_to(p3);

		//if (ab>bc) {
		if (ab>0)
			p0 = p1+(p0-p1)*(bc/ab);
		//}

		//if (cd>bc) {
		if (cd>0)
			p3 = p2+(p3-p2)*(bc/cd);
		//}
	}

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out.x = 0.5f * ( ( 2.0f * p1.x ) +
	( -p0.x + p2.x ) * t +
	( 2.0f * p0.x - 5.0f * p1.x + 4 * p2.x - p3.x ) * t2 +
	( -p0.x + 3.0f * p1.x - 3.0f * p2.x + p3.x ) * t3 );
	out.y = 0.5f * ( ( 2.0f * p1.y ) +
	( -p0.y + p2.y ) * t +
	( 2.0f * p0.y - 5.0f * p1.y + 4 * p2.y - p3.y ) * t2 +
	( -p0.y + 3.0f * p1.y - 3.0f * p2.y + p3.y ) * t3 );
	out.z = 0.5f * ( ( 2.0f * p1.z ) +
	( -p0.z + p2.z ) * t +
	( 2.0f * p0.z - 5.0f * p1.z + 4 * p2.z - p3.z ) * t2 +
	( -p0.z + 3.0f * p1.z - 3.0f * p2.z + p3.z ) * t3 );
	return out;
}
# endif
Vector3::operator String() const {

	return (rtos(x)+", "+rtos(y)+", "+rtos(z));
}
<commit_msg>-fix vector rotation, fixes #1705<commit_after>/*************************************************************************/
/*  vector3.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "vector3.h"
#include "matrix3.h"

void Vector3::rotate(const Vector3& p_axis,float p_phi) {

	*this=Matrix3(p_axis,p_phi).xform(*this);
}

Vector3 Vector3::rotated(const Vector3& p_axis,float p_phi) const {

	Vector3 r = *this;
	r.rotate(p_axis,p_phi);
	return r;
}

void Vector3::set_axis(int p_axis,real_t p_value) {
	ERR_FAIL_INDEX(p_axis,3);
	coord[p_axis]=p_value;

}
real_t Vector3::get_axis(int p_axis) const {

        ERR_FAIL_INDEX_V(p_axis,3,0);
        return operator[](p_axis);
}

int Vector3::min_axis() const {

        return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
}
int Vector3::max_axis() const {

	return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
}

void Vector3::snap(float p_val) {

	x+=p_val/2.0;
	x-=Math::fmod(x,p_val);
	y+=p_val/2.0;
	y-=Math::fmod(y,p_val);
	z+=p_val/2.0;
	z-=Math::fmod(z,p_val);

}
Vector3 Vector3::snapped(float p_val) const {

        Vector3 v=*this;
        v.snap(p_val);
        return v;
}

Vector3 Vector3::cubic_interpolaten(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	{
		//normalize

		float ab = p0.distance_to(p1);
		float bc = p1.distance_to(p2);
		float cd = p2.distance_to(p3);

		if (ab>0)
			p0 = p1+(p0-p1)*(bc/ab);
		if (cd>0)
			p3 = p2+(p3-p2)*(bc/cd);
	}

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out = 0.5f * ( ( p1 * 2.0f) +
	( -p0 + p2 ) * t +
	( 2.0f * p0 - 5.0f * p1 + 4 * p2 - p3 ) * t2 +
	( -p0 + 3.0f * p1 - 3.0f * p2 + p3 ) * t3 );
	return out;

}

Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out = 0.5f * ( ( p1 * 2.0f) +
	( -p0 + p2 ) * t +
	( 2.0f * p0 - 5.0f * p1 + 4 * p2 - p3 ) * t2 +
	( -p0 + 3.0f * p1 - 3.0f * p2 + p3 ) * t3 );
	return out;

}

#if 0
Vector3 Vector3::cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const {

	Vector3 p0=p_pre_a;
	Vector3 p1=*this;
	Vector3 p2=p_b;
	Vector3 p3=p_post_b;

	if (true) {

		float ab = p0.distance_to(p1);
		float bc = p1.distance_to(p2);
		float cd = p2.distance_to(p3);

		//if (ab>bc) {
		if (ab>0)
			p0 = p1+(p0-p1)*(bc/ab);
		//}

		//if (cd>bc) {
		if (cd>0)
			p3 = p2+(p3-p2)*(bc/cd);
		//}
	}

	float t = p_t;
	float t2 = t * t;
	float t3 = t2 * t;

	Vector3 out;
	out.x = 0.5f * ( ( 2.0f * p1.x ) +
	( -p0.x + p2.x ) * t +
	( 2.0f * p0.x - 5.0f * p1.x + 4 * p2.x - p3.x ) * t2 +
	( -p0.x + 3.0f * p1.x - 3.0f * p2.x + p3.x ) * t3 );
	out.y = 0.5f * ( ( 2.0f * p1.y ) +
	( -p0.y + p2.y ) * t +
	( 2.0f * p0.y - 5.0f * p1.y + 4 * p2.y - p3.y ) * t2 +
	( -p0.y + 3.0f * p1.y - 3.0f * p2.y + p3.y ) * t3 );
	out.z = 0.5f * ( ( 2.0f * p1.z ) +
	( -p0.z + p2.z ) * t +
	( 2.0f * p0.z - 5.0f * p1.z + 4 * p2.z - p3.z ) * t2 +
	( -p0.z + 3.0f * p1.z - 3.0f * p2.z + p3.z ) * t3 );
	return out;
}
# endif
Vector3::operator String() const {

	return (rtos(x)+", "+rtos(y)+", "+rtos(z));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formbrowsertools.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 13:17:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#ifndef _EXTENSIONS_FORMSCTRLR_FORMBROWSERTOOLS_HXX_
#include "formbrowsertools.hxx"
#endif
#ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_
#include <com/sun/star/form/FormComponentType.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
#include "formresid.hrc"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
#include "modulepcr.hxx"
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _EXTENSIONS_FORMSCTRLR_FORMSTRINGS_HXX_
#include "formstrings.hxx"
#endif

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;

    ::rtl::OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
    {
        PcrClient aResourceAccess;
            // this ensures that we have our resource file loaded

        ::rtl::OUString sClassName;
        switch (nClassId)
        {
            case FormComponentType::TEXTFIELD:
            {
                Reference< XInterface >  xIFace;
                aUnoObj >>= xIFace;
                sClassName = String(PcrRes(RID_STR_PROPTITLE_EDIT));
                if (xIFace.is())
                {   // we have a chance to check if it's a formatted field model
                    Reference< XServiceInfo >  xInfo(xIFace, UNO_QUERY);
                    if (xInfo.is() && (xInfo->supportsService(SERVICE_COMPONENT_FORMATTEDFIELD)))
                        sClassName = String(PcrRes(RID_STR_PROPTITLE_FORMATTED));
                    else if (!xInfo.is())
                    {
                        // couldn't distinguish between formatted and edit with the service name, so try with the properties
                        Reference< XPropertySet >  xProps(xIFace, UNO_QUERY);
                        if (xProps.is())
                        {
                            Reference< XPropertySetInfo >  xPropsInfo = xProps->getPropertySetInfo();
                            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(PROPERTY_FORMATSSUPPLIER))
                                sClassName = String(PcrRes(RID_STR_PROPTITLE_FORMATTED));
                        }
                    }
                }
            }
            break;

            case FormComponentType::COMMANDBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_PUSHBUTTON)); break;
            case FormComponentType::RADIOBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_RADIOBUTTON)); break;
            case FormComponentType::CHECKBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_CHECKBOX)); break;
            case FormComponentType::LISTBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_LISTBOX)); break;
            case FormComponentType::COMBOBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_COMBOBOX)); break;
            case FormComponentType::GROUPBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_GROUPBOX)); break;
            case FormComponentType::IMAGEBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_IMAGEBUTTON)); break;
            case FormComponentType::FIXEDTEXT:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_FIXEDTEXT)); break;
            case FormComponentType::GRIDCONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_DBGRID)); break;
            case FormComponentType::FILECONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_FILECONTROL)); break;

            case FormComponentType::DATEFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_DATEFIELD)); break;
            case FormComponentType::TIMEFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_TIMEFIELD)); break;
            case FormComponentType::NUMERICFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_NUMERICFIELD)); break;
            case FormComponentType::CURRENCYFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_CURRENCYFIELD)); break;
            case FormComponentType::PATTERNFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_PATTERNFIELD)); break;
            case FormComponentType::IMAGECONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_IMAGECONTROL)); break;
            case FormComponentType::HIDDENCONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_HIDDENCONTROL)); break;

            case FormComponentType::CONTROL:
            default:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_UNKNOWNCONTROL)); break;
        }

        return sClassName;
    }

//............................................................................
} // namespace pcr
//............................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.6.276); FILE MERGED 2008/04/01 15:15:15 thb 1.6.276.3: #i85898# Stripping all external header guards 2008/04/01 12:29:49 thb 1.6.276.2: #i85898# Stripping all external header guards 2008/03/31 12:31:41 rt 1.6.276.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: formbrowsertools.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "formbrowsertools.hxx"
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
#include "formresid.hrc"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
#include "modulepcr.hxx"
#endif
#include <tools/string.hxx>
#include "formstrings.hxx"

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;

    ::rtl::OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
    {
        PcrClient aResourceAccess;
            // this ensures that we have our resource file loaded

        ::rtl::OUString sClassName;
        switch (nClassId)
        {
            case FormComponentType::TEXTFIELD:
            {
                Reference< XInterface >  xIFace;
                aUnoObj >>= xIFace;
                sClassName = String(PcrRes(RID_STR_PROPTITLE_EDIT));
                if (xIFace.is())
                {   // we have a chance to check if it's a formatted field model
                    Reference< XServiceInfo >  xInfo(xIFace, UNO_QUERY);
                    if (xInfo.is() && (xInfo->supportsService(SERVICE_COMPONENT_FORMATTEDFIELD)))
                        sClassName = String(PcrRes(RID_STR_PROPTITLE_FORMATTED));
                    else if (!xInfo.is())
                    {
                        // couldn't distinguish between formatted and edit with the service name, so try with the properties
                        Reference< XPropertySet >  xProps(xIFace, UNO_QUERY);
                        if (xProps.is())
                        {
                            Reference< XPropertySetInfo >  xPropsInfo = xProps->getPropertySetInfo();
                            if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(PROPERTY_FORMATSSUPPLIER))
                                sClassName = String(PcrRes(RID_STR_PROPTITLE_FORMATTED));
                        }
                    }
                }
            }
            break;

            case FormComponentType::COMMANDBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_PUSHBUTTON)); break;
            case FormComponentType::RADIOBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_RADIOBUTTON)); break;
            case FormComponentType::CHECKBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_CHECKBOX)); break;
            case FormComponentType::LISTBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_LISTBOX)); break;
            case FormComponentType::COMBOBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_COMBOBOX)); break;
            case FormComponentType::GROUPBOX:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_GROUPBOX)); break;
            case FormComponentType::IMAGEBUTTON:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_IMAGEBUTTON)); break;
            case FormComponentType::FIXEDTEXT:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_FIXEDTEXT)); break;
            case FormComponentType::GRIDCONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_DBGRID)); break;
            case FormComponentType::FILECONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_FILECONTROL)); break;

            case FormComponentType::DATEFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_DATEFIELD)); break;
            case FormComponentType::TIMEFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_TIMEFIELD)); break;
            case FormComponentType::NUMERICFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_NUMERICFIELD)); break;
            case FormComponentType::CURRENCYFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_CURRENCYFIELD)); break;
            case FormComponentType::PATTERNFIELD:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_PATTERNFIELD)); break;
            case FormComponentType::IMAGECONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_IMAGECONTROL)); break;
            case FormComponentType::HIDDENCONTROL:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_HIDDENCONTROL)); break;

            case FormComponentType::CONTROL:
            default:
                sClassName = String(PcrRes(RID_STR_PROPTITLE_UNKNOWNCONTROL)); break;
        }

        return sClassName;
    }

//............................................................................
} // namespace pcr
//............................................................................

<|endoftext|>