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

/* Author: Wim Meeussen */

#include "urdf_parser/urdf_parser.h"
#include <iostream>
#include <fstream>

using namespace urdf;
using namespace std;

void addChildLinkNames(boost::shared_ptr<const Link> link, ofstream& os)
{
  os << "\"" << link->name << "\" [label=\"" << link->name << "\"];" << endl;
  for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++)
    addChildLinkNames(*child, os);
}

void addChildJointNames(boost::shared_ptr<const Link> link, ofstream& os)
{
  double r, p, y;
  for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++){
    (*child)->parent_joint->parent_to_joint_origin_transform.rotation.getRPY(r,p,y);
    os << "\"" << link->name << "\" -> \"" << (*child)->parent_joint->name
       << "\" [label=\"xyz: "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.x << " "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.y << " "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.z << " "
       << "\\nrpy: " << r << " " << p << " " << y << "\"]" << endl;
    os << "\"" << (*child)->parent_joint->name << "\" -> \"" << (*child)->name << "\"" << endl;
    addChildJointNames(*child, os);
  }
}

void printTree(boost::shared_ptr<const Link> link, string file)
{
  std::ofstream os;
  os.open(file.c_str());
  os << "digraph G {" << endl;

  os << "node [shape=box];" << endl;
  addChildLinkNames(link, os);

  os << "node [shape=ellipse, color=blue, fontcolor=blue];" << endl;
  addChildJointNames(link, os);

  os << "}" << endl;
  os.close();
}

int main(int argc, char** argv)
{
  if (argc != 2){
    std::cerr << "Usage: urdf_to_graphiz input.xml" << std::endl;
    return -1;
  }

  // get the entire file
  std::string xml_string;
  std::fstream xml_file(argv[1], std::fstream::in);
  while ( xml_file.good() )
  {
    std::string line;
    std::getline( xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();

  boost::shared_ptr<ModelInterface> robot = parseURDF(xml_string);
  if (!robot){
    std::cerr << "ERROR: Model Parsing the xml failed" << std::endl;
    return -1;
  }
  string output = robot->getName();

  // print entire tree to file
  printTree(robot->getRoot(), output+".gv");
  cout << "Created file " << output << ".gv" << endl;

  string command = "dot -Tpdf "+output+".gv  -o "+output+".pdf";
  if (system(command.c_str()) != -1)
    cout << "Created file " << output << ".pdf" << endl;
  else
    cout << "There was an error executing '" << command << "'" << endl;
  return 0;
}

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

/* Author: Wim Meeussen */

#include "urdf_parser/urdf_parser.h"
#include <iostream>
#include <fstream>

using namespace urdf;
using namespace std;

void addChildLinkNames(boost::shared_ptr<const Link> link, ofstream& os)
{
  os << "\"" << link->name << "\" [label=\"" << link->name << "\"];" << endl;
  for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++)
    addChildLinkNames(*child, os);
}

void addChildJointNames(boost::shared_ptr<const Link> link, ofstream& os)
{
  double r, p, y;
  for (std::vector<boost::shared_ptr<Link> >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++){
    // use blue for fixed joint and green for not-fixed joints
    if( (*child)->parent_joint->type != Joint::FIXED  ) {
      os << "\"" << (*child)->parent_joint->name << "\" [color=green, fontcolor=green];"  << endl;
    }

    (*child)->parent_joint->parent_to_joint_origin_transform.rotation.getRPY(r,p,y);
    os << "\"" << link->name << "\" -> \"" << (*child)->parent_joint->name
       << "\" [label=\"xyz: "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.x << " "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.y << " "
       << (*child)->parent_joint->parent_to_joint_origin_transform.position.z << " "
       << "\\nrpy: " << r << " " << p << " " << y << "\"]" << endl;
    os << "\"" << (*child)->parent_joint->name << "\" -> \"" << (*child)->name << "\"" << endl;
    addChildJointNames(*child, os);
  }
}

void printTree(boost::shared_ptr<const Link> link, string file)
{
  std::ofstream os;
  os.open(file.c_str());
  os << "digraph G {" << endl;

  os << "node [shape=box];" << endl;
  addChildLinkNames(link, os);

  os << "node [shape=ellipse, color=blue, fontcolor=blue];" << endl;
  addChildJointNames(link, os);

  os << "}" << endl;
  os.close();
}

int main(int argc, char** argv)
{
  if (argc != 2){
    std::cerr << "Usage: urdf_to_graphiz input.xml" << std::endl;
    return -1;
  }

  // get the entire file
  std::string xml_string;
  std::fstream xml_file(argv[1], std::fstream::in);
  while ( xml_file.good() )
  {
    std::string line;
    std::getline( xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();

  boost::shared_ptr<ModelInterface> robot = parseURDF(xml_string);
  if (!robot){
    std::cerr << "ERROR: Model Parsing the xml failed" << std::endl;
    return -1;
  }
  string output = robot->getName();

  // print entire tree to file
  printTree(robot->getRoot(), output+".gv");
  cout << "Created file " << output << ".gv" << endl;

  string command = "dot -Tpdf "+output+".gv  -o "+output+".pdf";
  if (system(command.c_str()) != -1)
    cout << "Created file " << output << ".pdf" << endl;
  else
    cout << "There was an error executing '" << command << "'" << endl;
  return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: JDriver.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: oj $ $Date: 2001-05-31 08:32:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_JAVA_SQL_DRIVER_HXX_
#include "java/sql/Driver.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#include "java/lang/Object.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_LANG_CLASS_HXX_
#include "java/lang/Class.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_DRIVERMANAGER_HXX_
#include "java/sql/DriverManager.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_DRIVERPOPERTYINFO_HXX_
#include "java/sql/DriverPropertyInfo.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_CONNECTION_HXX_
#include "java/sql/Connection.hxx"
#endif
#include "java/util/Property.hxx"
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif

using namespace connectivity;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
//  using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;

// -------------------------------------------------------------------------
java_sql_Driver::java_sql_Driver(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
    : java_lang_Object(_rxFactory)
{
//  SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
//  // this object is not the right one
//  if(t.pEnv)
//      t.pEnv->DeleteGlobalRef( object );
//  object = 0;
}
// --------------------------------------------------------------------------------
jclass java_sql_Driver::theClass = 0;
// --------------------------------------------------------------------------------
java_sql_Driver::~java_sql_Driver()
{}
// static ServiceInfo
//------------------------------------------------------------------------------
rtl::OUString java_sql_Driver::getImplementationName_Static(  ) throw(RuntimeException)
{
    return ::rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.JDBCDriver");
        // this name is referenced in the configuration and in the jdbc.xml
        // Please take care when changing it.
}
//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > java_sql_Driver::getSupportedServiceNames_Static(  ) throw (RuntimeException)
{
    Sequence< ::rtl::OUString > aSNS( 1 );
    aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
    return aSNS;
}
//------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL connectivity::java_sql_Driver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception )
{
    return *(new java_sql_Driver(_rxFactory));
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL java_sql_Driver::getImplementationName(  ) throw(RuntimeException)
{
    return getImplementationName_Static();
}

// --------------------------------------------------------------------------------
sal_Bool SAL_CALL java_sql_Driver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
{
    Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}

// --------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL java_sql_Driver::getSupportedServiceNames(  ) throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

// --------------------------------------------------------------------------------
jclass java_sql_Driver::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass )
    {
        SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
        if( t.pEnv )
        {
            jclass tempClass = t.pEnv->FindClass("java/sql/Driver");
            OSL_ENSURE(tempClass,"Java : FindClass nicht erfolgreich!");
            jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
            t.pEnv->DeleteLocalRef( tempClass );
            saveClassRef( globClass );
        }
    }
    return theClass;
}
// --------------------------------------------------------------------------------
void java_sql_Driver::saveClassRef( jclass pClass )
{
    if( SDBThreadAttach::IsJavaErrorOccured() || pClass==0  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}
// -------------------------------------------------------------------------
Reference< XConnection > SAL_CALL java_sql_Driver::connect( const ::rtl::OUString& url, const
                                                         Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    Reference< XConnection > xRet;
    // first try if the jdbc driver is alraedy registered at the driver manager
    try
    {
        if(!object)
        {
            const PropertyValue* pBegin = info.getConstArray();
            const PropertyValue* pEnd   = pBegin + info.getLength();
            for(jsize i=0;pBegin != pEnd;++pBegin)
            {
                if(!pBegin->Name.compareToAscii("JavaDriverClass"))
                {
                    // here I try to find the class for jdbc driver
                    java_sql_SQLException_BASE::getMyClass();
                    java_lang_Throwable::getMyClass();

                    ::rtl::OUString aStr;
                    pBegin->Value >>= aStr;
                    // the driver manager holds the class of the driver for later use
                    // if forName didn't find the class it will throw an exception
                    java_lang_Class *pDrvClass = java_lang_Class::forName(aStr);
                    if(pDrvClass)
                    {
                        saveRef(t.pEnv, pDrvClass->newInstanceObject());
                        delete pDrvClass;
                    }
                    break;
                }
            }
        }
    }
    catch(Exception&)
    {
        throw SQLException(::rtl::OUString::createFromAscii("The specified driver could not be loaded!"),*this,::rtl::OUString(),1000,Any());
    }

    jobject out(0);

    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
        char * cMethodName = "connect";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        ThrowSQLException(t.pEnv,*this);
        if( mID )
        {
            jvalue args[2];
            // Parameter konvertieren
            args[0].l = convertwchar_tToJavaString(t.pEnv,url);
            java_util_Properties* pProps = createStringPropertyArray(t.pEnv,info);
            args[1].l = pProps->getJavaObject();

            out = t.pEnv->CallObjectMethod( object, mID, args[0].l,args[1].l );
            ThrowSQLException(t.pEnv,*this);
            // und aufraeumen
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            ThrowSQLException(t.pEnv,*this);
            delete pProps;
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    Reference< XConnection > xOut;
    return out==0 ? 0 : new java_sql_Connection( t.pEnv, out,this );
    //  return xOut;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL java_sql_Driver::acceptsURL( const ::rtl::OUString& url ) throw(SQLException, RuntimeException)
{
    // don't ask the real driver for the url
    // I feel responsible for all jdbc url's
    static const ::rtl::OUString s_sJdbcPrefix = ::rtl::OUString::createFromAscii("jdbc:");
    return 0 == url.compareTo(s_sJdbcPrefix, 5);
}
// -------------------------------------------------------------------------
Sequence< DriverPropertyInfo > SAL_CALL java_sql_Driver::getPropertyInfo( const ::rtl::OUString& url,
                                                                         const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if(!object)
        object = java_sql_DriverManager::getDriver(url);

    if(!object)
    {
        // one of these must throw an exception
        ThrowSQLException(t.pEnv,*this);
        throw SQLException(); // we need a object here
    }

    jobjectArray out(0);

    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)[Ljava/sql/DriverPropertyInfo;";
        char * cMethodName = "getPropertyInfo";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
        {
            jvalue args[2];
            // Parameter konvertieren
            args[0].l = convertwchar_tToJavaString(t.pEnv,url);
            java_util_Properties* pProps = createStringPropertyArray(t.pEnv,info);
            args[1].l = pProps->getJavaObject();

            out = (jobjectArray)t.pEnv->CallObjectMethodA( object, mID, args );
            ThrowSQLException(t.pEnv,*this);
            // und aufraeumen
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            delete pProps;
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return copyArrayAndDelete( t.pEnv, out, DriverPropertyInfo(),java_sql_DriverPropertyInfo(NULL,NULL));
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL java_sql_Driver::getMajorVersion(  ) throw(RuntimeException)
{
    if(!object)
        throw RuntimeException();
    jint out(0);
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if( t.pEnv ){

        // temporaere Variable initialisieren
        char * cSignature = "()I";
        char * cMethodName = "getMajorVersion";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
            out = t.pEnv->CallIntMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
    } //t.pEnv
    return out;
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL java_sql_Driver::getMinorVersion(  ) throw(RuntimeException)
{
    if(!object)
        throw RuntimeException();
    jint out(0);
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if( t.pEnv ){

        // temporaere Variable initialisieren
        char * cSignature = "()I";
        char * cMethodName = "getMinorVersion";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
            out = t.pEnv->CallIntMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
    } //t.pEnv
    return out;
}
// -------------------------------------------------------------------------

<commit_msg>#90553# forget to clear the object after use<commit_after>/*************************************************************************
 *
 *  $RCSfile: JDriver.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: oj $ $Date: 2001-08-03 14:19:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_JAVA_SQL_DRIVER_HXX_
#include "java/sql/Driver.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#include "java/lang/Object.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_LANG_CLASS_HXX_
#include "java/lang/Class.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_DRIVERMANAGER_HXX_
#include "java/sql/DriverManager.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_DRIVERPOPERTYINFO_HXX_
#include "java/sql/DriverPropertyInfo.hxx"
#endif
#ifndef _CONNECTIVITY_JAVA_SQL_CONNECTION_HXX_
#include "java/sql/Connection.hxx"
#endif
#include "java/util/Property.hxx"
#ifndef _CONNECTIVITY_JAVA_TOOLS_HXX_
#include "java/tools.hxx"
#endif

using namespace connectivity;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
//  using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;

// -------------------------------------------------------------------------
java_sql_Driver::java_sql_Driver(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
    : java_lang_Object(_rxFactory)
{
}
// --------------------------------------------------------------------------------
jclass java_sql_Driver::theClass = 0;
// --------------------------------------------------------------------------------
java_sql_Driver::~java_sql_Driver()
{}
// static ServiceInfo
//------------------------------------------------------------------------------
rtl::OUString java_sql_Driver::getImplementationName_Static(  ) throw(RuntimeException)
{
    return ::rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.JDBCDriver");
        // this name is referenced in the configuration and in the jdbc.xml
        // Please take care when changing it.
}
//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > java_sql_Driver::getSupportedServiceNames_Static(  ) throw (RuntimeException)
{
    Sequence< ::rtl::OUString > aSNS( 1 );
    aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
    return aSNS;
}
//------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL connectivity::java_sql_Driver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception )
{
    return *(new java_sql_Driver(_rxFactory));
}
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL java_sql_Driver::getImplementationName(  ) throw(RuntimeException)
{
    return getImplementationName_Static();
}

// --------------------------------------------------------------------------------
sal_Bool SAL_CALL java_sql_Driver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
{
    Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
    const ::rtl::OUString* pSupported = aSupported.getConstArray();
    const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
    for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
        ;

    return pSupported != pEnd;
}

// --------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL java_sql_Driver::getSupportedServiceNames(  ) throw(RuntimeException)
{
    return getSupportedServiceNames_Static();
}

// --------------------------------------------------------------------------------
jclass java_sql_Driver::getMyClass()
{
    // die Klasse muss nur einmal geholt werden, daher statisch
    if( !theClass )
    {
        SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
        if( t.pEnv )
        {
            jclass tempClass = t.pEnv->FindClass("java/sql/Driver");
            OSL_ENSURE(tempClass,"Java : FindClass nicht erfolgreich!");
            jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
            t.pEnv->DeleteLocalRef( tempClass );
            saveClassRef( globClass );
        }
    }
    return theClass;
}
// --------------------------------------------------------------------------------
void java_sql_Driver::saveClassRef( jclass pClass )
{
    if( SDBThreadAttach::IsJavaErrorOccured() || pClass==0  )
        return;
    // der uebergebe Klassen-Handle ist schon global, daher einfach speichern
    theClass = pClass;
}
// -------------------------------------------------------------------------
Reference< XConnection > SAL_CALL java_sql_Driver::connect( const ::rtl::OUString& url, const
                                                         Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    Reference< XConnection > xRet;
    // first try if the jdbc driver is alraedy registered at the driver manager
    try
    {
        if(!object)
        {
            const PropertyValue* pBegin = info.getConstArray();
            const PropertyValue* pEnd   = pBegin + info.getLength();
            for(jsize i=0;pBegin != pEnd;++pBegin)
            {
                if(!pBegin->Name.compareToAscii("JavaDriverClass"))
                {
                    // here I try to find the class for jdbc driver
                    java_sql_SQLException_BASE::getMyClass();
                    java_lang_Throwable::getMyClass();

                    ::rtl::OUString aStr;
                    pBegin->Value >>= aStr;
                    // the driver manager holds the class of the driver for later use
                    // if forName didn't find the class it will throw an exception
                    java_lang_Class *pDrvClass = java_lang_Class::forName(aStr);
                    if(pDrvClass)
                    {
                        saveRef(t.pEnv, pDrvClass->newInstanceObject());
                        delete pDrvClass;
                    }
                    break;
                }
            }
        }
    }
    catch(Exception&)
    {
        if( object )
        {
            t.pEnv->DeleteGlobalRef( object );
            object = NULL;
        }
        throw SQLException(::rtl::OUString::createFromAscii("The specified driver could not be loaded!"),*this,::rtl::OUString(),1000,Any());
    }

    jobject out(0);

    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
        char * cMethodName = "connect";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        ThrowSQLException(t.pEnv,*this);
        if( mID )
        {
            jvalue args[2];
            // Parameter konvertieren
            args[0].l = convertwchar_tToJavaString(t.pEnv,url);
            java_util_Properties* pProps = createStringPropertyArray(t.pEnv,info);
            args[1].l = pProps->getJavaObject();

            out = t.pEnv->CallObjectMethod( object, mID, args[0].l,args[1].l );
            // und aufraeumen
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            delete pProps;
            if( object )
            {
                t.pEnv->DeleteGlobalRef( object );
                object = NULL;
            }
            ThrowSQLException(t.pEnv,*this);

        } //mID
        if( object )
        {
            t.pEnv->DeleteGlobalRef( object );
            object = NULL;
        }
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    Reference< XConnection > xOut;
    return out==0 ? 0 : new java_sql_Connection( t.pEnv, out,this );
    //  return xOut;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL java_sql_Driver::acceptsURL( const ::rtl::OUString& url ) throw(SQLException, RuntimeException)
{
    // don't ask the real driver for the url
    // I feel responsible for all jdbc url's
    static const ::rtl::OUString s_sJdbcPrefix = ::rtl::OUString::createFromAscii("jdbc:");
    return 0 == url.compareTo(s_sJdbcPrefix, 5);
}
// -------------------------------------------------------------------------
Sequence< DriverPropertyInfo > SAL_CALL java_sql_Driver::getPropertyInfo( const ::rtl::OUString& url,
                                                                         const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
{
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if(!object)
        object = java_sql_DriverManager::getDriver(url);

    if(!object)
    {
        // one of these must throw an exception
        ThrowSQLException(t.pEnv,*this);
        throw SQLException(); // we need a object here
    }

    jobjectArray out(0);

    if( t.pEnv )
    {
        // temporaere Variable initialisieren
        char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)[Ljava/sql/DriverPropertyInfo;";
        char * cMethodName = "getPropertyInfo";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
        {
            jvalue args[2];
            // Parameter konvertieren
            args[0].l = convertwchar_tToJavaString(t.pEnv,url);
            java_util_Properties* pProps = createStringPropertyArray(t.pEnv,info);
            args[1].l = pProps->getJavaObject();

            out = (jobjectArray)t.pEnv->CallObjectMethodA( object, mID, args );
            ThrowSQLException(t.pEnv,*this);
            // und aufraeumen
            t.pEnv->DeleteLocalRef((jstring)args[0].l);
            delete pProps;
        } //mID
    } //t.pEnv
    // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
    return copyArrayAndDelete( t.pEnv, out, DriverPropertyInfo(),java_sql_DriverPropertyInfo(NULL,NULL));
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL java_sql_Driver::getMajorVersion(  ) throw(RuntimeException)
{
    if(!object)
        throw RuntimeException();
    jint out(0);
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if( t.pEnv ){

        // temporaere Variable initialisieren
        char * cSignature = "()I";
        char * cMethodName = "getMajorVersion";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
            out = t.pEnv->CallIntMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
    } //t.pEnv
    return out;
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL java_sql_Driver::getMinorVersion(  ) throw(RuntimeException)
{
    if(!object)
        throw RuntimeException();
    jint out(0);
    SDBThreadAttach t(getORB()); OSL_ENSURE(t.pEnv,"Java Enviroment gelscht worden!");
    if( t.pEnv ){

        // temporaere Variable initialisieren
        char * cSignature = "()I";
        char * cMethodName = "getMinorVersion";
        // Java-Call absetzen
        jmethodID mID = t.pEnv->GetMethodID( getMyClass(), cMethodName, cSignature );OSL_ENSURE(mID,"Unknown method id!");
        if( mID )
            out = t.pEnv->CallIntMethod( object, mID);
            ThrowSQLException(t.pEnv,*this);
    } //t.pEnv
    return out;
}
// -------------------------------------------------------------------------

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: Object.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-24 13:23:29 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#define _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_

#if STLPORT_VERSION>=321
// jni.h needs cstdarg for std::va_list
#include <cstdarg>
#endif
#include <jni.h>

#ifdef OS2
#include <typedefs.h>
#endif

#ifndef _COM_SUN_STAR_SDBC_SQLEXCEPTION_HPP_
#include <com/sun/star/sdbc/SQLException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX
#include <jvmaccess/virtualmachine.hxx>
#endif // INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX

//=====================================================================

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define INT64_TO_PVOID(x) (void *)x.lo
inline jlong Make_Os2_Int64( sal_Int32 hi, sal_Int32 lo ) {jlong x = CONST64( hi, lo ); return x; }
#define PVOID_TO_INT64(x) Make_Os2_Int64( 0, (sal_Int32)x )
#else //OS2
#define PVOID_TO_INT64(x) (jlong)(sal_Int32)x
#define INT64_TO_PVOID(x) (void *)x
#endif //Os2
#endif //HAVE_64BIT_POINTERS

namespace connectivity
{
    class SDBThreadAttach
    {
        jvmaccess::VirtualMachine::AttachGuard m_aGuard;
        SDBThreadAttach(SDBThreadAttach&);
    public:
        SDBThreadAttach();
        ~SDBThreadAttach();

        JNIEnv* pEnv;
        void addRef();
        void releaseRef();
    };
    //=====================================================================
    class java_lang_Class;
    class  java_lang_Object
    {
        // Zuweisungsoperator und Copy Konstruktor sind verboten
        java_lang_Object& operator = (java_lang_Object&) { return *this;};
        java_lang_Object(java_lang_Object&) {};

        static jclass getMyClass();
        // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
        // abgeleiteten Java Objekten
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    protected:
        // der JAVA Handle zu dieser Klasse
        jobject object;
        // Klassendefinition

        // neu in SJ2:
        static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !
        static jclass theJSbxObjectClass;   // die Klasse braucht nur einmal angefordert werden !
        static sal_uInt32 nObjCount;                // Zaehler fuer die Anzahl der Instanzen

    public:
        // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
        // werden soll.
        java_lang_Object( JNIEnv * pEnv, jobject myObj );
        // der eigentliche Konstruktor
        java_lang_Object(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);

        virtual ~java_lang_Object();

        void                saveRef( JNIEnv * pEnv, jobject myObj );
        jobject             getJavaObject() const { return object; }
        java_lang_Object *  GetWrapper() { return this; }

        java_lang_Class *   getClass();

        ::rtl::OUString     toString();
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() { return m_xFactory; }
        static void ThrowSQLException(JNIEnv * pEnv,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> & _rContext) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

        static ::rtl::Reference< jvmaccess::VirtualMachine > getVM(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);
    };
}
#endif //_CONNECTIVITY_JAVA_LANG_OBJJECT_HXX_

<commit_msg>INTEGRATION: CWS geordi2q10 (1.5.78); FILE MERGED 2003/11/28 09:38:59 rt 1.5.78.1: #111934#: join CWS dba01pp1<commit_after>/*************************************************************************
 *
 *  $RCSfile: Object.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2003-12-01 10:49:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#define _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_

#if STLPORT_VERSION>=321
// jni.h needs cstdarg for std::va_list
#include <cstdarg>
#endif
#include <jni.h>

#ifdef OS2
#include <typedefs.h>
#endif

#ifndef _COM_SUN_STAR_SDBC_SQLEXCEPTION_HPP_
#include <com/sun/star/sdbc/SQLException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX
#include <jvmaccess/virtualmachine.hxx>
#endif // INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX
#include <memory>

//=====================================================================

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define INT64_TO_PVOID(x) (void *)x.lo
inline jlong Make_Os2_Int64( sal_Int32 hi, sal_Int32 lo ) {jlong x = CONST64( hi, lo ); return x; }
#define PVOID_TO_INT64(x) Make_Os2_Int64( 0, (sal_Int32)x )
#else //OS2
#define PVOID_TO_INT64(x) (jlong)(sal_Int32)x
#define INT64_TO_PVOID(x) (void *)x
#endif //Os2
#endif //HAVE_64BIT_POINTERS

namespace connectivity
{
    class SDBThreadAttach
    {
        ::std::auto_ptr< jvmaccess::VirtualMachine::AttachGuard> m_aGuard;
        SDBThreadAttach(SDBThreadAttach&);
    public:
        SDBThreadAttach();
        ~SDBThreadAttach();

        JNIEnv* pEnv;
        void addRef();
        void releaseRef();
    };
    //=====================================================================
    class java_lang_Class;
    class  java_lang_Object
    {
        // Zuweisungsoperator und Copy Konstruktor sind verboten
        java_lang_Object& operator = (java_lang_Object&) { return *this;};
        java_lang_Object(java_lang_Object&) {};

        static jclass getMyClass();
        // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
        // abgeleiteten Java Objekten
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    protected:
        // der JAVA Handle zu dieser Klasse
        jobject object;
        // Klassendefinition

        // neu in SJ2:
        static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !
        static jclass theJSbxObjectClass;   // die Klasse braucht nur einmal angefordert werden !
        static sal_uInt32 nObjCount;                // Zaehler fuer die Anzahl der Instanzen

    public:
        // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
        // werden soll.
        java_lang_Object( JNIEnv * pEnv, jobject myObj );
        // der eigentliche Konstruktor
        java_lang_Object(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);

        virtual ~java_lang_Object();

        void                saveRef( JNIEnv * pEnv, jobject myObj );
        jobject             getJavaObject() const { return object; }
        java_lang_Object *  GetWrapper() { return this; }

        java_lang_Class *   getClass();

        ::rtl::OUString     toString();
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() { return m_xFactory; }
        static void ThrowSQLException(JNIEnv * pEnv,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> & _rContext) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

        static ::rtl::Reference< jvmaccess::VirtualMachine > getVM(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);
    };
}
#endif //_CONNECTIVITY_JAVA_LANG_OBJJECT_HXX_

<|endoftext|>


<commit_before>#include <iostream>

using state = unsigned long long;
using tower = unsigned int;
using size = unsigned int;

constexpr tower other(tower t1, tower t2) {
    return 3 - t1 - t2;
}

constexpr state move(state s, tower src, tower target) {
    return s % 3 == src
        ? s / 3 * 3 + target
        : move(s / 3, src, target) * 3 + s % 3;
}

// disk 1 is the smallest, 0 does not exist (is "above" the smallest)
constexpr tower getTower(state s, size disk) {
    return disk == 1
        ? s % 3
        : getTower(s / 3, disk - 1);
}

std::ostream &print_state(std::ostream &os, size ndisks, state s) {
    return ndisks ? print_state(os, ndisks - 1, s / 3) << s % 3 : os;
}

template <size DISKS, state S, tower SRC, tower TARGET>
struct SolverRec {
    static constexpr tower nextSrc = getTower(S, DISKS - 1);
    static constexpr tower inter = other(SRC, TARGET);
    using rec1 = SolverRec<DISKS - 1, S, nextSrc, inter>;
    static constexpr state value = move(rec1::final_state, SRC, TARGET);
    using rec2 = SolverRec<DISKS - 1, value, inter, TARGET>;
    static constexpr state final_state = rec2::final_state;
};

template <size DISKS, state S, tower TOWER>
struct SolverRec<DISKS, S, TOWER, TOWER> {
    static constexpr tower nextSrc = getTower(S, DISKS - 1);
    using rec = SolverRec<DISKS - 1, S, nextSrc, TOWER>;
    static constexpr state final_state = rec::final_state;
};

template <state S, tower SRC, tower TARGET>
struct SolverRec<1, S, SRC, TARGET> {
    static constexpr state final_state = move(S, SRC, TARGET);
};

template <state S, tower TOWER>
struct SolverRec<1, S, TOWER, TOWER> {
    static constexpr state final_state = S;
};

template <size DISKS, state S, tower TARGET>
struct Solver {
    static constexpr tower src = getTower(S, DISKS);
    using start = SolverRec<DISKS, S, src, TARGET>;
    static constexpr state final_state = start::final_state;
};

int main() {
    constexpr size disks = 5;
    using solver = Solver<disks, 0, 2>;
    print_state(std::cout, disks, solver::final_state) << std::endl;
    return 0;
}
<commit_msg>Disks template for initial state<commit_after>#include <iostream>

using state = unsigned long long;
using tower = unsigned int;
using size = unsigned int;

constexpr tower other(tower t1, tower t2) {
    return 3 - t1 - t2;
}

constexpr state move(state s, tower src, tower target) {
    return s % 3 == src
        ? s / 3 * 3 + target
        : move(s / 3, src, target) * 3 + s % 3;
}

// disk 1 is the smallest, 0 does not exist (is "above" the smallest)
constexpr tower getTower(state s, size disk) {
    return disk == 1
        ? s % 3
        : getTower(s / 3, disk - 1);
}

std::ostream &print_state(std::ostream &os, size ndisks, state s) {
    return ndisks ? print_state(os, ndisks - 1, s / 3) << s % 3 : os;
}

template <tower ...T>
struct Disks;

template <tower H, tower ...T>
struct Disks<H, T...> {
    static constexpr state count = 1 + sizeof...(T);
    static constexpr state pack(state tmp) {
        return Disks<T...>::pack(tmp * 3 + H);
    }
    static constexpr state packed = pack(0);
};

template <>
struct Disks<> {
    static constexpr state count = 0;
    static constexpr state pack(state tmp) { return tmp; };
    static constexpr state packed = 0;
};

template <size DISKS, state S, tower SRC, tower TARGET>
struct SolverRec {
    static constexpr tower nextSrc = getTower(S, DISKS - 1);
    static constexpr tower inter = other(SRC, TARGET);
    using rec1 = SolverRec<DISKS - 1, S, nextSrc, inter>;
    static constexpr state value = move(rec1::final_state, SRC, TARGET);
    using rec2 = SolverRec<DISKS - 1, value, inter, TARGET>;
    static constexpr state final_state = rec2::final_state;
};

template <size DISKS, state S, tower TOWER>
struct SolverRec<DISKS, S, TOWER, TOWER> {
    static constexpr tower nextSrc = getTower(S, DISKS - 1);
    using rec = SolverRec<DISKS - 1, S, nextSrc, TOWER>;
    static constexpr state final_state = rec::final_state;
};

template <state S, tower SRC, tower TARGET>
struct SolverRec<1, S, SRC, TARGET> {
    static constexpr state final_state = move(S, SRC, TARGET);
};

template <state S, tower TOWER>
struct SolverRec<1, S, TOWER, TOWER> {
    static constexpr state final_state = S;
};

template <size DISKS, state S, tower TARGET>
struct Solver {
    static constexpr tower src = getTower(S, DISKS);
    using start = SolverRec<DISKS, S, src, TARGET>;
    static constexpr state final_state = start::final_state;
};

int main() {
    using disks = Disks<0, 0, 0, 0, 0>;
    using solver = Solver<disks::count, disks::packed, 2>;
    print_state(std::cout, disks::count, solver::final_state) << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 Caitlin Potter and Contributors
// 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.
//
// 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
// HOLDER 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 <TimedText/Cue.h>
#include <gtest/gtest.h>
using namespace TimedText;

void testSetAlign(const char *text, bool expectedSet,
                  Cue::Align expectedAlign = Cue::Middle)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedAlign = Cue::defaultAlign;
  ++run;
  EXPECT_EQ(expectedSet, cue.setAlign(text))
    << "in testSetAlign(string) #" << run;
  EXPECT_EQ(expectedAlign, cue.align())
    << "in testSetAlign(string) #" << run;
}

void testSetAlign(Cue::Align align, bool expectedSet,
                  Cue::Align expectedAlign = Cue::Middle)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedAlign = Cue::defaultAlign;
  ++run;
  EXPECT_EQ(expectedSet, cue.setAlign(align))
    << "in testSetAlign(enum) #" << run;
  EXPECT_EQ(expectedAlign, cue.align())
    << "in testSetAlign(enum) #" << run;
}

void testSetLine(const char *text, bool expectedSet,
                 int expectedLine = 0, bool expectedSnapToLines = false)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet) {
    expectedLine = Cue::defaultLine;
    expectedSnapToLines = Cue::defaultSnapToLines;
  }
  ++run;
  EXPECT_EQ(expectedSet, cue.setLine(text)) << "in testSetLine #" << run;
  EXPECT_EQ(expectedLine, cue.line()) << "in testSetLine #" << run;
  EXPECT_EQ(expectedSnapToLines, cue.snapToLines()) << "in testSetLine #" << run;
}

void testSetPosition(const char *text, bool expectedSet, int expectedPosition = 0)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedPosition = Cue::defaultPosition;
  ++run;
  EXPECT_EQ(expectedSet, cue.setPosition(text)) << "in testSetPosition #" << run;
  EXPECT_EQ(expectedPosition, cue.position()) << "in testSetPosition #" << run;
}

void testSetSize(const char *text, bool expectedSet, int expectedSize = 0)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedSize = Cue::defaultSize;
  ++run;
  EXPECT_EQ(expectedSet, cue.setSize(text)) << "in testSetSize #" << run;
  EXPECT_EQ(expectedSize, cue.size()) << "in testSetSize #" << run;
}

void testSetVertical(const char *text, bool expectedSet,
                     Cue::Vertical expectedVertical = Cue::Horizontal)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedVertical = Cue::defaultVertical;
  ++run;
  EXPECT_EQ(expectedSet, cue.setVertical(text))
    << "in testSetVertical(string) #" << run;
  EXPECT_EQ(expectedVertical, cue.vertical())
    << "in testSetVertical(string) #" << run;
}

void testSetVertical(Cue::Vertical vertical, bool expectedSet,
                     Cue::Vertical expectedVertical = Cue::Horizontal)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedVertical = Cue::defaultVertical;
  ++run;
  EXPECT_EQ(expectedSet, cue.setVertical(vertical))
    << "in testSetVertical(enum) #" << run;
  EXPECT_EQ(expectedVertical, cue.vertical())
    << "in testSetVertical(enum) #" << run;
}

TEST(CueSettings,SetId)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_STREQ("",cue.id());
  cue.setId("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn", cue.id());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetText)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_STREQ("",cue.text());
  cue.setText("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn", cue.text());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetStartTime)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_EQ(0.000,cue.startTime().toSeconds());
  cue.setStartTime(6667.334);
  EXPECT_EQ(6667.334,cue.startTime().toSeconds());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetEndTime)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_EQ(1.000,cue.endTime().toSeconds());
  cue.setEndTime(8362.316);
  EXPECT_EQ(8362.316,cue.endTime().toSeconds());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetAlign)
{
  const Cue::Align defaultAlign = Cue::defaultAlign;
  testSetAlign("start",true,Cue::Start);
  testSetAlign("middle",true,Cue::Middle);
  testSetAlign("end",true,Cue::End);
  testSetAlign("left",true,Cue::Left);
  testSetAlign("right",true,Cue::Right);
  testSetAlign("12345",false);
  testSetAlign("!@#$",false);
  testSetAlign("bottom",false);
  testSetAlign("",false);
  testSetAlign(NULL,false);
  testSetAlign(static_cast<Cue::Align>(-1),false,defaultAlign);
  testSetAlign(static_cast<Cue::Align>(68),false,defaultAlign);
}

TEST(CueSettings,SetLine)
{
  testSetLine("-1",true,-1,true);
  testSetLine("10%",true,10,false);
  testSetLine("0%",true,0,false);
  testSetLine("100%",true,100,false);
  testSetLine("-1%",false);
  testSetLine("101%",false);
  testSetLine("1%1",false);
  testSetLine("1-1",false);
  testSetLine("1z",false);
  testSetLine("%",false);
  testSetLine("-",false);
  testSetLine("alpha",false);
  testSetPosition("",false);
  testSetPosition(NULL,false);
}

TEST(CueSettings,SetPosition)
{
  testSetPosition("0%",true,0);
  testSetPosition("100%",true,100);
  testSetPosition("-1%",false);
  testSetPosition("101%",false);
  testSetPosition("0",false);
  testSetPosition("100",false);
  testSetPosition("%",false);
  testSetPosition("%100",false);
  testSetPosition("alpha",false);
  testSetPosition("",false);
  testSetPosition(NULL,false);
}

TEST(CueSettings,SetSize)
{
  testSetSize("0%",true,0);
  testSetSize("100%",true,100);
  testSetSize("-1%",false);
  testSetSize("101%",false);
  testSetSize("0",false);
  testSetSize("100",false);
  testSetSize("%",false);
  testSetSize("%100",false);
  testSetSize("alpha",false);
  testSetSize("",false);
  testSetSize(NULL,false);
}

TEST(CueSettings,SetVertical)
{
  const Cue::Vertical defaultVertical = Cue::defaultVertical;
  testSetVertical("",true,Cue::Horizontal);
  testSetVertical("lr",true,Cue::VerticalLeftToRight);
  testSetVertical("rl",true,Cue::VerticalRightToLeft);
  testSetVertical(static_cast<Cue::Vertical>(-1),false,defaultVertical);
  testSetVertical(static_cast<Cue::Vertical>(2000),false,defaultVertical);
  testSetVertical(NULL,false);
  testSetVertical("lr ",false);
  testSetVertical("rl ",false);
  testSetVertical("lrr",false);
  testSetVertical("rll",false);
  testSetVertical("0",false);
  testSetVertical("1",false);
  testSetVertical("2",false);
}

TEST(CueSettings,EmptyCue)
{
  // Avoid using references to const values in EXPECT_EQ statements
  const Cue::Align defaultAlign = Cue::defaultAlign;
  const int defaultLine = Cue::defaultLine;
  const int defaultPosition = Cue::defaultPosition;
  const int defaultSize = Cue::defaultSize;
  const bool defaultSnapToLines = Cue::defaultSnapToLines;
  const Cue::Vertical defaultVertical = Cue::defaultVertical;

  // Trying to set empty cue settings should always fail
  Cue cue;

  // Id
  cue.setId("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("", cue.id());

  // Text
  cue.setText("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("", cue.text());

  // StartTime
  cue.setStartTime(68.067);
  EXPECT_EQ(MalformedTimestamp, cue.startTime());

  // EndTime
  cue.setEndTime(98.678);
  EXPECT_EQ(MalformedTimestamp, cue.endTime());

  // Align
  EXPECT_FALSE(cue.setAlign(Cue::Start));
  EXPECT_FALSE(cue.setAlign(Cue::Middle));
  EXPECT_FALSE(cue.setAlign(Cue::End));
  EXPECT_FALSE(cue.setAlign(Cue::Left));
  EXPECT_FALSE(cue.setAlign(Cue::Right));
  EXPECT_FALSE(cue.setAlign("start"));
  EXPECT_FALSE(cue.setAlign("middle"));
  EXPECT_FALSE(cue.setAlign("end"));
  EXPECT_FALSE(cue.setAlign("left"));
  EXPECT_FALSE(cue.setAlign("right"));
  EXPECT_EQ(defaultAlign,cue.align());

  // Line
  EXPECT_FALSE(cue.setLine(0, false));
  EXPECT_FALSE(cue.setLine(0, false));
  EXPECT_FALSE(cue.setLine(-101, true));
  EXPECT_FALSE(cue.setLine(101, true));
  EXPECT_FALSE(cue.setLine("0%"));
  EXPECT_FALSE(cue.setLine("100%"));
  EXPECT_FALSE(cue.setLine("-101"));
  EXPECT_FALSE(cue.setLine("1001"));
  EXPECT_EQ(defaultLine, cue.line());
  EXPECT_EQ(defaultSnapToLines, cue.snapToLines());

  // Position
  EXPECT_FALSE(cue.setPosition(0));
  EXPECT_FALSE(cue.setPosition(100));
  EXPECT_FALSE(cue.setPosition("0%"));
  EXPECT_FALSE(cue.setPosition("100%"));
  EXPECT_EQ(defaultPosition, cue.position());

  // Size
  EXPECT_FALSE(cue.setSize(0));
  EXPECT_FALSE(cue.setSize(100));
  EXPECT_FALSE(cue.setSize("0%"));
  EXPECT_FALSE(cue.setSize("100%"));
  EXPECT_EQ(defaultSize, cue.size());

  // Vertical
  EXPECT_FALSE(cue.setVertical(Cue::Horizontal));
  EXPECT_FALSE(cue.setVertical(Cue::VerticalLeftToRight));
  EXPECT_FALSE(cue.setVertical(Cue::VerticalRightToLeft));
  EXPECT_FALSE(cue.setVertical(""));
  EXPECT_FALSE(cue.setVertical("lr"));
  EXPECT_FALSE(cue.setVertical("rl"));
  EXPECT_EQ(defaultVertical, cue.vertical());
}
<commit_msg>Test setting Cue::setLine with NULL and empty strings<commit_after>//
// Copyright (c) 2014 Caitlin Potter and Contributors
// 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.
//
// 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
// HOLDER 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 <TimedText/Cue.h>
#include <gtest/gtest.h>
using namespace TimedText;

void testSetAlign(const char *text, bool expectedSet,
                  Cue::Align expectedAlign = Cue::Middle)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedAlign = Cue::defaultAlign;
  ++run;
  EXPECT_EQ(expectedSet, cue.setAlign(text))
    << "in testSetAlign(string) #" << run;
  EXPECT_EQ(expectedAlign, cue.align())
    << "in testSetAlign(string) #" << run;
}

void testSetAlign(Cue::Align align, bool expectedSet,
                  Cue::Align expectedAlign = Cue::Middle)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedAlign = Cue::defaultAlign;
  ++run;
  EXPECT_EQ(expectedSet, cue.setAlign(align))
    << "in testSetAlign(enum) #" << run;
  EXPECT_EQ(expectedAlign, cue.align())
    << "in testSetAlign(enum) #" << run;
}

void testSetLine(const char *text, bool expectedSet,
                 int expectedLine = 0, bool expectedSnapToLines = false)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet) {
    expectedLine = Cue::defaultLine;
    expectedSnapToLines = Cue::defaultSnapToLines;
  }
  ++run;
  EXPECT_EQ(expectedSet, cue.setLine(text)) << "in testSetLine #" << run;
  EXPECT_EQ(expectedLine, cue.line()) << "in testSetLine #" << run;
  EXPECT_EQ(expectedSnapToLines, cue.snapToLines()) << "in testSetLine #" << run;
}

void testSetPosition(const char *text, bool expectedSet, int expectedPosition = 0)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedPosition = Cue::defaultPosition;
  ++run;
  EXPECT_EQ(expectedSet, cue.setPosition(text)) << "in testSetPosition #" << run;
  EXPECT_EQ(expectedPosition, cue.position()) << "in testSetPosition #" << run;
}

void testSetSize(const char *text, bool expectedSet, int expectedSize = 0)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedSize = Cue::defaultSize;
  ++run;
  EXPECT_EQ(expectedSet, cue.setSize(text)) << "in testSetSize #" << run;
  EXPECT_EQ(expectedSize, cue.size()) << "in testSetSize #" << run;
}

void testSetVertical(const char *text, bool expectedSet,
                     Cue::Vertical expectedVertical = Cue::Horizontal)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedVertical = Cue::defaultVertical;
  ++run;
  EXPECT_EQ(expectedSet, cue.setVertical(text))
    << "in testSetVertical(string) #" << run;
  EXPECT_EQ(expectedVertical, cue.vertical())
    << "in testSetVertical(string) #" << run;
}

void testSetVertical(Cue::Vertical vertical, bool expectedSet,
                     Cue::Vertical expectedVertical = Cue::Horizontal)
{
  static int run = 0;
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  if(!expectedSet)
    expectedVertical = Cue::defaultVertical;
  ++run;
  EXPECT_EQ(expectedSet, cue.setVertical(vertical))
    << "in testSetVertical(enum) #" << run;
  EXPECT_EQ(expectedVertical, cue.vertical())
    << "in testSetVertical(enum) #" << run;
}

TEST(CueSettings,SetId)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_STREQ("",cue.id());
  cue.setId("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn", cue.id());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetText)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_STREQ("",cue.text());
  cue.setText("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn", cue.text());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetStartTime)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_EQ(0.000,cue.startTime().toSeconds());
  cue.setStartTime(6667.334);
  EXPECT_EQ(6667.334,cue.startTime().toSeconds());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetEndTime)
{
  Cue cue(Cue::WebVTTCue, 0.000, 1.000);
  EXPECT_EQ(1.000,cue.endTime().toSeconds());
  cue.setEndTime(8362.316);
  EXPECT_EQ(8362.316,cue.endTime().toSeconds());
  // TODO: Test with TTML Cues too!
}

TEST(CueSettings,SetAlign)
{
  const Cue::Align defaultAlign = Cue::defaultAlign;
  testSetAlign("start",true,Cue::Start);
  testSetAlign("middle",true,Cue::Middle);
  testSetAlign("end",true,Cue::End);
  testSetAlign("left",true,Cue::Left);
  testSetAlign("right",true,Cue::Right);
  testSetAlign("12345",false);
  testSetAlign("!@#$",false);
  testSetAlign("bottom",false);
  testSetAlign("",false);
  testSetAlign(NULL,false);
  testSetAlign(static_cast<Cue::Align>(-1),false,defaultAlign);
  testSetAlign(static_cast<Cue::Align>(68),false,defaultAlign);
}

TEST(CueSettings,SetLine)
{
  testSetLine("-1",true,-1,true);
  testSetLine("10%",true,10,false);
  testSetLine("0%",true,0,false);
  testSetLine("100%",true,100,false);
  testSetLine("-1%",false);
  testSetLine("101%",false);
  testSetLine("1%1",false);
  testSetLine("1-1",false);
  testSetLine("1z",false);
  testSetLine("%",false);
  testSetLine("-",false);
  testSetLine("alpha",false);
  testSetLine("",false);
  testSetLine(NULL,false);
}

TEST(CueSettings,SetPosition)
{
  testSetPosition("0%",true,0);
  testSetPosition("100%",true,100);
  testSetPosition("-1%",false);
  testSetPosition("101%",false);
  testSetPosition("0",false);
  testSetPosition("100",false);
  testSetPosition("%",false);
  testSetPosition("%100",false);
  testSetPosition("alpha",false);
  testSetPosition("",false);
  testSetPosition(NULL,false);
}

TEST(CueSettings,SetSize)
{
  testSetSize("0%",true,0);
  testSetSize("100%",true,100);
  testSetSize("-1%",false);
  testSetSize("101%",false);
  testSetSize("0",false);
  testSetSize("100",false);
  testSetSize("%",false);
  testSetSize("%100",false);
  testSetSize("alpha",false);
  testSetSize("",false);
  testSetSize(NULL,false);
}

TEST(CueSettings,SetVertical)
{
  const Cue::Vertical defaultVertical = Cue::defaultVertical;
  testSetVertical("",true,Cue::Horizontal);
  testSetVertical("lr",true,Cue::VerticalLeftToRight);
  testSetVertical("rl",true,Cue::VerticalRightToLeft);
  testSetVertical(static_cast<Cue::Vertical>(-1),false,defaultVertical);
  testSetVertical(static_cast<Cue::Vertical>(2000),false,defaultVertical);
  testSetVertical(NULL,false);
  testSetVertical("lr ",false);
  testSetVertical("rl ",false);
  testSetVertical("lrr",false);
  testSetVertical("rll",false);
  testSetVertical("0",false);
  testSetVertical("1",false);
  testSetVertical("2",false);
}

TEST(CueSettings,EmptyCue)
{
  // Avoid using references to const values in EXPECT_EQ statements
  const Cue::Align defaultAlign = Cue::defaultAlign;
  const int defaultLine = Cue::defaultLine;
  const int defaultPosition = Cue::defaultPosition;
  const int defaultSize = Cue::defaultSize;
  const bool defaultSnapToLines = Cue::defaultSnapToLines;
  const Cue::Vertical defaultVertical = Cue::defaultVertical;

  // Trying to set empty cue settings should always fail
  Cue cue;

  // Id
  cue.setId("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("", cue.id());

  // Text
  cue.setText("Phnglui mglw nafh Cthulhu R'lyeh wgah nagl fhtagn");
  EXPECT_STREQ("", cue.text());

  // StartTime
  cue.setStartTime(68.067);
  EXPECT_EQ(MalformedTimestamp, cue.startTime());

  // EndTime
  cue.setEndTime(98.678);
  EXPECT_EQ(MalformedTimestamp, cue.endTime());

  // Align
  EXPECT_FALSE(cue.setAlign(Cue::Start));
  EXPECT_FALSE(cue.setAlign(Cue::Middle));
  EXPECT_FALSE(cue.setAlign(Cue::End));
  EXPECT_FALSE(cue.setAlign(Cue::Left));
  EXPECT_FALSE(cue.setAlign(Cue::Right));
  EXPECT_FALSE(cue.setAlign("start"));
  EXPECT_FALSE(cue.setAlign("middle"));
  EXPECT_FALSE(cue.setAlign("end"));
  EXPECT_FALSE(cue.setAlign("left"));
  EXPECT_FALSE(cue.setAlign("right"));
  EXPECT_EQ(defaultAlign,cue.align());

  // Line
  EXPECT_FALSE(cue.setLine(0, false));
  EXPECT_FALSE(cue.setLine(0, false));
  EXPECT_FALSE(cue.setLine(-101, true));
  EXPECT_FALSE(cue.setLine(101, true));
  EXPECT_FALSE(cue.setLine("0%"));
  EXPECT_FALSE(cue.setLine("100%"));
  EXPECT_FALSE(cue.setLine("-101"));
  EXPECT_FALSE(cue.setLine("1001"));
  EXPECT_EQ(defaultLine, cue.line());
  EXPECT_EQ(defaultSnapToLines, cue.snapToLines());

  // Position
  EXPECT_FALSE(cue.setPosition(0));
  EXPECT_FALSE(cue.setPosition(100));
  EXPECT_FALSE(cue.setPosition("0%"));
  EXPECT_FALSE(cue.setPosition("100%"));
  EXPECT_EQ(defaultPosition, cue.position());

  // Size
  EXPECT_FALSE(cue.setSize(0));
  EXPECT_FALSE(cue.setSize(100));
  EXPECT_FALSE(cue.setSize("0%"));
  EXPECT_FALSE(cue.setSize("100%"));
  EXPECT_EQ(defaultSize, cue.size());

  // Vertical
  EXPECT_FALSE(cue.setVertical(Cue::Horizontal));
  EXPECT_FALSE(cue.setVertical(Cue::VerticalLeftToRight));
  EXPECT_FALSE(cue.setVertical(Cue::VerticalRightToLeft));
  EXPECT_FALSE(cue.setVertical(""));
  EXPECT_FALSE(cue.setVertical("lr"));
  EXPECT_FALSE(cue.setVertical("rl"));
  EXPECT_EQ(defaultVertical, cue.vertical());
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#include <map>
#include <string>
#include <fstream>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>

#define CLIOPTS_ENABLE_CXX
#define INCLUDE_SUBDOC_NTOHLL
#include "subdoc/subdoc-api.h"
#include "subdoc/subdoc-util.h"
#include "subdoc/path.h"
#include "subdoc/match.h"
#include "subdoc/operations.h"
#include "contrib/cliopts/cliopts.h"

using std::string;
using std::map;
using namespace cliopts;

class Options {
public:
    Options() :
        o_iter('i', "iterations", 1000),
        o_path('p', "docpath"),
        o_value('v', "value"),
        o_jsfile('f', "json"),
        o_cmd('c', "command"),
        parser("subdoc-bench")
    {
        o_iter.description("Number of iterations to run");
        o_path.description("Document path to manipulate").mandatory();
        o_value.description("Document value to insert");
        o_jsfile.description("JSON file to operate on");
        o_cmd.description("Command to use").mandatory();

        parser.addOption(o_iter);
        parser.addOption(o_path);
        parser.addOption(o_value);
        parser.addOption(o_jsfile);
        parser.addOption(o_cmd);

        // Set the opmap
        initOpmap();
    }

    void initOpmap() {
        // generic ops:
        opmap["replace"] = SUBDOC_CMD_REPLACE;
        opmap["delete"] = SUBDOC_CMD_DELETE;
        opmap["get"] = SUBDOC_CMD_GET;
        opmap["exists"] = SUBDOC_CMD_EXISTS;

        // dict ops
        opmap["add"] = SUBDOC_CMD_DICT_ADD;
        opmap["upsert"] = SUBDOC_CMD_DICT_UPSERT;
        opmap["add_p"] = SUBDOC_CMD_DICT_ADD_P;
        opmap["upsert_p"] = SUBDOC_CMD_DICT_UPSERT_P;

        // list ops
        opmap["append"] = SUBDOC_CMD_ARRAY_APPEND;
        opmap["prepend"] = SUBDOC_CMD_ARRAY_PREPEND;
        opmap["pop"] = SUBDOC_CMD_ARRAY_POP;
        opmap["shift"] = SUBDOC_CMD_ARRAY_SHIFT;
        opmap["addunique"] = SUBDOC_CMD_ARRAY_ADD_UNIQUE;
        opmap["append_p"] = SUBDOC_CMD_ARRAY_APPEND_P;
        opmap["prepend_p"] = SUBDOC_CMD_ARRAY_PREPEND_P;
        opmap["addunique_p"] = SUBDOC_CMD_ARRAY_ADD_UNIQUE_P;

        // arithmetic ops
        opmap["incr"] = SUBDOC_CMD_INCREMENT;
        opmap["decr"] = SUBDOC_CMD_DECREMENT;
        opmap["incr_p"] = SUBDOC_CMD_INCREMENT_P;
        opmap["decr_p"] = SUBDOC_CMD_DECREMENT_P;
    }

    UIntOption o_iter;
    StringOption o_path;
    StringOption o_value;
    StringOption o_jsfile;
    StringOption o_cmd;
    map<string,uint8_t> opmap;
    Parser parser;
};

#ifdef _WIN32
#include <windows.h>
static uint64_t
get_nstime(void) {
    double ret;
    static LARGE_INTEGER pf = { 0 };
    static double freq;
    LARGE_INTEGER currtime;

    if (pf.QuadPart == 0) {
        QueryPerformanceFrequency(&pf);
        freq = 1.0e9 / (double)pf.QuadPart;
    }

    QueryPerformanceCounter(&currtime);

    ret = (double)currtime.QuadPart * freq ;
    return (uint64_t)ret;
}
#else
#include <sys/time.h>
static uint64_t
get_nstime(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (tv.tv_sec * 1000000000) + (tv.tv_usec * 1000);
}
#endif

static void
execOperation(Options& o)
{
    string json;
    std::ifstream input(o.o_jsfile.result().c_str());
    if (input.bad()) {
        throw string("Couldn't open file!");
    }
    std::stringstream ss;
    ss << input.rdbuf();
    json = ss.str();
    input.close();

    const uint8_t opcode = o.opmap[o.o_cmd.const_result()];
    string value = o.o_value.const_result();
    string path = o.o_path.const_result();
    const char *vbuf = value.c_str();
    size_t nvbuf = value.length();
    uint64_t dummy;

    switch (opcode) {
    case SUBDOC_CMD_INCREMENT:
    case SUBDOC_CMD_INCREMENT_P:
    case SUBDOC_CMD_DECREMENT:
    case SUBDOC_CMD_DECREMENT_P: {
        int64_t ctmp = (uint64_t)strtoll(vbuf, NULL, 10);
        if (ctmp == LLONG_MAX && errno == ERANGE) {
            throw string("Invalid delta for arithmetic operation!");
        }
        dummy = ctmp;
        dummy = htonll(dummy);
        vbuf = (const char *)&dummy;
        nvbuf = sizeof dummy;
        break;
    }
    }

    subdoc_OPERATION *op = subdoc_op_alloc();

    size_t itermax = o.o_iter.result();
    for (size_t ii = 0; ii < itermax; ii++) {
        subdoc_op_clear(op);
        SUBDOC_OP_SETCODE(op, opcode);
        SUBDOC_OP_SETDOC(op, json.c_str(), json.size());
        SUBDOC_OP_SETVALUE(op, vbuf, nvbuf);

        uint16_t rv = subdoc_op_exec(op, path.c_str(), path.size());
        if (rv != SUBDOC_STATUS_SUCCESS) {
            throw string("Operation failed!");
        }
    }

    // Print the result.
    if (opcode == SUBDOC_CMD_GET || opcode == SUBDOC_CMD_EXISTS) {
        string match(op->match.loc_match.at, op->match.loc_match.length);
        std::cout << match << std::endl;
    } else {
        string newdoc;
        for (size_t ii = 0; ii < op->doc_new_len; ii++) {
            const subdoc_LOC *loc = &op->doc_new[ii];
            newdoc.append(loc->at, loc->length);
        }
        std::cout << newdoc << std::endl;
    }

    subdoc_op_free(op);
}

static void
execPathParse(Options& o)
{
    size_t itermax = o.o_iter.result();
    string path = o.o_path.const_result();
    subdoc_PATH *pth = subdoc_path_alloc();

    for (size_t ii = 0; ii < itermax; ii++) {
        subdoc_path_clear(pth);
        int rv = subdoc_path_parse(pth, path.c_str(), path.size());

        if (rv != 0) {
            throw string("Failed to parse path!");
        }
    }

    subdoc_path_free(pth);
}

void runMain(int argc, char **argv)
{
    Options o;
    if (!o.parser.parse(argc, argv)) {
        throw string("Bad options!");
    }
    // Determine the command
    string cmdStr = o.o_cmd.const_result();

    uint64_t t_begin = get_nstime();

    if (o.opmap.find(cmdStr) != o.opmap.end()) {
        if (!o.o_jsfile.passed()) {
            throw string("Operation must contain file!");
        }
        execOperation(o);
    } else if (cmdStr == "path") {
        execPathParse(o);
    } else {
        throw string("Unknown command!");
    }

    uint64_t t_total = get_nstime() - t_begin;
    // Get the number of seconds:
    double n_seconds = t_total / 1000000000.0;
    double ops_per_sec = (double)o.o_iter.result() / n_seconds;

    fprintf(stderr, "DURATION=%.2lfs. OPS=%lu\n", n_seconds, o.o_iter.result());
    fprintf(stderr, "%.2lf OPS/s\n",  ops_per_sec);
}

int main(int argc, char **argv)
{
    try {
        runMain(argc, argv);
        return EXIT_SUCCESS;
    } catch (string& exc) {
        std::cerr << exc << std::endl;
        return EXIT_FAILURE;
    }
}
<commit_msg>Bench: don't use C++ cout/cerr (very slow)<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#include <map>
#include <string>
#include <fstream>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>

#define CLIOPTS_ENABLE_CXX
#define INCLUDE_SUBDOC_NTOHLL
#include "subdoc/subdoc-api.h"
#include "subdoc/subdoc-util.h"
#include "subdoc/path.h"
#include "subdoc/match.h"
#include "subdoc/operations.h"
#include "contrib/cliopts/cliopts.h"

using std::string;
using std::map;
using namespace cliopts;

class Options {
public:
    Options() :
        o_iter('i', "iterations", 1000),
        o_path('p', "docpath"),
        o_value('v', "value"),
        o_jsfile('f', "json"),
        o_cmd('c', "command"),
        parser("subdoc-bench")
    {
        o_iter.description("Number of iterations to run");
        o_path.description("Document path to manipulate").mandatory();
        o_value.description("Document value to insert");
        o_jsfile.description("JSON file to operate on");
        o_cmd.description("Command to use").mandatory();

        parser.addOption(o_iter);
        parser.addOption(o_path);
        parser.addOption(o_value);
        parser.addOption(o_jsfile);
        parser.addOption(o_cmd);

        // Set the opmap
        initOpmap();
    }

    void initOpmap() {
        // generic ops:
        opmap["replace"] = SUBDOC_CMD_REPLACE;
        opmap["delete"] = SUBDOC_CMD_DELETE;
        opmap["get"] = SUBDOC_CMD_GET;
        opmap["exists"] = SUBDOC_CMD_EXISTS;

        // dict ops
        opmap["add"] = SUBDOC_CMD_DICT_ADD;
        opmap["upsert"] = SUBDOC_CMD_DICT_UPSERT;
        opmap["add_p"] = SUBDOC_CMD_DICT_ADD_P;
        opmap["upsert_p"] = SUBDOC_CMD_DICT_UPSERT_P;

        // list ops
        opmap["append"] = SUBDOC_CMD_ARRAY_APPEND;
        opmap["prepend"] = SUBDOC_CMD_ARRAY_PREPEND;
        opmap["pop"] = SUBDOC_CMD_ARRAY_POP;
        opmap["shift"] = SUBDOC_CMD_ARRAY_SHIFT;
        opmap["addunique"] = SUBDOC_CMD_ARRAY_ADD_UNIQUE;
        opmap["append_p"] = SUBDOC_CMD_ARRAY_APPEND_P;
        opmap["prepend_p"] = SUBDOC_CMD_ARRAY_PREPEND_P;
        opmap["addunique_p"] = SUBDOC_CMD_ARRAY_ADD_UNIQUE_P;

        // arithmetic ops
        opmap["incr"] = SUBDOC_CMD_INCREMENT;
        opmap["decr"] = SUBDOC_CMD_DECREMENT;
        opmap["incr_p"] = SUBDOC_CMD_INCREMENT_P;
        opmap["decr_p"] = SUBDOC_CMD_DECREMENT_P;
    }

    UIntOption o_iter;
    StringOption o_path;
    StringOption o_value;
    StringOption o_jsfile;
    StringOption o_cmd;
    map<string,uint8_t> opmap;
    Parser parser;
};

#ifdef _WIN32
#include <windows.h>
static uint64_t
get_nstime(void) {
    double ret;
    static LARGE_INTEGER pf = { 0 };
    static double freq;
    LARGE_INTEGER currtime;

    if (pf.QuadPart == 0) {
        QueryPerformanceFrequency(&pf);
        freq = 1.0e9 / (double)pf.QuadPart;
    }

    QueryPerformanceCounter(&currtime);

    ret = (double)currtime.QuadPart * freq ;
    return (uint64_t)ret;
}
#else
#include <sys/time.h>
static uint64_t
get_nstime(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (tv.tv_sec * 1000000000) + (tv.tv_usec * 1000);
}
#endif

static void
execOperation(Options& o)
{
    string json;
    std::ifstream input(o.o_jsfile.result().c_str());
    if (input.bad()) {
        throw string("Couldn't open file!");
    }
    std::stringstream ss;
    ss << input.rdbuf();
    json = ss.str();
    input.close();

    const uint8_t opcode = o.opmap[o.o_cmd.const_result()];
    string value = o.o_value.const_result();
    string path = o.o_path.const_result();
    const char *vbuf = value.c_str();
    size_t nvbuf = value.length();
    uint64_t dummy;

    switch (opcode) {
    case SUBDOC_CMD_INCREMENT:
    case SUBDOC_CMD_INCREMENT_P:
    case SUBDOC_CMD_DECREMENT:
    case SUBDOC_CMD_DECREMENT_P: {
        int64_t ctmp = (uint64_t)strtoll(vbuf, NULL, 10);
        if (ctmp == LLONG_MAX && errno == ERANGE) {
            throw string("Invalid delta for arithmetic operation!");
        }
        dummy = ctmp;
        dummy = htonll(dummy);
        vbuf = (const char *)&dummy;
        nvbuf = sizeof dummy;
        break;
    }
    }

    subdoc_OPERATION *op = subdoc_op_alloc();

    size_t itermax = o.o_iter.result();
    for (size_t ii = 0; ii < itermax; ii++) {
        subdoc_op_clear(op);
        SUBDOC_OP_SETCODE(op, opcode);
        SUBDOC_OP_SETDOC(op, json.c_str(), json.size());
        SUBDOC_OP_SETVALUE(op, vbuf, nvbuf);

        uint16_t rv = subdoc_op_exec(op, path.c_str(), path.size());
        if (rv != SUBDOC_STATUS_SUCCESS) {
            throw string("Operation failed!");
        }
    }

    // Print the result.
    if (opcode == SUBDOC_CMD_GET || opcode == SUBDOC_CMD_EXISTS) {
        string match(op->match.loc_match.at, op->match.loc_match.length);
        printf("%s\n", match.c_str());
    } else {
        string newdoc;
        for (size_t ii = 0; ii < op->doc_new_len; ii++) {
            const subdoc_LOC *loc = &op->doc_new[ii];
            newdoc.append(loc->at, loc->length);
        }
        printf("%s\n", newdoc.c_str());
    }

    subdoc_op_free(op);
}

static void
execPathParse(Options& o)
{
    size_t itermax = o.o_iter.result();
    string path = o.o_path.const_result();
    subdoc_PATH *pth = subdoc_path_alloc();

    for (size_t ii = 0; ii < itermax; ii++) {
        subdoc_path_clear(pth);
        int rv = subdoc_path_parse(pth, path.c_str(), path.size());

        if (rv != 0) {
            throw string("Failed to parse path!");
        }
    }

    subdoc_path_free(pth);
}

void runMain(int argc, char **argv)
{
    Options o;
    if (!o.parser.parse(argc, argv)) {
        throw string("Bad options!");
    }
    // Determine the command
    string cmdStr = o.o_cmd.const_result();

    uint64_t t_begin = get_nstime();

    if (o.opmap.find(cmdStr) != o.opmap.end()) {
        if (!o.o_jsfile.passed()) {
            throw string("Operation must contain file!");
        }
        execOperation(o);
    } else if (cmdStr == "path") {
        execPathParse(o);
    } else {
        throw string("Unknown command!");
    }

    uint64_t t_total = get_nstime() - t_begin;
    // Get the number of seconds:
    double n_seconds = t_total / 1000000000.0;
    double ops_per_sec = (double)o.o_iter.result() / n_seconds;

    fprintf(stderr, "DURATION=%.2lfs. OPS=%lu\n", n_seconds, o.o_iter.result());
    fprintf(stderr, "%.2lf OPS/s\n",  ops_per_sec);
}

int main(int argc, char **argv)
{
    try {
        runMain(argc, argv);
        return EXIT_SUCCESS;
    } catch (string& exc) {
        fprintf(stderr, "%s\n", exc.c_str());
        return EXIT_FAILURE;
    }
}
<|endoftext|>